diff --git a/.gitignore b/.gitignore index ee681ef..37e8f0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,21 @@ # Ignore private files and directories by default. .* !.codegen.json +!.package.json +# Track the release ledger + anchors under each module's .codegen/ (the +# per-module releases.jsonl prepare-release reads to compute the next +# version). The dir must be un-ignored explicitly — the .* rule above +# excludes it, and git can't re-include a file whose parent dir is excluded. +!.codegen/ !.gitignore !.github !.agent !.cursor !.cursorrules +**/go.sum +!examples/go.sum + # Claude Code: track commands and settings, ignore local sessions. !.claude .claude/settings.local.json diff --git a/accessmanagement/.package.json b/accessmanagement/.package.json new file mode 100644 index 0000000..78f43b5 --- /dev/null +++ b/accessmanagement/.package.json @@ -0,0 +1,3 @@ +{ + "package": "accessmanagement" +} diff --git a/accessmanagement/CHANGELOG.md b/accessmanagement/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/accessmanagement/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/accessmanagement/README.md b/accessmanagement/README.md new file mode 100644 index 0000000..c643a47 --- /dev/null +++ b/accessmanagement/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/accessmanagement + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/accessmanagement@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/accessmanagement/v1" + +client, err := accessmanagement.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/accessmanagement/go.mod b/accessmanagement/go.mod new file mode 100644 index 0000000..18e8727 --- /dev/null +++ b/accessmanagement/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/accessmanagement + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/accessmanagement/internal/version.go b/accessmanagement/internal/version.go new file mode 100644 index 0000000..621844f --- /dev/null +++ b/accessmanagement/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-accessmanagement" + +const Version = "0.0.1-dev.1" diff --git a/accessmanagement/v1/client.go b/accessmanagement/v1/client.go new file mode 100755 index 0000000..6165da2 --- /dev/null +++ b/accessmanagement/v1/client.go @@ -0,0 +1,1124 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package accessmanagement + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/accessmanagement/internal" + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Deletes the workspace permissions assignment in a given account and workspace +// for the specified principal. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteWorkspacePermissionAssignment(ctx context.Context, req *DeleteWorkspacePermissionAssignmentRequest, opts ...call.Option) (*DeleteWorkspacePermissionAssignmentResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/permissionassignments/principals/") + pb.singleSegment(*req.PrincipalId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteWorkspacePermissionAssignmentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteWorkspacePermissionAssignmentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get the permission assignments for the specified and . +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListWorkspacePermissionAssignments(ctx context.Context, req *ListWorkspacePermissionAssignmentsRequest, opts ...call.Option) (*ListWorkspacePermissionAssignmentsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/permissionassignments") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListWorkspacePermissionAssignmentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listWorkspacePermissionAssignmentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listWorkspacePermissionAssignmentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get an array of workspace permissions for the specified account and +// workspace. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListWorkspacePermissions(ctx context.Context, req *ListWorkspacePermissionsRequest, opts ...call.Option) (*ListWorkspacePermissionsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/permissionassignments/permissions") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListWorkspacePermissionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listWorkspacePermissionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listWorkspacePermissionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates or updates the workspace permissions assignment in a given account +// and workspace for the specified principal. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateWorkspacePermissionAssignment(ctx context.Context, req *UpdateWorkspacePermissionAssignmentRequest, opts ...call.Option) (*WorkspacePermissionAssignmentOutput, error) { + wireReq, err := updateWorkspacePermissionAssignmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/permissionassignments/principals/") + pb.singleSegment(*req.PrincipalId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *WorkspacePermissionAssignmentOutput + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp workspacePermissionAssignmentOutputWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = workspacePermissionAssignmentOutputFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a rule set by its name. A rule set is always attached to a resource and +// contains a list of access rules on the said resource. Currently only a +// default rule set for each resource is supported. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetRuleSet(ctx context.Context, req *GetRuleSetRequest, opts ...call.Option) (*RuleSet, error) { + wireReq, err := getRuleSetRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/accounts/") + pb.singleSegment(accountID) + pb.literal("/access-control/rule-sets") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RuleSet + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp ruleSetWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = ruleSetFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a rule set by its name. A rule set is always attached to a resource and +// contains a list of access rules on the said resource. Currently only a +// default rule set for each resource is supported. +func (c *internalClient) GetRuleSetProxy(ctx context.Context, req *GetRuleSetRequest, opts ...call.Option) (*RuleSet, error) { + wireReq, err := getRuleSetRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/preview/accounts/access-control/rule-sets" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "account_id", wireReq.AccountId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RuleSet + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp ruleSetWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = ruleSetFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets all the roles that can be granted on an account level resource. A role +// is grantable if the rule set on the resource can contain an access rule of +// the role. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListAssignableRolesForResource(ctx context.Context, req *ListAssignableRolesForResourceRequest, opts ...call.Option) (*ListAssignableRolesForResourceResponse, error) { + wireReq, err := listAssignableRolesForResourceRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/accounts/") + pb.singleSegment(accountID) + pb.literal("/access-control/assignable-roles") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "resource", wireReq.Resource); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAssignableRolesForResourceResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAssignableRolesForResourceResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAssignableRolesForResourceResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets all the roles that can be granted on an account level resource. A role +// is grantable if the rule set on the resource can contain an access rule of +// the role. +func (c *internalClient) ListAssignableRolesForResourceProxy(ctx context.Context, req *ListAssignableRolesForResourceRequest, opts ...call.Option) (*ListAssignableRolesForResourceResponse, error) { + wireReq, err := listAssignableRolesForResourceRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/preview/accounts/access-control/assignable-roles" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "account_id", wireReq.AccountId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "resource", wireReq.Resource); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAssignableRolesForResourceResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAssignableRolesForResourceResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAssignableRolesForResourceResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Replace the rules of a rule set. First, use get to read the current version +// of the rule set before modifying it. This pattern helps prevent conflicts +// between concurrent updates. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateRuleSet(ctx context.Context, req *UpdateRuleSetRequest, opts ...call.Option) (*RuleSet, error) { + wireReq, err := updateRuleSetRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/accounts/") + pb.singleSegment(accountID) + pb.literal("/access-control/rule-sets") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RuleSet + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp ruleSetWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = ruleSetFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Replace the rules of a rule set. First, use get to read the current version +// of the rule set before modifying it. This pattern helps prevent conflicts +// between concurrent updates. +func (c *internalClient) UpdateRuleSetProxy(ctx context.Context, req *UpdateRuleSetRequest, opts ...call.Option) (*RuleSet, error) { + wireReq, err := updateRuleSetRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/preview/accounts/access-control/rule-sets" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RuleSet + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp ruleSetWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = ruleSetFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the permissions of an object. Objects can inherit permissions from their +// parent objects or root object. +func (c *internalClient) GetObjectPermissions(ctx context.Context, req *GetObjectPermissionsRequest, opts ...call.Option) (*PermissionsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/permissions/") + pb.singleSegment(*req.RequestObjectType) + pb.literal("/") + pb.singleSegment(*req.RequestObjectId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PermissionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp permissionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = permissionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the permission levels that a user can have on an object. +func (c *internalClient) ListPermissionLevels(ctx context.Context, req *ListPermissionLevelsRequest, opts ...call.Option) (*ListPermissionLevelsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/permissions/") + pb.singleSegment(*req.RequestObjectType) + pb.literal("/") + pb.singleSegment(*req.RequestObjectId) + pb.literal("/permissionLevels") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPermissionLevelsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listPermissionLevelsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listPermissionLevelsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Sets permissions on an object, replacing existing permissions if they exist. +// Deletes all direct permissions if none are specified. Objects can inherit +// permissions from their parent objects or root object. +func (c *internalClient) SetObjectPermissions(ctx context.Context, req *SetObjectPermissionsRequest, opts ...call.Option) (*PermissionsResponse, error) { + wireReq, err := setObjectPermissionsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/permissions/") + pb.singleSegment(*req.RequestObjectType) + pb.literal("/") + pb.singleSegment(*req.RequestObjectId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PermissionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp permissionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = permissionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the permissions on an object. Objects can inherit permissions from +// their parent objects or root object. +func (c *internalClient) UpdateObjectPermissions(ctx context.Context, req *UpdateObjectPermissionsRequest, opts ...call.Option) (*PermissionsResponse, error) { + wireReq, err := updateObjectPermissionsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/permissions/") + pb.singleSegment(*req.RequestObjectType) + pb.literal("/") + pb.singleSegment(*req.RequestObjectId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PermissionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp permissionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = permissionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Check access policy to a resource. +func (c *internalClient) CheckPolicy(ctx context.Context, req *CheckPolicyRequest, opts ...call.Option) (*CheckPolicyResponse, error) { + wireReq, err := checkPolicyRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/access-control/check-policy-v2" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "actor", wireReq.Actor); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "permission", wireReq.Permission); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "resource", wireReq.Resource); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "consistency_token", wireReq.ConsistencyToken); err != nil { + return nil, err + } + if wireReq.AuthzIdentity != "" { + if err := addQueryValue(queryParams, "authz_identity", wireReq.AuthzIdentity); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "resource_info", wireReq.ResourceInfo); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CheckPolicyResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp checkPolicyResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = checkPolicyResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/accessmanagement/v1/genhelper.go b/accessmanagement/v1/genhelper.go new file mode 100755 index 0000000..b7c91f8 --- /dev/null +++ b/accessmanagement/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package accessmanagement + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/accessmanagement/v1/model.go b/accessmanagement/v1/model.go new file mode 100755 index 0000000..9290e19 --- /dev/null +++ b/accessmanagement/v1/model.go @@ -0,0 +1,452 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package accessmanagement + +// Permission level +type PermissionLevel string + +const ( + PermissionLevel_Unspecified PermissionLevel = "" + PermissionLevel_CanRestart PermissionLevel = "CAN_RESTART" + PermissionLevel_CanAttachTo PermissionLevel = "CAN_ATTACH_TO" + PermissionLevel_IsOwner PermissionLevel = "IS_OWNER" + PermissionLevel_CanManageRun PermissionLevel = "CAN_MANAGE_RUN" + PermissionLevel_CanView PermissionLevel = "CAN_VIEW" + PermissionLevel_CanRead PermissionLevel = "CAN_READ" + PermissionLevel_CanRun PermissionLevel = "CAN_RUN" + PermissionLevel_CanEdit PermissionLevel = "CAN_EDIT" + PermissionLevel_CanUse PermissionLevel = "CAN_USE" + PermissionLevel_CanManageStagingVersions PermissionLevel = "CAN_MANAGE_STAGING_VERSIONS" + PermissionLevel_CanManageProductionVersions PermissionLevel = "CAN_MANAGE_PRODUCTION_VERSIONS" + PermissionLevel_CanEditMetadata PermissionLevel = "CAN_EDIT_METADATA" + PermissionLevel_CanViewMetadata PermissionLevel = "CAN_VIEW_METADATA" + PermissionLevel_CanBind PermissionLevel = "CAN_BIND" + PermissionLevel_CanQuery PermissionLevel = "CAN_QUERY" + PermissionLevel_CanMonitor PermissionLevel = "CAN_MONITOR" + PermissionLevel_CanCreate PermissionLevel = "CAN_CREATE" + PermissionLevel_CanMonitorOnly PermissionLevel = "CAN_MONITOR_ONLY" + PermissionLevel_CanCreateApp PermissionLevel = "CAN_CREATE_APP" +) + +// Defines the identity to be used for authZ of the request on the server side. +// See one pager for for more information: http://go/acl/service-identity +type RequestAuthzIdentity string + +const ( + RequestAuthzIdentity_Unspecified RequestAuthzIdentity = "" + RequestAuthzIdentity_RequestAuthzIdentityUserContext RequestAuthzIdentity = "REQUEST_AUTHZ_IDENTITY_USER_CONTEXT" + RequestAuthzIdentity_RequestAuthzIdentityServiceIdentity RequestAuthzIdentity = "REQUEST_AUTHZ_IDENTITY_SERVICE_IDENTITY" +) + +type WorkspacePermission string + +const ( + WorkspacePermission_Unspecified WorkspacePermission = "" + // The most basic workspace permission + WorkspacePermission_User WorkspacePermission = "USER" + WorkspacePermission_Admin WorkspacePermission = "ADMIN" +) + +type AccessControlRequest struct { + PrincipalName isAccessControlRequest_PrincipalName + PermissionLevel PermissionLevel +} + +type isAccessControlRequest_PrincipalName interface { + isAccessControlRequest_PrincipalName() +} + +// AccessControlRequest_PrincipalName_UserName selects UserName for AccessControlRequest.PrincipalName. +// name of the user +type AccessControlRequest_PrincipalName_UserName struct { + UserName string +} + +func (*AccessControlRequest_PrincipalName_UserName) isAccessControlRequest_PrincipalName() {} + +// AccessControlRequest_PrincipalName_GroupName selects GroupName for AccessControlRequest.PrincipalName. +// name of the group +type AccessControlRequest_PrincipalName_GroupName struct { + GroupName string +} + +func (*AccessControlRequest_PrincipalName_GroupName) isAccessControlRequest_PrincipalName() {} + +// AccessControlRequest_PrincipalName_ServicePrincipalName selects ServicePrincipalName for AccessControlRequest.PrincipalName. +// application ID of a service principal +type AccessControlRequest_PrincipalName_ServicePrincipalName struct { + ServicePrincipalName string +} + +func (*AccessControlRequest_PrincipalName_ServicePrincipalName) isAccessControlRequest_PrincipalName() { +} + +type AccessControlResponse struct { + PrincipalName isAccessControlResponse_PrincipalName + // Display name of the user or service principal. + DisplayName *string + // All permissions. + AllPermissions []Permission +} + +type isAccessControlResponse_PrincipalName interface { + isAccessControlResponse_PrincipalName() +} + +// AccessControlResponse_PrincipalName_UserName selects UserName for AccessControlResponse.PrincipalName. +// name of the user +type AccessControlResponse_PrincipalName_UserName struct { + UserName string +} + +func (*AccessControlResponse_PrincipalName_UserName) isAccessControlResponse_PrincipalName() {} + +// AccessControlResponse_PrincipalName_GroupName selects GroupName for AccessControlResponse.PrincipalName. +// name of the group +type AccessControlResponse_PrincipalName_GroupName struct { + GroupName string +} + +func (*AccessControlResponse_PrincipalName_GroupName) isAccessControlResponse_PrincipalName() {} + +// AccessControlResponse_PrincipalName_ServicePrincipalName selects ServicePrincipalName for AccessControlResponse.PrincipalName. +// Name of the service principal. +type AccessControlResponse_PrincipalName_ServicePrincipalName struct { + ServicePrincipalName string +} + +func (*AccessControlResponse_PrincipalName_ServicePrincipalName) isAccessControlResponse_PrincipalName() { +} + +// represents an identity trying to access a resource - user or a service +// principal group can be a principal of a permission set assignment but an +// actor is always a user or a service principal. +type Actor struct { + Kind isActor_Kind +} + +type isActor_Kind interface { + isActor_Kind() +} + +// Actor_Kind_ActorId selects ActorId for Actor.Kind. +type Actor_Kind_ActorId struct { + ActorId int64 +} + +func (*Actor_Kind_ActorId) isActor_Kind() {} + +type CheckPolicyRequest struct { + Actor *Actor + Permission *string + // Ex: (servicePrincipal/use, accounts//servicePrincipals/) + // Ex: (servicePrincipal.ruleSet/update, + // accounts//servicePrincipals//ruleSets/default) + Resource *string + ConsistencyToken *ConsistencyToken + AuthzIdentity RequestAuthzIdentity + ResourceInfo *ResourceInfo +} + +type CheckPolicyResponse struct { + IsPermitted *bool + ConsistencyToken *ConsistencyToken +} + +type ConsistencyToken struct { + Value *string +} + +// Removes all permission assignments for a workspace given a principal.. +type DeleteWorkspacePermissionAssignmentRequest struct { + // The account ID. + AccountId *string + // The workspace ID for the account. + WorkspaceId *int64 + // The ID of the user, service principal, or group. + PrincipalId *int64 +} + +type DeleteWorkspacePermissionAssignmentResponse struct { +} + +type GetObjectPermissionsRequest struct { + // The type of the request object. Can be one of the following: alerts, + // alertsv2, authorization, clusters, cluster-policies, dashboards, + // database-projects, dbsql-dashboards, directories, experiments, files, genie, + // instance-pools, jobs, knowledge-assistants, notebooks, pipelines, queries, + // registered-models, repos, serving-endpoints, supervisor-agents, + // vector-search-endpoints, or warehouses. + RequestObjectType *string + // The id of the request object. + RequestObjectId *string +} + +type GetRuleSetRequest struct { + // account ID. + AccountId *string + // The ruleset name associated with the request. + // + // Examples | Summary :--- | :--- `name=accounts//ruleSets/default` + // | A name for a rule set on the account. + // `name=accounts//groups//ruleSets/default` | A name for + // a rule set on the group. + // `name=accounts//servicePrincipals//ruleSets/default` + // | A name for a rule set on the service principal. + // `name=accounts//tagPolicies//ruleSets/default` | A + // name for a rule set on the tag policy. + Name *string + // Etag used for versioning. The response is at least as fresh as the eTag + // provided. Etag is used for optimistic concurrency control as a way to help + // prevent simultaneous updates of a rule set from overwriting each other. It is + // strongly suggested that systems make use of the etag in the read -> modify -> + // write pattern to perform rule set updates in order to avoid race conditions + // that is get an etag from a GET rule set request, and pass it with the PUT + // update request to identify the rule set version you are updating. + // + // Examples | Summary :--- | :--- `etag=` | An empty etag can only be used in + // GET to indicate no freshness requirements. + // `etag=RENUAAABhSweA4NvVmmUYdiU717H3Tgy0UJdor3gE4a+mq/oj9NjAf8ZsQ==` | An etag + // encoded a specific version of the rule set to get or to be updated. + Etag *string +} + +type GrantRule struct { + // Principals this grant rule applies to. A principal can be a user (for end + // users), a service principal (for applications and compute workloads), or an + // account group. Each principal has its own identifier format: * + // users/ * groups/ * + // servicePrincipals/ + Principals []string + // Role that is assigned to the list of principals. + Role *string +} + +type ListAssignableRolesForResourceRequest struct { + // account ID. + AccountId *string + // The resource name for which assignable roles will be listed. + // + // Examples | Summary :--- | :--- `resource=accounts/` | A resource + // name for the account. `resource=accounts//groups/` | A + // resource name for the group. + // `resource=accounts//servicePrincipals/` | A resource name + // for the service principal. + // `resource=accounts//tagPolicies/` | A resource + // name for the tag policy. + Resource *string +} + +type ListAssignableRolesForResourceResponse struct { + Roles []Role +} + +type ListPermissionLevelsRequest struct { + // The type of the request object. Can be one of the following: alerts, + // alertsv2, authorization, clusters, cluster-policies, dashboards, + // database-projects, dbsql-dashboards, directories, experiments, files, genie, + // instance-pools, jobs, knowledge-assistants, notebooks, pipelines, queries, + // registered-models, repos, serving-endpoints, supervisor-agents, + // vector-search-endpoints, or warehouses. + RequestObjectType *string + RequestObjectId *string +} + +type ListPermissionLevelsResponse struct { + // Specific permission levels + PermissionLevels []PermissionsDescription +} + +// Gets all the permission assignments for a workspace, given an account and a +// workspace.. +type ListWorkspacePermissionAssignmentsRequest struct { + // The account ID. + AccountId *string + // The workspace ID for the account. + WorkspaceId *int64 +} + +type ListWorkspacePermissionAssignmentsResponse struct { + // Array of permissions assignments defined for a workspace. + PermissionAssignments []WorkspacePermissionAssignmentOutput +} + +// List permissions for a workspace, given an account and a workspace.. +type ListWorkspacePermissionsRequest struct { + // The account ID. + AccountId *string + // The workspace ID. + WorkspaceId *int64 +} + +type ListWorkspacePermissionsResponse struct { + // Array of permissions defined for a workspace. + Permissions []PermissionOutput +} + +type Permission struct { + PermissionLevel PermissionLevel + Inherited *bool + InheritedFromObject []string +} + +type PermissionOutput struct { + PermissionLevel WorkspacePermission + // The results of a permissions query. + Description *string +} + +type PermissionsDescription struct { + PermissionLevel PermissionLevel + Description *string +} + +type PermissionsResponse struct { + ObjectId *string + ObjectType *string + AccessControlList []AccessControlResponse +} + +// Information about the principal assigned to the workspace.. +type PrincipalOutput struct { + PrincipalName isPrincipalOutput_PrincipalName + // The unique, opaque id of the principal. + PrincipalId *int64 + // The display name of the principal. + DisplayName *string +} + +type isPrincipalOutput_PrincipalName interface { + isPrincipalOutput_PrincipalName() +} + +// PrincipalOutput_PrincipalName_UserName selects UserName for PrincipalOutput.PrincipalName. +// The username of the user. Present only if the principal is a user. +type PrincipalOutput_PrincipalName_UserName struct { + UserName string +} + +func (*PrincipalOutput_PrincipalName_UserName) isPrincipalOutput_PrincipalName() {} + +// PrincipalOutput_PrincipalName_GroupName selects GroupName for PrincipalOutput.PrincipalName. +// The group name of the group. Present only if the principal is a group. +type PrincipalOutput_PrincipalName_GroupName struct { + GroupName string +} + +func (*PrincipalOutput_PrincipalName_GroupName) isPrincipalOutput_PrincipalName() {} + +// PrincipalOutput_PrincipalName_ServicePrincipalName selects ServicePrincipalName for PrincipalOutput.PrincipalName. +// The name of the service principal. Present only if the principal is a service +// principal. +type PrincipalOutput_PrincipalName_ServicePrincipalName struct { + ServicePrincipalName string +} + +func (*PrincipalOutput_PrincipalName_ServicePrincipalName) isPrincipalOutput_PrincipalName() {} + +type ResourceInfo struct { + // Id of the current resource. + Id *string + // Parent resource info for the current resource. The parent may have another + // parent. + ParentResourceInfo *ResourceInfo + // The legacy acl path of the current resource. + LegacyAclPath *string +} + +type Role struct { + // Role to assign to a principal or a list of principals on a resource. + Name *string +} + +type RuleSet struct { + // Name of the rule set. + Name *string + // Identifies the version of the rule set returned. Etag used for versioning. + // The response is at least as fresh as the eTag provided. Etag is used for + // optimistic concurrency control as a way to help prevent simultaneous updates + // of a rule set from overwriting each other. It is strongly suggested that + // systems make use of the etag in the read -> modify -> write pattern to + // perform rule set updates in order to avoid race conditions that is get an + // etag from a GET rule set request, and pass it with the PUT update request to + // identify the rule set version you are updating. + Etag *string + GrantRules []GrantRule +} + +type RuleSetUpdateRequest struct { + // Name of the rule set. + Name *string + // Identifies the version of the rule set returned. Etag used for versioning. + // The response is at least as fresh as the eTag provided. Etag is used for + // optimistic concurrency control as a way to help prevent simultaneous updates + // of a rule set from overwriting each other. It is strongly suggested that + // systems make use of the etag in the read -> modify -> write pattern to + // perform rule set updates in order to avoid race conditions that is get an + // etag from a GET rule set request, and pass it with the PUT update request to + // identify the rule set version you are updating. + Etag *string + GrantRules []GrantRule +} + +type SetObjectPermissionsRequest struct { + // The type of the request object. Can be one of the following: alerts, + // alertsv2, authorization, clusters, cluster-policies, dashboards, + // database-projects, dbsql-dashboards, directories, experiments, files, genie, + // instance-pools, jobs, knowledge-assistants, notebooks, pipelines, queries, + // registered-models, repos, serving-endpoints, supervisor-agents, + // vector-search-endpoints, or warehouses. + RequestObjectType *string + // The id of the request object. + RequestObjectId *string + AccessControlList []AccessControlRequest +} + +type UpdateObjectPermissionsRequest struct { + // The type of the request object. Can be one of the following: alerts, + // alertsv2, authorization, clusters, cluster-policies, dashboards, + // database-projects, dbsql-dashboards, directories, experiments, files, genie, + // instance-pools, jobs, knowledge-assistants, notebooks, pipelines, queries, + // registered-models, repos, serving-endpoints, supervisor-agents, + // vector-search-endpoints, or warehouses. + RequestObjectType *string + // The id of the request object. + RequestObjectId *string + AccessControlList []AccessControlRequest +} + +type UpdateRuleSetRequest struct { + // account ID. + AccountId *string + // Name of the rule set. + Name *string + RuleSet *RuleSetUpdateRequest +} + +type UpdateWorkspacePermissionAssignmentRequest struct { + // The account ID. + AccountId *string + // The workspace ID. + WorkspaceId *int64 + // The ID of the user, service principal, or group. + PrincipalId *int64 + // Array of permissions assignments to update on the workspace. Valid values are + // "USER" and "ADMIN" (case-sensitive). If both "USER" and "ADMIN" are provided, + // "ADMIN" takes precedence. Other values will be ignored. Note that excluding + // this field, or providing unsupported values, will have the same effect as + // providing an empty list, which will result in the deletion of all permissions + // for the principal. + Permissions []WorkspacePermission +} + +// The output format for existing workspace PermissionAssignment records, which +// contains some info for user consumption.. +type WorkspacePermissionAssignmentOutput struct { + // Information about the principal assigned to the workspace. + Principal *PrincipalOutput + // The permissions level of the principal. + Permissions []WorkspacePermission + // Error response associated with a workspace permission assignment, if any. + Error *string +} diff --git a/accessmanagement/v1/wire.go b/accessmanagement/v1/wire.go new file mode 100755 index 0000000..81d1c38 --- /dev/null +++ b/accessmanagement/v1/wire.go @@ -0,0 +1,618 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package accessmanagement + +import ( + "fmt" +) + +type accessControlRequestWire struct { + UserName *string `json:"user_name,omitempty"` + GroupName *string `json:"group_name,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` + PermissionLevel PermissionLevel `json:"permission_level,omitempty"` +} + +func accessControlRequestToWire(v *AccessControlRequest) (*accessControlRequestWire, error) { + if v == nil { + return nil, nil + } + var principalNameUserNameWire *string + var principalNameGroupNameWire *string + var principalNameServicePrincipalNameWire *string + switch value := v.PrincipalName.(type) { + case nil: + case *AccessControlRequest_PrincipalName_UserName: + if value != nil { + principalNameUserNameWire = new(value.UserName) + } + case *AccessControlRequest_PrincipalName_GroupName: + if value != nil { + principalNameGroupNameWire = new(value.GroupName) + } + case *AccessControlRequest_PrincipalName_ServicePrincipalName: + if value != nil { + principalNameServicePrincipalNameWire = new(value.ServicePrincipalName) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AccessControlRequest.PrincipalName", value) + } + return &accessControlRequestWire{ + UserName: principalNameUserNameWire, + GroupName: principalNameGroupNameWire, + ServicePrincipalName: principalNameServicePrincipalNameWire, + PermissionLevel: v.PermissionLevel, + }, nil +} + +type accessControlResponseWire struct { + UserName *string `json:"user_name,omitempty"` + GroupName *string `json:"group_name,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + AllPermissions []permissionWire `json:"all_permissions,omitempty"` +} + +func accessControlResponseFromWire(w *accessControlResponseWire) (*AccessControlResponse, error) { + if w == nil { + return nil, nil + } + principalNameMembers := 0 + if w.UserName != nil { + principalNameMembers++ + } + if w.GroupName != nil { + principalNameMembers++ + } + if w.ServicePrincipalName != nil { + principalNameMembers++ + } + if principalNameMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AccessControlResponse.PrincipalName") + } + allPermissionsPublicValue, err := convertSlice(w.AllPermissions, permissionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccessControlResponse.AllPermissions", err) + } + var principalNameSelection isAccessControlResponse_PrincipalName + switch { + case w.UserName != nil: + principalNameSelection = &AccessControlResponse_PrincipalName_UserName{UserName: *w.UserName} + case w.GroupName != nil: + principalNameSelection = &AccessControlResponse_PrincipalName_GroupName{GroupName: *w.GroupName} + case w.ServicePrincipalName != nil: + principalNameSelection = &AccessControlResponse_PrincipalName_ServicePrincipalName{ServicePrincipalName: *w.ServicePrincipalName} + } + return &AccessControlResponse{ + DisplayName: w.DisplayName, + AllPermissions: allPermissionsPublicValue, + PrincipalName: principalNameSelection, + }, nil +} + +type actorWire struct { + ActorId *int64 `json:"actor_id,omitempty"` +} + +func actorToWire(v *Actor) (*actorWire, error) { + if v == nil { + return nil, nil + } + var kindActorIdWire *int64 + switch value := v.Kind.(type) { + case nil: + case *Actor_Kind_ActorId: + if value != nil { + kindActorIdWire = new(value.ActorId) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Actor.Kind", value) + } + return &actorWire{ + ActorId: kindActorIdWire, + }, nil +} + +type checkPolicyRequestWire struct { + Actor *actorWire `json:"actor,omitempty"` + Permission *string `json:"permission,omitempty"` + Resource *string `json:"resource,omitempty"` + ConsistencyToken *consistencyTokenWire `json:"consistency_token,omitempty"` + AuthzIdentity RequestAuthzIdentity `json:"authz_identity,omitempty"` + ResourceInfo *resourceInfoWire `json:"resource_info,omitempty"` +} + +func checkPolicyRequestToWire(v *CheckPolicyRequest) (*checkPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + actorWireValue, err := actorToWire(v.Actor) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CheckPolicyRequest.Actor", err) + } + consistencyTokenWireValue, err := consistencyTokenToWire(v.ConsistencyToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CheckPolicyRequest.ConsistencyToken", err) + } + resourceInfoWireValue, err := resourceInfoToWire(v.ResourceInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CheckPolicyRequest.ResourceInfo", err) + } + return &checkPolicyRequestWire{ + Actor: actorWireValue, + Permission: v.Permission, + Resource: v.Resource, + ConsistencyToken: consistencyTokenWireValue, + AuthzIdentity: v.AuthzIdentity, + ResourceInfo: resourceInfoWireValue, + }, nil +} + +type checkPolicyResponseWire struct { + IsPermitted *bool `json:"is_permitted,omitempty"` + ConsistencyToken *consistencyTokenWire `json:"consistency_token,omitempty"` +} + +func checkPolicyResponseFromWire(w *checkPolicyResponseWire) (*CheckPolicyResponse, error) { + if w == nil { + return nil, nil + } + consistencyTokenPublicValue, err := consistencyTokenFromWire(w.ConsistencyToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CheckPolicyResponse.ConsistencyToken", err) + } + return &CheckPolicyResponse{ + IsPermitted: w.IsPermitted, + ConsistencyToken: consistencyTokenPublicValue, + }, nil +} + +type consistencyTokenWire struct { + Value *string `json:"value,omitempty"` +} + +func consistencyTokenToWire(v *ConsistencyToken) (*consistencyTokenWire, error) { + if v == nil { + return nil, nil + } + return &consistencyTokenWire{ + Value: v.Value, + }, nil +} + +func consistencyTokenFromWire(w *consistencyTokenWire) (*ConsistencyToken, error) { + if w == nil { + return nil, nil + } + return &ConsistencyToken{ + Value: w.Value, + }, nil +} + +type getRuleSetRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +func getRuleSetRequestToWire(v *GetRuleSetRequest) (*getRuleSetRequestWire, error) { + if v == nil { + return nil, nil + } + return &getRuleSetRequestWire{ + AccountId: v.AccountId, + Name: v.Name, + Etag: v.Etag, + }, nil +} + +type grantRuleWire struct { + Principals []string `json:"principals,omitempty"` + Role *string `json:"role,omitempty"` +} + +func grantRuleToWire(v *GrantRule) (*grantRuleWire, error) { + if v == nil { + return nil, nil + } + return &grantRuleWire{ + Principals: v.Principals, + Role: v.Role, + }, nil +} + +func grantRuleFromWire(w *grantRuleWire) (*GrantRule, error) { + if w == nil { + return nil, nil + } + return &GrantRule{ + Principals: w.Principals, + Role: w.Role, + }, nil +} + +type listAssignableRolesForResourceRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + Resource *string `json:"resource,omitempty"` +} + +func listAssignableRolesForResourceRequestToWire(v *ListAssignableRolesForResourceRequest) (*listAssignableRolesForResourceRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAssignableRolesForResourceRequestWire{ + AccountId: v.AccountId, + Resource: v.Resource, + }, nil +} + +type listAssignableRolesForResourceResponseWire struct { + Roles []roleWire `json:"roles,omitempty"` +} + +func listAssignableRolesForResourceResponseFromWire(w *listAssignableRolesForResourceResponseWire) (*ListAssignableRolesForResourceResponse, error) { + if w == nil { + return nil, nil + } + rolesPublicValue, err := convertSlice(w.Roles, roleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAssignableRolesForResourceResponse.Roles", err) + } + return &ListAssignableRolesForResourceResponse{ + Roles: rolesPublicValue, + }, nil +} + +type listPermissionLevelsResponseWire struct { + PermissionLevels []permissionsDescriptionWire `json:"permission_levels,omitempty"` +} + +func listPermissionLevelsResponseFromWire(w *listPermissionLevelsResponseWire) (*ListPermissionLevelsResponse, error) { + if w == nil { + return nil, nil + } + permissionLevelsPublicValue, err := convertSlice(w.PermissionLevels, permissionsDescriptionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPermissionLevelsResponse.PermissionLevels", err) + } + return &ListPermissionLevelsResponse{ + PermissionLevels: permissionLevelsPublicValue, + }, nil +} + +type listWorkspacePermissionAssignmentsResponseWire struct { + PermissionAssignments []workspacePermissionAssignmentOutputWire `json:"permission_assignments,omitempty"` +} + +func listWorkspacePermissionAssignmentsResponseFromWire(w *listWorkspacePermissionAssignmentsResponseWire) (*ListWorkspacePermissionAssignmentsResponse, error) { + if w == nil { + return nil, nil + } + permissionAssignmentsPublicValue, err := convertSlice(w.PermissionAssignments, workspacePermissionAssignmentOutputFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListWorkspacePermissionAssignmentsResponse.PermissionAssignments", err) + } + return &ListWorkspacePermissionAssignmentsResponse{ + PermissionAssignments: permissionAssignmentsPublicValue, + }, nil +} + +type listWorkspacePermissionsResponseWire struct { + Permissions []permissionOutputWire `json:"permissions,omitempty"` +} + +func listWorkspacePermissionsResponseFromWire(w *listWorkspacePermissionsResponseWire) (*ListWorkspacePermissionsResponse, error) { + if w == nil { + return nil, nil + } + permissionsPublicValue, err := convertSlice(w.Permissions, permissionOutputFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListWorkspacePermissionsResponse.Permissions", err) + } + return &ListWorkspacePermissionsResponse{ + Permissions: permissionsPublicValue, + }, nil +} + +type permissionWire struct { + PermissionLevel PermissionLevel `json:"permission_level,omitempty"` + Inherited *bool `json:"inherited,omitempty"` + InheritedFromObject []string `json:"inherited_from_object,omitempty"` +} + +func permissionFromWire(w *permissionWire) (*Permission, error) { + if w == nil { + return nil, nil + } + return &Permission{ + PermissionLevel: w.PermissionLevel, + Inherited: w.Inherited, + InheritedFromObject: w.InheritedFromObject, + }, nil +} + +type permissionOutputWire struct { + PermissionLevel WorkspacePermission `json:"permission_level,omitempty"` + Description *string `json:"description,omitempty"` +} + +func permissionOutputFromWire(w *permissionOutputWire) (*PermissionOutput, error) { + if w == nil { + return nil, nil + } + return &PermissionOutput{ + PermissionLevel: w.PermissionLevel, + Description: w.Description, + }, nil +} + +type permissionsDescriptionWire struct { + PermissionLevel PermissionLevel `json:"permission_level,omitempty"` + Description *string `json:"description,omitempty"` +} + +func permissionsDescriptionFromWire(w *permissionsDescriptionWire) (*PermissionsDescription, error) { + if w == nil { + return nil, nil + } + return &PermissionsDescription{ + PermissionLevel: w.PermissionLevel, + Description: w.Description, + }, nil +} + +type permissionsResponseWire struct { + ObjectId *string `json:"object_id,omitempty"` + ObjectType *string `json:"object_type,omitempty"` + AccessControlList []accessControlResponseWire `json:"access_control_list,omitempty"` +} + +func permissionsResponseFromWire(w *permissionsResponseWire) (*PermissionsResponse, error) { + if w == nil { + return nil, nil + } + accessControlListPublicValue, err := convertSlice(w.AccessControlList, accessControlResponseFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PermissionsResponse.AccessControlList", err) + } + return &PermissionsResponse{ + ObjectId: w.ObjectId, + ObjectType: w.ObjectType, + AccessControlList: accessControlListPublicValue, + }, nil +} + +type principalOutputWire struct { + UserName *string `json:"user_name,omitempty"` + GroupName *string `json:"group_name,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` + PrincipalId *int64 `json:"principal_id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` +} + +func principalOutputFromWire(w *principalOutputWire) (*PrincipalOutput, error) { + if w == nil { + return nil, nil + } + principalNameMembers := 0 + if w.UserName != nil { + principalNameMembers++ + } + if w.GroupName != nil { + principalNameMembers++ + } + if w.ServicePrincipalName != nil { + principalNameMembers++ + } + if principalNameMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PrincipalOutput.PrincipalName") + } + var principalNameSelection isPrincipalOutput_PrincipalName + switch { + case w.UserName != nil: + principalNameSelection = &PrincipalOutput_PrincipalName_UserName{UserName: *w.UserName} + case w.GroupName != nil: + principalNameSelection = &PrincipalOutput_PrincipalName_GroupName{GroupName: *w.GroupName} + case w.ServicePrincipalName != nil: + principalNameSelection = &PrincipalOutput_PrincipalName_ServicePrincipalName{ServicePrincipalName: *w.ServicePrincipalName} + } + return &PrincipalOutput{ + PrincipalId: w.PrincipalId, + DisplayName: w.DisplayName, + PrincipalName: principalNameSelection, + }, nil +} + +type resourceInfoWire struct { + Id *string `json:"id,omitempty"` + ParentResourceInfo *resourceInfoWire `json:"parent_resource_info,omitempty"` + LegacyAclPath *string `json:"legacy_acl_path,omitempty"` +} + +func resourceInfoToWire(v *ResourceInfo) (*resourceInfoWire, error) { + if v == nil { + return nil, nil + } + parentResourceInfoWireValue, err := resourceInfoToWire(v.ParentResourceInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResourceInfo.ParentResourceInfo", err) + } + return &resourceInfoWire{ + Id: v.Id, + ParentResourceInfo: parentResourceInfoWireValue, + LegacyAclPath: v.LegacyAclPath, + }, nil +} + +type roleWire struct { + Name *string `json:"name,omitempty"` +} + +func roleFromWire(w *roleWire) (*Role, error) { + if w == nil { + return nil, nil + } + return &Role{ + Name: w.Name, + }, nil +} + +type ruleSetWire struct { + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` + GrantRules []grantRuleWire `json:"grant_rules,omitempty"` +} + +func ruleSetFromWire(w *ruleSetWire) (*RuleSet, error) { + if w == nil { + return nil, nil + } + grantRulesPublicValue, err := convertSlice(w.GrantRules, grantRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RuleSet.GrantRules", err) + } + return &RuleSet{ + Name: w.Name, + Etag: w.Etag, + GrantRules: grantRulesPublicValue, + }, nil +} + +type ruleSetUpdateRequestWire struct { + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` + GrantRules []grantRuleWire `json:"grant_rules,omitempty"` +} + +func ruleSetUpdateRequestToWire(v *RuleSetUpdateRequest) (*ruleSetUpdateRequestWire, error) { + if v == nil { + return nil, nil + } + grantRulesWireValue, err := convertSlice(v.GrantRules, grantRuleToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RuleSetUpdateRequest.GrantRules", err) + } + return &ruleSetUpdateRequestWire{ + Name: v.Name, + Etag: v.Etag, + GrantRules: grantRulesWireValue, + }, nil +} + +type setObjectPermissionsRequestWire struct { + RequestObjectType *string `json:"request_object_type,omitempty"` + RequestObjectId *string `json:"request_object_id,omitempty"` + AccessControlList []accessControlRequestWire `json:"access_control_list,omitempty"` +} + +func setObjectPermissionsRequestToWire(v *SetObjectPermissionsRequest) (*setObjectPermissionsRequestWire, error) { + if v == nil { + return nil, nil + } + accessControlListWireValue, err := convertSlice(v.AccessControlList, accessControlRequestToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SetObjectPermissionsRequest.AccessControlList", err) + } + return &setObjectPermissionsRequestWire{ + RequestObjectType: v.RequestObjectType, + RequestObjectId: v.RequestObjectId, + AccessControlList: accessControlListWireValue, + }, nil +} + +type updateObjectPermissionsRequestWire struct { + RequestObjectType *string `json:"request_object_type,omitempty"` + RequestObjectId *string `json:"request_object_id,omitempty"` + AccessControlList []accessControlRequestWire `json:"access_control_list,omitempty"` +} + +func updateObjectPermissionsRequestToWire(v *UpdateObjectPermissionsRequest) (*updateObjectPermissionsRequestWire, error) { + if v == nil { + return nil, nil + } + accessControlListWireValue, err := convertSlice(v.AccessControlList, accessControlRequestToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateObjectPermissionsRequest.AccessControlList", err) + } + return &updateObjectPermissionsRequestWire{ + RequestObjectType: v.RequestObjectType, + RequestObjectId: v.RequestObjectId, + AccessControlList: accessControlListWireValue, + }, nil +} + +type updateRuleSetRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + Name *string `json:"name,omitempty"` + RuleSet *ruleSetUpdateRequestWire `json:"rule_set,omitempty"` +} + +func updateRuleSetRequestToWire(v *UpdateRuleSetRequest) (*updateRuleSetRequestWire, error) { + if v == nil { + return nil, nil + } + ruleSetWireValue, err := ruleSetUpdateRequestToWire(v.RuleSet) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRuleSetRequest.RuleSet", err) + } + return &updateRuleSetRequestWire{ + AccountId: v.AccountId, + Name: v.Name, + RuleSet: ruleSetWireValue, + }, nil +} + +type updateWorkspacePermissionAssignmentRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + WorkspaceId *int64 `json:"workspace_id,omitempty"` + PrincipalId *int64 `json:"principal_id,omitempty"` + Permissions []WorkspacePermission `json:"permissions,omitempty"` +} + +func updateWorkspacePermissionAssignmentRequestToWire(v *UpdateWorkspacePermissionAssignmentRequest) (*updateWorkspacePermissionAssignmentRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateWorkspacePermissionAssignmentRequestWire{ + AccountId: v.AccountId, + WorkspaceId: v.WorkspaceId, + PrincipalId: v.PrincipalId, + Permissions: v.Permissions, + }, nil +} + +type workspacePermissionAssignmentOutputWire struct { + Principal *principalOutputWire `json:"principal,omitempty"` + Permissions []WorkspacePermission `json:"permissions,omitempty"` + Error *string `json:"error,omitempty"` +} + +func workspacePermissionAssignmentOutputFromWire(w *workspacePermissionAssignmentOutputWire) (*WorkspacePermissionAssignmentOutput, error) { + if w == nil { + return nil, nil + } + principalPublicValue, err := principalOutputFromWire(w.Principal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkspacePermissionAssignmentOutput.Principal", err) + } + return &WorkspacePermissionAssignmentOutput{ + Principal: principalPublicValue, + Permissions: w.Permissions, + Error: w.Error, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/aigateway/.package.json b/aigateway/.package.json new file mode 100644 index 0000000..ccf6fb6 --- /dev/null +++ b/aigateway/.package.json @@ -0,0 +1,3 @@ +{ + "package": "aigateway" +} diff --git a/aigateway/CHANGELOG.md b/aigateway/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/aigateway/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/aigateway/README.md b/aigateway/README.md new file mode 100644 index 0000000..336f343 --- /dev/null +++ b/aigateway/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/aigateway + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/aigateway@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/aigateway/v1" + +client, err := aigateway.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/aigateway/go.mod b/aigateway/go.mod new file mode 100644 index 0000000..3d4b91e --- /dev/null +++ b/aigateway/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/aigateway + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/aigateway/internal/version.go b/aigateway/internal/version.go new file mode 100644 index 0000000..8af74c7 --- /dev/null +++ b/aigateway/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-aigateway" + +const Version = "0.0.1-dev.1" diff --git a/aigateway/v1/client.go b/aigateway/v1/client.go new file mode 100755 index 0000000..6fe27b7 --- /dev/null +++ b/aigateway/v1/client.go @@ -0,0 +1,1312 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package aigateway + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/aigateway/internal" + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates an MCP service in a Unity Catalog schema. An MCP (Model Context +// Protocol) service is a governed securable that registers an MCP server and +// exposes its tools for discovery, access control, and invocation. The caller +// supplies the leaf name in `mcp_service_id`. +// +// You must be the owner of the parent schema or have the `CREATE_SERVICE` and +// `USE_SCHEMA` privileges on the parent schema and `USE_CATALOG` on the parent +// catalog. You also need `USE_CONNECTION` on the connection the MCP service +// references. +func (c *internalClient) CreateMcpService(ctx context.Context, req *CreateMcpServiceRequest, opts ...call.Option) (*McpService, error) { + wireReq, err := createMcpServiceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.McpService) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/mcp-services" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "parent", wireReq.Parent); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "mcp_service_id", wireReq.McpServiceId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *McpService + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp mcpServiceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = mcpServiceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a model provider service in a Unity Catalog schema. A model provider +// service is a governed connection to an external model provider (for example +// OpenAI, Azure OpenAI, or Amazon Bedrock) that model services reference to +// invoke that provider. The caller supplies the leaf name in +// `model_provider_service_id`. +// +// You must be the owner of the parent schema or have the `CREATE_SERVICE` and +// `USE_SCHEMA` privileges on the parent schema and `USE_CATALOG` on the parent +// catalog. +func (c *internalClient) CreateModelProviderService(ctx context.Context, req *CreateModelProviderServiceRequest, opts ...call.Option) (*ModelProviderService, error) { + wireReq, err := createModelProviderServiceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.ModelProviderService) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/model-provider-services" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "parent", wireReq.Parent); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "model_provider_service_id", wireReq.ModelProviderServiceId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ModelProviderService + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp modelProviderServiceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = modelProviderServiceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a model service in a Unity Catalog schema. A model service is a +// governed AI Gateway endpoint that routes inference requests to one or more +// model destinations. The caller supplies the leaf name in `model_service_id`. +// +// You must be the owner of the parent schema or have the `CREATE_SERVICE` and +// `USE_SCHEMA` privileges on the parent schema and `USE_CATALOG` on the parent +// catalog. +func (c *internalClient) CreateModelService(ctx context.Context, req *CreateModelServiceRequest, opts ...call.Option) (*ModelService, error) { + wireReq, err := createModelServiceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.ModelService) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/model-services" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "parent", wireReq.Parent); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "model_service_id", wireReq.ModelServiceId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ModelService + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp modelServiceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = modelServiceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the MCP service identified by its resource name. Optionally supply an +// `etag` to make the delete conditional on the MCP service not having changed +// since it was read. +// +// You must be the owner of the MCP service or have `MANAGE` on it, plus +// `USE_CATALOG` on the parent catalog and `USE_SCHEMA` on the parent schema. +func (c *internalClient) DeleteMcpService(ctx context.Context, req *DeleteMcpServiceRequest, opts ...call.Option) error { + wireReq, err := deleteMcpServiceRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Deletes the model provider service identified by its resource name. +// Optionally supply an `etag` to make the delete conditional on the model +// provider service not having changed since it was read. +// +// You must be the owner of the model provider service or have `MANAGE` on it, +// plus `USE_CATALOG` on the parent catalog and `USE_SCHEMA` on the parent +// schema. +func (c *internalClient) DeleteModelProviderService(ctx context.Context, req *DeleteModelProviderServiceRequest, opts ...call.Option) error { + wireReq, err := deleteModelProviderServiceRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Deletes the model service identified by its resource name. Optionally supply +// an `etag` to make the delete conditional on the model service not having +// changed since it was read. +// +// You must be the owner of the model service or have `MANAGE` on it, plus +// `USE_CATALOG` on the parent catalog and `USE_SCHEMA` on the parent schema. +func (c *internalClient) DeleteModelService(ctx context.Context, req *DeleteModelServiceRequest, opts ...call.Option) error { + wireReq, err := deleteModelServiceRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Returns the MCP service identified by its resource name. +// +// You must be the owner of the MCP service or have `EXECUTE`, `READ_METADATA`, +// or `MANAGE` on it, plus `USE_CATALOG` on the parent catalog and `USE_SCHEMA` +// on the parent schema. +func (c *internalClient) GetMcpService(ctx context.Context, req *GetMcpServiceRequest, opts ...call.Option) (*McpService, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *McpService + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp mcpServiceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = mcpServiceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns the model provider service identified by its resource name. +// +// You must be the owner of the model provider service or have `EXECUTE`, +// `READ_METADATA`, or `MANAGE` on it, plus `USE_CATALOG` on the parent catalog +// and `USE_SCHEMA` on the parent schema. +func (c *internalClient) GetModelProviderService(ctx context.Context, req *GetModelProviderServiceRequest, opts ...call.Option) (*ModelProviderService, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ModelProviderService + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp modelProviderServiceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = modelProviderServiceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns the model service identified by its resource name. +// +// You must be the owner of the model service or have `EXECUTE`, +// `READ_METADATA`, or `MANAGE` on it, plus `USE_CATALOG` on the parent catalog +// and `USE_SCHEMA` on the parent schema. +func (c *internalClient) GetModelService(ctx context.Context, req *GetModelServiceRequest, opts ...call.Option) (*ModelService, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ModelService + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp modelServiceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = modelServiceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists the MCP services in a Unity Catalog schema. Provide `parent` as +// `schemas/{catalog}.{schema}`. Results are paginated; pass the returned +// `next_page_token` to fetch subsequent pages. +// +// Requires `USE_CATALOG` on the parent catalog and `USE_SCHEMA` on the parent +// schema. Only MCP services the caller can access (as owner or through +// `EXECUTE`, `READ_METADATA`, or `MANAGE`) are returned. +func (c *internalClient) ListMcpServices(ctx context.Context, req *ListMcpServicesRequest, opts ...call.Option) (*ListMcpServicesResponse, error) { + wireReq, err := listMcpServicesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/mcp-services" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "parent", wireReq.Parent); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if wireReq.View != "" { + if err := addQueryValue(queryParams, "view", wireReq.View); err != nil { + return nil, err + } + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListMcpServicesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listMcpServicesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listMcpServicesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListMcpServicesIter returns an iterator that iterates +// over the results of ListMcpServices. +// +// For example: +// +// for item, err := range c.ListMcpServicesIter(ctx, &ListMcpServicesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListMcpServices call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListMcpServices directly. +func (c *internalClient) ListMcpServicesIter(ctx context.Context, req *ListMcpServicesRequest, opts ...call.Option) iter.Seq2[*McpService, error] { + return func(yield func(*McpService, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListMcpServicesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListMcpServices(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.McpServices { + if !yield(&resp.McpServices[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Lists the model provider services in a Unity Catalog schema. Provide `parent` +// as `schemas/{catalog}.{schema}`. Results are paginated; pass the returned +// `next_page_token` to fetch subsequent pages. +// +// Requires `USE_CATALOG` on the parent catalog and `USE_SCHEMA` on the parent +// schema. Only model provider services the caller can access (as owner or +// through `EXECUTE`, `READ_METADATA`, or `MANAGE`) are returned. +func (c *internalClient) ListModelProviderServices(ctx context.Context, req *ListModelProviderServicesRequest, opts ...call.Option) (*ListModelProviderServicesResponse, error) { + wireReq, err := listModelProviderServicesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/model-provider-services" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "parent", wireReq.Parent); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if wireReq.View != "" { + if err := addQueryValue(queryParams, "view", wireReq.View); err != nil { + return nil, err + } + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListModelProviderServicesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listModelProviderServicesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listModelProviderServicesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListModelProviderServicesIter returns an iterator that iterates +// over the results of ListModelProviderServices. +// +// For example: +// +// for item, err := range c.ListModelProviderServicesIter(ctx, &ListModelProviderServicesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListModelProviderServices call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListModelProviderServices directly. +func (c *internalClient) ListModelProviderServicesIter(ctx context.Context, req *ListModelProviderServicesRequest, opts ...call.Option) iter.Seq2[*ModelProviderService, error] { + return func(yield func(*ModelProviderService, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListModelProviderServicesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListModelProviderServices(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ModelProviderServices { + if !yield(&resp.ModelProviderServices[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Lists the model services in a Unity Catalog schema. Provide `parent` as +// `schemas/{catalog}.{schema}`. Results are paginated; pass the returned +// `next_page_token` to fetch subsequent pages. +// +// Requires `USE_CATALOG` on the parent catalog and `USE_SCHEMA` on the parent +// schema. Only model services the caller can access (as owner or through +// `EXECUTE`, `READ_METADATA`, or `MANAGE`) are returned. +func (c *internalClient) ListModelServices(ctx context.Context, req *ListModelServicesRequest, opts ...call.Option) (*ListModelServicesResponse, error) { + wireReq, err := listModelServicesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/model-services" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "parent", wireReq.Parent); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if wireReq.View != "" { + if err := addQueryValue(queryParams, "view", wireReq.View); err != nil { + return nil, err + } + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListModelServicesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listModelServicesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listModelServicesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListModelServicesIter returns an iterator that iterates +// over the results of ListModelServices. +// +// For example: +// +// for item, err := range c.ListModelServicesIter(ctx, &ListModelServicesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListModelServices call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListModelServices directly. +func (c *internalClient) ListModelServicesIter(ctx context.Context, req *ListModelServicesRequest, opts ...call.Option) iter.Seq2[*ModelService, error] { + return func(yield func(*ModelService, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListModelServicesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListModelServices(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ModelServices { + if !yield(&resp.ModelServices[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates an MCP service. Only the fields named in `update_mask` are changed; +// the resource name is immutable. Optionally supply an `etag` to make the +// update conditional on the MCP service not having changed since it was read. +// +// You must be the owner of the MCP service or have `MANAGE` on it, plus +// `USE_CATALOG` on the parent catalog and `USE_SCHEMA` on the parent schema. +func (c *internalClient) UpdateMcpService(ctx context.Context, req *UpdateMcpServiceRequest, opts ...call.Option) (*McpService, error) { + wireReq, err := updateMcpServiceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.McpService) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/") + pb.singleSegment(*req.McpService.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *McpService + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp mcpServiceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = mcpServiceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a model provider service. Only the fields named in `update_mask` are +// changed; the resource name and provider type are immutable. Optionally supply +// an `etag` to make the update conditional on the model provider service not +// having changed since it was read. +// +// You must be the owner of the model provider service or have `MANAGE` on it, +// plus `USE_CATALOG` on the parent catalog and `USE_SCHEMA` on the parent +// schema. +func (c *internalClient) UpdateModelProviderService(ctx context.Context, req *UpdateModelProviderServiceRequest, opts ...call.Option) (*ModelProviderService, error) { + wireReq, err := updateModelProviderServiceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.ModelProviderService) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/") + pb.singleSegment(*req.ModelProviderService.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ModelProviderService + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp modelProviderServiceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = modelProviderServiceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a model service. Only the fields named in `update_mask` are changed; +// the resource name is immutable. Optionally supply an `etag` to make the +// update conditional on the model service not having changed since it was read. +// +// You must be the owner of the model service or have `MANAGE` on it, plus +// `USE_CATALOG` on the parent catalog and `USE_SCHEMA` on the parent schema. +func (c *internalClient) UpdateModelService(ctx context.Context, req *UpdateModelServiceRequest, opts ...call.Option) (*ModelService, error) { + wireReq, err := updateModelServiceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.ModelService) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/") + pb.singleSegment(*req.ModelService.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ModelService + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp modelServiceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = modelServiceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/aigateway/v1/genhelper.go b/aigateway/v1/genhelper.go new file mode 100755 index 0000000..6d3e11c --- /dev/null +++ b/aigateway/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package aigateway + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/aigateway/v1/model.go b/aigateway/v1/model.go new file mode 100755 index 0000000..25a1f7c --- /dev/null +++ b/aigateway/v1/model.go @@ -0,0 +1,1562 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package aigateway + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// Controls which fields are populated on each McpService in the response. The +// server treats unset / VIEW_UNSPECIFIED as BASIC. Callers needing the full +// configuration must request it explicitly with `view = FULL`. +type ListMcpServicesRequest_View string + +const ( + ListMcpServicesRequest_View_Unspecified ListMcpServicesRequest_View = "" + // All fields populated, including the fully resolved `config` (connection + // details) and rate-limit principal names. + ListMcpServicesRequest_View_Full ListMcpServicesRequest_View = "FULL" + // Envelope only: identifiers, ownership, timestamps, plus the persisted + // `config` scalars (`include_tool_selectors`, `rate_limits` without + // `principal`); `config.source_connection` is unset. + ListMcpServicesRequest_View_Basic ListMcpServicesRequest_View = "BASIC" +) + +// Controls which fields are populated on each ModelProviderService in the +// response. The server treats unset / VIEW_UNSPECIFIED as BASIC. Callers +// needing the full configuration must request it explicitly with `view = FULL`. +type ListModelProviderServicesRequest_View string + +const ( + ListModelProviderServicesRequest_View_Unspecified ListModelProviderServicesRequest_View = "" + // All fields populated, including the fully resolved `config` (inference-table + // details) and rate-limit principal names. + ListModelProviderServicesRequest_View_Full ListModelProviderServicesRequest_View = "FULL" + // Envelope only: identifiers, ownership, timestamps, plus the persisted + // `config` scalars (`targets`, `allow_all_targets`, `rate_limits` without + // `principal`); the inference-table details are unset. + ListModelProviderServicesRequest_View_Basic ListModelProviderServicesRequest_View = "BASIC" +) + +// Controls which fields are populated on each ModelService in the response. The +// server treats unset / VIEW_UNSPECIFIED as BASIC. Callers needing the full +// configuration must request it explicitly with `view = FULL`. +type ListModelServicesRequest_View string + +const ( + ListModelServicesRequest_View_Unspecified ListModelServicesRequest_View = "" + // All fields populated, including the fully resolved `config` (destinations and + // inference-table details) and rate-limit principal names. + ListModelServicesRequest_View_Full ListModelServicesRequest_View = "FULL" + // Envelope only: identifiers, ownership, timestamps, plus the persisted + // `config` scalars (`routing_strategy`, `rate_limits` without `principal`); + // `destinations` and the inference-table details are unset. + ListModelServicesRequest_View_Basic ListModelServicesRequest_View = "BASIC" +) + +// Which Anthropic subscription tier the relayed OAuth token belongs to. +// Immutable after Create (switching tiers changes which governance controls the +// platform enforces). Only MAX and TEAM_ENTERPRISE differ in the governance +// surface the gateway can enforce, not in how the token is relayed. +type ModelProviderServiceConfig_AnthropicProviderRelayedConfig_AnthropicRelayedPlanType string + +const ( + ModelProviderServiceConfig_AnthropicProviderRelayedConfig_AnthropicRelayedPlanType_Unspecified ModelProviderServiceConfig_AnthropicProviderRelayedConfig_AnthropicRelayedPlanType = "" + // Personal Claude Max/Pro subscription. No gateway-enforced governance: model + // selection, per-principal rate limits, and service policies (guard- rails) + // cannot be enforced on a personal subscription and are rejected. + ModelProviderServiceConfig_AnthropicProviderRelayedConfig_AnthropicRelayedPlanType_AnthropicRelayedPlanTypeMax ModelProviderServiceConfig_AnthropicProviderRelayedConfig_AnthropicRelayedPlanType = "ANTHROPIC_RELAYED_PLAN_TYPE_MAX" + // Claude for Teams / Enterprise organization subscription. Supports the full + // gateway governance surface: model allowlist (`targets` / + // `allow_all_targets`), rate limits, and service policies. + ModelProviderServiceConfig_AnthropicProviderRelayedConfig_AnthropicRelayedPlanType_AnthropicRelayedPlanTypeTeamEnterprise ModelProviderServiceConfig_AnthropicProviderRelayedConfig_AnthropicRelayedPlanType = "ANTHROPIC_RELAYED_PLAN_TYPE_TEAM_ENTERPRISE" +) + +// External LLM provider for an EXTERNAL_FOUNDATION_MODEL destination. +type ModelProviderServiceConfig_ExternalModelProviderType string + +const ( + ModelProviderServiceConfig_ExternalModelProviderType_Unspecified ModelProviderServiceConfig_ExternalModelProviderType = "" + // OpenAI (api.openai.com). Auth via API key. + ModelProviderServiceConfig_ExternalModelProviderType_ExternalModelProviderTypeOpenai ModelProviderServiceConfig_ExternalModelProviderType = "EXTERNAL_MODEL_PROVIDER_TYPE_OPENAI" + // Azure OpenAI Service. Auth via API key or Entra ID service principal. + ModelProviderServiceConfig_ExternalModelProviderType_ExternalModelProviderTypeAzureOpenai ModelProviderServiceConfig_ExternalModelProviderType = "EXTERNAL_MODEL_PROVIDER_TYPE_AZURE_OPENAI" + // Anthropic (api.anthropic.com). Auth via API key. + ModelProviderServiceConfig_ExternalModelProviderType_ExternalModelProviderTypeAnthropic ModelProviderServiceConfig_ExternalModelProviderType = "EXTERNAL_MODEL_PROVIDER_TYPE_ANTHROPIC" + // Amazon Bedrock. Auth via AWS credentials (access key + secret) or assumed + // role. + ModelProviderServiceConfig_ExternalModelProviderType_ExternalModelProviderTypeAmazonBedrock ModelProviderServiceConfig_ExternalModelProviderType = "EXTERNAL_MODEL_PROVIDER_TYPE_AMAZON_BEDROCK" + // Custom OpenAI-compatible provider (any endpoint that speaks the OpenAI HTTP + // API). Configured by `base_url` + API key. + ModelProviderServiceConfig_ExternalModelProviderType_ExternalModelProviderTypeCustom ModelProviderServiceConfig_ExternalModelProviderType = "EXTERNAL_MODEL_PROVIDER_TYPE_CUSTOM" + // Microsoft AI Foundry. Auth via API key plus Foundry endpoint URL. + ModelProviderServiceConfig_ExternalModelProviderType_ExternalModelProviderTypeMicrosoftFoundry ModelProviderServiceConfig_ExternalModelProviderType = "EXTERNAL_MODEL_PROVIDER_TYPE_MICROSOFT_FOUNDRY" + // Google Gemini Enterprise. Auth via API key. + ModelProviderServiceConfig_ExternalModelProviderType_ExternalModelProviderTypeGeminiEnterprise ModelProviderServiceConfig_ExternalModelProviderType = "EXTERNAL_MODEL_PROVIDER_TYPE_GEMINI_ENTERPRISE" +) + +// Backing-model category for a model service destination. +type ModelServiceConfig_DestinationConfig_DestinationType string + +const ( + ModelServiceConfig_DestinationConfig_DestinationType_Unspecified ModelServiceConfig_DestinationConfig_DestinationType = "" + // A foundation model billed per token. + ModelServiceConfig_DestinationConfig_DestinationType_DestinationTypePayPerTokenFoundationModel ModelServiceConfig_DestinationConfig_DestinationType = "DESTINATION_TYPE_PAY_PER_TOKEN_FOUNDATION_MODEL" + // A foundation model with provisioned throughput. + ModelServiceConfig_DestinationConfig_DestinationType_DestinationTypeProvisionedThroughputFoundationModel ModelServiceConfig_DestinationConfig_DestinationType = "DESTINATION_TYPE_PROVISIONED_THROUGHPUT_FOUNDATION_MODEL" + // An external LLM provider (OpenAI, Anthropic, Azure OpenAI, Bedrock, ...). + ModelServiceConfig_DestinationConfig_DestinationType_DestinationTypeExternalFoundationModel ModelServiceConfig_DestinationConfig_DestinationType = "DESTINATION_TYPE_EXTERNAL_FOUNDATION_MODEL" +) + +// Scope key for a rate limit. +type RateLimit_RateLimitKey string + +const ( + RateLimit_RateLimitKey_Unspecified RateLimit_RateLimitKey = "" + // Rate limit applies to a specific user (matched on `principal`). + RateLimit_RateLimitKey_RateLimitKeyUser RateLimit_RateLimitKey = "RATE_LIMIT_KEY_USER" + // Rate limit applies to all members of a group (matched on `principal`). + RateLimit_RateLimitKey_RateLimitKeyUserGroup RateLimit_RateLimitKey = "RATE_LIMIT_KEY_USER_GROUP" + // Rate limit applies to a specific service principal (matched on `principal`). + RateLimit_RateLimitKey_RateLimitKeyServicePrincipal RateLimit_RateLimitKey = "RATE_LIMIT_KEY_SERVICE_PRINCIPAL" + // Rate limit applies to the parent service (ModelService or McpService) as a + // whole, across all callers. Domain-neutral so the same enum can scope a + // service-wide quota on either securable. + RateLimit_RateLimitKey_RateLimitKeyService RateLimit_RateLimitKey = "RATE_LIMIT_KEY_SERVICE" + // Default per-user rate limit applied when no more-specific rule matches. + RateLimit_RateLimitKey_RateLimitKeyUserDefault RateLimit_RateLimitKey = "RATE_LIMIT_KEY_USER_DEFAULT" + // Rate limit scoped to a request tag (matched on `request_tag_key` and + // optionally `request_tag_value`), independent of the caller principal. + RateLimit_RateLimitKey_RateLimitKeyRequestTag RateLimit_RateLimitKey = "RATE_LIMIT_KEY_REQUEST_TAG" +) + +// Renewal period for a rate limit. +type RateLimit_RateLimitRenewalPeriod string + +const ( + RateLimit_RateLimitRenewalPeriod_Unspecified RateLimit_RateLimitRenewalPeriod = "" + // Rate limit counters reset every minute. + RateLimit_RateLimitRenewalPeriod_RateLimitRenewalPeriodMinute RateLimit_RateLimitRenewalPeriod = "RATE_LIMIT_RENEWAL_PERIOD_MINUTE" + // Rate limit counters reset every hour. + RateLimit_RateLimitRenewalPeriod_RateLimitRenewalPeriodHour RateLimit_RateLimitRenewalPeriod = "RATE_LIMIT_RENEWAL_PERIOD_HOUR" +) + +// Request to create a new MCP service.. +type CreateMcpServiceRequest struct { + // Name of the parent schema. Format: `schemas/{catalog}.{schema}`. Each `{...}` + // component is capped at 255 characters individually. + Parent *string + // Name for the MCP service, e.g. "my_mcp_service". + McpServiceId *string + // The MCP service to create. The server populates `name` from `parent` + + // `mcp_service_id`; clients should leave it unset. + McpService *McpService +} + +// Request to create a new model provider service.. +type CreateModelProviderServiceRequest struct { + // Name of the parent schema. Format: `schemas/{catalog}.{schema}`. Each `{...}` + // component is capped at 255 characters individually. + Parent *string + // Name for the model provider service, e.g. "openai_prod". + ModelProviderServiceId *string + // The model provider service to create. The server populates `name` from + // `parent` + `model_provider_service_id`; clients should leave it unset. + ModelProviderService *ModelProviderService +} + +// Request to create a new model service.. +type CreateModelServiceRequest struct { + // Name of the parent schema. Format: `schemas/{catalog}.{schema}`. Each `{...}` + // component is capped at 255 characters individually. + Parent *string + // Name for the model service, e.g. "my_model_service". + ModelServiceId *string + // The model service to create. The server populates `name` from `parent` + + // `model_service_id`; clients should leave it unset. + ModelService *ModelService +} + +// Request to delete an MCP service.. +type DeleteMcpServiceRequest struct { + // Resource name of the MCP service. Format: + // `mcp-services/{catalog}.{schema}.{mcp_service}`. Each `{...}` component is + // capped at 255 characters individually. + Name *string + // If-match precondition: when set, the delete proceeds only if the current + // server-side etag matches. Empty means unconditional delete. + Etag []byte +} + +// Request to delete a model provider service.. +type DeleteModelProviderServiceRequest struct { + // Resource name of the model provider service. Format: + // `model-provider-services/{catalog}.{schema}.{model_provider_service}`. Each + // `{...}` component is capped at 255 characters individually. + Name *string + // If-match precondition: when set, the delete proceeds only if the current + // server-side etag matches. Empty means unconditional delete. + Etag []byte +} + +// Request to delete a model service.. +type DeleteModelServiceRequest struct { + // Resource name of the model service. Format: + // `model-services/{catalog}.{schema}.{model_service}`. Each `{...}` component + // is capped at 255 characters individually. + Name *string + // If-match precondition: when set, the delete proceeds only if the current + // server-side etag matches. Empty means unconditional delete. + Etag []byte +} + +// Request to get an MCP service.. +type GetMcpServiceRequest struct { + // Resource name of the MCP service. Format: + // `mcp-services/{catalog}.{schema}.{mcp_service}`. Each `{...}` component is + // capped at 255 characters individually. + Name *string +} + +// Request to get a model provider service.. +type GetModelProviderServiceRequest struct { + // Resource name of the model provider service. Format: + // `model-provider-services/{catalog}.{schema}.{model_provider_service}`. Each + // `{...}` component is capped at 255 characters individually. + Name *string +} + +// Request to get a model service.. +type GetModelServiceRequest struct { + // Resource name of the model service. Format: + // `model-services/{catalog}.{schema}.{model_service}`. Each `{...}` component + // is capped at 255 characters individually. + Name *string +} + +// Inference table configuration for payload logging on a model service. +// +// `parent` is always REQUIRED when the sub-message is set; the destination UC +// schema is needed to construct or rebind the payload TABLE regardless of +// whether payload logging is currently active. Payload logging is active by +// default; set `disabled = true` to pause runtime logging without dropping the +// table or the binding.. +type InferenceTableConfig struct { + // Parent UC schema where the inference table is created. Format: + // `schemas/{catalog}.{schema}`. Set at create time and immutable thereafter; + // changing it on an existing service is rejected. + Parent *string `fieldmask:"parent"` + // Prefix for the inference-table's UC-registered name. The actual leaf name UC + // stores is `_payload`; the `_payload` suffix is appended + // automatically. To find the actual UC table after Create, read the `table` + // field on the response. Defaults to `_payload` when unset. + // Set at create time and immutable thereafter; changing it on an existing + // service is rejected. + TableNamePrefix *string `fieldmask:"table_name_prefix"` + // Indicates whether payload logging is disabled (opt-out). Unset means that + // payload logging is active (the on-by-default state coincides with the proto + // zero-value, so the server never fills this field for a client that leaves it + // unset). Set `disabled = true` to pause runtime logging while keeping the + // sub-message attached (preserving `parent` and `table_name_prefix` for a later + // flip back to active). `parent` remains required either way. + Disabled *bool `fieldmask:"disabled"` + // Resolved UC table for payload logs. Format: + // `tables/{catalog}.{schema}.{table}`. + Table *string `fieldmask:"table"` + // True when the bound inference TABLE has been deleted but the parent service + // still references it. The dangling reference is surfaced (not silently + // dropped) so callers can see the broken dependency. AI Gateway payload logging + // fails closed in this state. + IsDeleted *bool `fieldmask:"is_deleted"` +} + +// Request to list MCP services. Accepts `parent`, `page_size`, and +// `page_token`.. +type ListMcpServicesRequest struct { + // Name of the parent schema to list within, as `schemas/{catalog}.{schema}`. + // Each `{...}` component is capped at 255 characters individually. + Parent *string + // Maximum number of MCP services to return. Defaults to 100 when unset or 0; + // the maximum is 100. Use `page_token` to retrieve additional pages. + PageSize *int + // Opaque pagination token from a previous request. + PageToken *string + // View selector controlling which fields are populated per row. `FULL` returns + // the full representation of the service; `BASIC` returns a more compact + // version. Defaults to `BASIC` when unset. + View ListMcpServicesRequest_View +} + +// Response for listing MCP services.. +type ListMcpServicesResponse struct { + // The list of MCP services. + McpServices []McpService + // Pagination token for retrieving the next page of results. + NextPageToken *string +} + +// Request to list model provider services. Accepts `parent`, `page_size`, and +// `page_token`.. +type ListModelProviderServicesRequest struct { + // Name of the parent schema to list within, as `schemas/{catalog}.{schema}`. + // Each `{...}` component is capped at 255 characters individually. + Parent *string + // Maximum number of provider services to return. Defaults to 100 when unset or + // 0; the maximum is 100. Use `page_token` to retrieve additional pages. + PageSize *int + // Opaque pagination token from a previous request. + PageToken *string + // View selector controlling which fields are populated per row. `FULL` returns + // the full representation of the service; `BASIC` returns a more compact + // version. Defaults to `BASIC` when unset. + View ListModelProviderServicesRequest_View +} + +// Response for listing model provider services.. +type ListModelProviderServicesResponse struct { + // The list of model provider services. + ModelProviderServices []ModelProviderService + // Pagination token for retrieving the next page of results. + NextPageToken *string +} + +// Request to list model services. Accepts `parent`, `page_size`, and +// `page_token`.. +type ListModelServicesRequest struct { + // Name of the parent schema to list within, as `schemas/{catalog}.{schema}`. + // Each `{...}` component is capped at 255 characters individually. + Parent *string + // Maximum number of model services to return. Defaults to 100 when unset or 0; + // the maximum is 100. Use `page_token` to retrieve additional pages. + PageSize *int + // Opaque pagination token from a previous request. + PageToken *string + // View selector controlling which fields are populated per row. `FULL` returns + // the full representation of the service; `BASIC` returns a more compact + // version. Defaults to `BASIC` when unset. + View ListModelServicesRequest_View +} + +// Response for listing model services.. +type ListModelServicesResponse struct { + // The list of model services. + ModelServices []ModelService + // Pagination token for retrieving the next page of results. + NextPageToken *string +} + +// A governed MCP server registration in Unity Catalog. Acts as a container +// securable that references an MCP server -- customer-external via a UC +// Connection, or -hosted via an internal server -- and exposes its +// tools for discovery, authorization, and invocation.. +type McpService struct { + // Resource name of the MCP service. Format: + // `mcp-services/{catalog}.{schema}.{mcp_service}`. Each `{...}` component is + // capped at 255 characters individually. Server-derived on Create from `parent` + // + `mcp_service_id`; required and immutable on Update/Get/Delete. + Name *string `fieldmask:"name"` + // The owner of the MCP service. Write-only; read owner via effective_owner. + Owner *string `fieldmask:"owner"` + // The resolved owner of the MCP service. Falls back to the caller's identity + // when `owner` is not explicitly set on creation. + EffectiveOwner *string `fieldmask:"effective_owner"` + // Metastore hosting the MCP service. + MetastoreId *string `fieldmask:"metastore_id"` + // When the MCP service was created. + CreateTime *types.Time `fieldmask:"create_time"` + // Creator identity. + CreatedBy *string `fieldmask:"created_by"` + // When the MCP service was last modified. + UpdateTime *types.Time `fieldmask:"update_time"` + // Identity of the last updater. + UpdatedBy *string `fieldmask:"updated_by"` + // User-provided description. + Comment *string `fieldmask:"comment"` + // Operational configuration: connection, tool selectors, rate limit. Required + // on CreateMcpService; on UpdateMcpService it is required only when `config` + // (or a `config.*` subpath) appears in `update_mask`. + Config *McpServiceConfig `fieldmask:"config"` + // Optimistic concurrency control token. Server-generated from the entity's + // state and returned on every read. To use it as an if-match precondition on a + // mutation, echo the last-read value back via the dedicated `etag` field on the + // Update / Delete request; the server rejects the mutation if the stored etag + // differs. + Etag []byte `fieldmask:"etag"` +} + +// Operational configuration for an MCP service. Groups the source reference, +// tool selectors, and rate limit -- the fields that configure how the MCP +// service behaves at invocation time.. +type McpServiceConfig struct { + // Polymorphic reference to where the MCP server lives. MCP_SERVICE is a + // single-kind securable (`MCP_SERVICE_STANDARD`) with two source variants: + // `source_connection` (a UC Connection FQN) and `internal` (a + // -hosted MCP server). (-- Future MANAGED variants (if introduced) + // would slot additional oneof entries here. --) + // + // JSON shape: the active oneof variant appears as a sibling field on `config` + // (proto JSON does not nest the oneof container name). E.g.: { "config": { + // "source_connection": {"name": "connections/main.default.gh"}, + // "include_tool_selectors": ["read_*"], ... } } { "config": { "internal": + // {"server": "sandbox"}, ... } } Future variants slot in the same way: + // `{"config": {"app": {...}, ...}}`, `{"config": {"genie": {...}, ...}}`, etc. + // (-- The oneof shape lets future kinds add type-specific reference shapes + // without a wire-format bump. --) + Source isMcpServiceConfig_Source + // Glob or exact-match patterns selecting which tools from the MCP server to + // expose. Prefix match for patterns with `*`, exact match otherwise. An empty + // list means all tools are included. Per-element max 256 chars. + IncludeToolSelectors []string `fieldmask:"include_tool_selectors"` + // Per-principal rate limits applied to tool invocations routed through this MCP + // service. Repeated to support per-USER / USER_GROUP / SERVICE_PRINCIPAL / + // SERVICE / USER_DEFAULT scopes simultaneously, mirroring the + // `ModelServiceConfig.rate_limits` shape. Empty when no rate limit is + // configured. + RateLimits []RateLimit `fieldmask:"rate_limits"` + _ [0]mcpServiceConfigSourceFieldMaskMetadata `fieldmask_oneof:"Source"` +} + +type isMcpServiceConfig_Source interface { + isMcpServiceConfig_Source() +} + +// McpServiceConfig_Source_SourceConnection selects SourceConnection for McpServiceConfig.Source. +// UC Connection referencing the MCP server. +type McpServiceConfig_Source_SourceConnection struct { + SourceConnection McpServiceConfig_SourceConnection `fieldmask:"source_connection"` +} + +func (*McpServiceConfig_Source_SourceConnection) isMcpServiceConfig_Source() {} + +type mcpServiceConfigSourceFieldMaskMetadata struct { + *McpServiceConfig_Source_SourceConnection +} + +// UC Connection that hosts the MCP server. On create, provide `name` in the +// schema-scoped form `connections/{catalog}.{schema}.{connection}`. On read, +// the service populates the resolved connection metadata and preserves a +// dangling source so callers can diagnose a deleted backing connection.. +type McpServiceConfig_SourceConnection struct { + // Name of the UC connection that hosts the MCP server, as + // `connections/{catalog}.{schema}.{connection}`. + Name *string `fieldmask:"name"` + IsDeleted *bool `fieldmask:"is_deleted"` +} + +// A governed external model-provider connection stored in Unity Catalog (e.g. +// an OpenAI API account, an Azure OpenAI deployment, an Amazon Bedrock +// account). Owns the provider type and the auth/configuration the platform +// needs to invoke that provider, and is referenced from +// `ExternalModelConfig.model_provider_service` on a ModelService. +// +// One ModelProviderService can back many ModelServices (e.g. an `openai_prod` +// provider serving multiple models); a single ModelService can fan out across +// multiple ModelProviderServices for traffic split or failover.. +type ModelProviderService struct { + // Resource name of the provider service. Format: + // `model-provider-services/{catalog}.{schema}.{model_provider_service}`. Each + // `{...}` component is capped at 255 characters individually. Server-derived on + // Create from `parent` + `model_provider_service_id`; required and immutable on + // Update/Get/Delete. + Name *string `fieldmask:"name"` + // The owner of the model provider service. Write-only; read owner via + // effective_owner. + Owner *string `fieldmask:"owner"` + // The resolved owner of the model provider service. Falls back to the caller's + // identity when `owner` is not explicitly set on creation. + EffectiveOwner *string `fieldmask:"effective_owner"` + // Metastore hosting the provider service. + MetastoreId *string `fieldmask:"metastore_id"` + // When the provider service was created. + CreateTime *types.Time `fieldmask:"create_time"` + // Creator identity. + CreatedBy *string `fieldmask:"created_by"` + // When the provider service was last modified. + UpdateTime *types.Time `fieldmask:"update_time"` + // Identity of the last updater. + UpdatedBy *string `fieldmask:"updated_by"` + // User-provided description. + Comment *string `fieldmask:"comment"` + // Optimistic concurrency control token. Server-generated from the entity's + // state and returned on every read. To use it as an if-match precondition on a + // mutation, echo the last-read value back via the dedicated `etag` field on the + // Update / Delete request; the server rejects the mutation if the stored etag + // differs. + Etag []byte `fieldmask:"etag"` + // Behavioral configuration: provider connection, model catalog, and passthrough + // policy. See `ModelProviderServiceConfig` for the per-field contract. Required + // on CreateModelProviderService; on Update it is required only when `config` + // (or a `config.*` subpath) appears in `update_mask`. + Config *ModelProviderServiceConfig `fieldmask:"config"` +} + +// Behavioral configuration for a ModelProviderService: provider connection +// (auth + provider-specific fields), the catalog of models this provider +// service can route to, and the passthrough policy that governs how request +// headers, query parameters, and unmanaged subpaths cross the trust boundary to +// the upstream provider.. +type ModelProviderServiceConfig struct { + // Provider type discriminator. Required at create time; immutable after. + // Determines which variant of the `provider` oneof must be set. May not be + // changed via Update; attempts to include `config.provider_type` in + // `UpdateModelProviderServiceRequest.update_mask` are rejected. + // + // Required on CreateModelProviderService and immutable thereafter. + ProviderType ModelProviderServiceConfig_ExternalModelProviderType `fieldmask:"provider_type"` + // Provider-specific configuration. Exactly one variant must be set, and it must + // match `provider_type`; a request whose active variant disagrees with + // `provider_type` is rejected with `INVALID_PARAMETER_VALUE`. Secret-bearing + // fields nested inside each *DirectConfig (`api_key`, `aws_secret_access_key`, + // `service_account_key`, ...) wrap a `ProviderSecret`: callers supply the value + // as `ProviderSecret.plaintext` on writes, and the platform stores it + // encrypted. Reads (Get and List) omit the plaintext; secret-bearing fields + // appear in the response only as a presence indicator that a secret is + // configured. Non-secret fields (`base_url`, `region`, `organization`, + // `aws_access_key_id`, ...) round-trip directly. + // + // Declarative tooling (Terraform / DABs): the `plaintext` field is INPUT_ONLY + // and never round-trips on reads, so a Terraform config that supplies it will + // see a structural diff against the read state on every `terraform plan` unless + // mitigated. Mitigations, in order of preference: (a) use Terraform 1.11+ + // `WriteOnly` attribute on `plaintext` in the provider schema; (b) + // add provider `DiffSuppressFunc` for the secret field; (c) document + // `lifecycle.ignore_changes = []` for callers. The stored secret + // is normally changed through `UpdateModelProviderService`. + // + // (-- Secrets are persisted as the encrypted credential of a per-MPS UC + // SchemaConnection (`CONNECTION_HTTP_BEARER`). The auto-minted SchemaConnection + // is user-owned but hidden from the user, so it is not surfaced as a connection + // they manage directly even though the credential could in principle be changed + // out of band. --) + // + // (-- Field-behavior on the per-provider config fields: + // `(google.api.field_behavior) = OPTIONAL` everywhere on the *DirectConfig + // descendants, with Create-time requirements enforced in the validator. + // Proto-level REQUIRED is deliberately not used per the + // `proto-required-vs-update-mask` guardrail: REQUIRED would reject sparse + // Update requests that legitimately omit a field whose value is unchanged, + // breaking AIP-134 partial-Update. The user-facing javadoc on each field states + // which fields are required on Create. --) + Provider isModelProviderServiceConfig_Provider + // When true, accepts any model exposed by the upstream provider; `targets` is + // not required and does not restrict routability. When false, only models + // listed in `targets` are routable. + AllowAllTargets *bool `fieldmask:"allow_all_targets"` + // Routing targets this provider service exposes (provider-side model identifier + // + unified API types per entry). Required (>=1) when `allow_all_targets = + // false`; optional and additive when `allow_all_targets = true`. References + // from `ExternalModelConfig.target` must match an entry here unless + // `allow_all_targets = true`. + Targets []ModelProviderServiceConfig_ModelTargetConfig `fieldmask:"targets"` + // Whether to forward incoming request headers to the upstream provider. Applies + // to managed (multi-model) requests as well as passthrough requests served by + // this provider service. Governance-level decision by the provider service + // owner; not selectable per inference call. + ForwardHeaders *bool `fieldmask:"forward_headers"` + // Whether to forward incoming request query parameters to the upstream + // provider. Same trust-boundary semantics as `forward_headers`. + ForwardQueryParameters *bool `fieldmask:"forward_query_parameters"` + // Whether to forward request paths that fall outside this service's managed API + // set to the upstream provider as opaque passthrough. When true, requests + // addressed to subpaths not recognized by the managed API surface are proxied + // to the upstream provider over the same provider connection. When false, only + // managed-API paths are served. Governance-level decision by the provider + // service owner; expanding this expands the trust boundary that the + // ModelProviderService exposes. + ForwardUnmanagedPaths *bool `fieldmask:"forward_unmanaged_paths"` + // Rate limits applied when this provider service is invoked directly. When it + // is invoked through a model service, the model service's own `rate_limits` + // apply instead. Mirrors `ModelServiceConfig.rate_limits` / + // `McpServiceConfig.rate_limits`. + RateLimits []RateLimit `fieldmask:"rate_limits"` + // Inference table configuration for payload logging when this provider service + // is invoked directly. When it is invoked through a model service, the model + // service's own inference table captures the invocation instead. Mirrors + // `ModelServiceConfig.inference_table` / `AgentServiceConfig.inference_table`. + InferenceTable *InferenceTableConfig `fieldmask:"inference_table"` + _ [0]modelProviderServiceConfigProviderFieldMaskMetadata `fieldmask_oneof:"Provider"` +} + +type isModelProviderServiceConfig_Provider interface { + isModelProviderServiceConfig_Provider() +} + +// ModelProviderServiceConfig_Provider_Openai selects Openai for ModelProviderServiceConfig.Provider. +type ModelProviderServiceConfig_Provider_Openai struct { + Openai ModelProviderServiceConfig_OpenAiProviderConfig `fieldmask:"openai"` +} + +func (*ModelProviderServiceConfig_Provider_Openai) isModelProviderServiceConfig_Provider() {} + +// ModelProviderServiceConfig_Provider_AzureOpenai selects AzureOpenai for ModelProviderServiceConfig.Provider. +type ModelProviderServiceConfig_Provider_AzureOpenai struct { + AzureOpenai ModelProviderServiceConfig_AzureOpenAiProviderConfig `fieldmask:"azure_openai"` +} + +func (*ModelProviderServiceConfig_Provider_AzureOpenai) isModelProviderServiceConfig_Provider() {} + +// ModelProviderServiceConfig_Provider_Anthropic selects Anthropic for ModelProviderServiceConfig.Provider. +type ModelProviderServiceConfig_Provider_Anthropic struct { + Anthropic ModelProviderServiceConfig_AnthropicProviderConfig `fieldmask:"anthropic"` +} + +func (*ModelProviderServiceConfig_Provider_Anthropic) isModelProviderServiceConfig_Provider() {} + +// ModelProviderServiceConfig_Provider_AmazonBedrock selects AmazonBedrock for ModelProviderServiceConfig.Provider. +type ModelProviderServiceConfig_Provider_AmazonBedrock struct { + AmazonBedrock ModelProviderServiceConfig_AmazonBedrockProviderConfig `fieldmask:"amazon_bedrock"` +} + +func (*ModelProviderServiceConfig_Provider_AmazonBedrock) isModelProviderServiceConfig_Provider() {} + +// ModelProviderServiceConfig_Provider_Custom selects Custom for ModelProviderServiceConfig.Provider. +type ModelProviderServiceConfig_Provider_Custom struct { + Custom ModelProviderServiceConfig_CustomProviderConfig `fieldmask:"custom"` +} + +func (*ModelProviderServiceConfig_Provider_Custom) isModelProviderServiceConfig_Provider() {} + +// ModelProviderServiceConfig_Provider_MicrosoftFoundry selects MicrosoftFoundry for ModelProviderServiceConfig.Provider. +type ModelProviderServiceConfig_Provider_MicrosoftFoundry struct { + MicrosoftFoundry ModelProviderServiceConfig_MicrosoftFoundryProviderConfig `fieldmask:"microsoft_foundry"` +} + +func (*ModelProviderServiceConfig_Provider_MicrosoftFoundry) isModelProviderServiceConfig_Provider() { +} + +// ModelProviderServiceConfig_Provider_GeminiEnterprise selects GeminiEnterprise for ModelProviderServiceConfig.Provider. +type ModelProviderServiceConfig_Provider_GeminiEnterprise struct { + GeminiEnterprise ModelProviderServiceConfig_GeminiEnterpriseProviderConfig `fieldmask:"gemini_enterprise"` +} + +func (*ModelProviderServiceConfig_Provider_GeminiEnterprise) isModelProviderServiceConfig_Provider() { +} + +type modelProviderServiceConfigProviderFieldMaskMetadata struct { + *ModelProviderServiceConfig_Provider_Openai + *ModelProviderServiceConfig_Provider_AzureOpenai + *ModelProviderServiceConfig_Provider_Anthropic + *ModelProviderServiceConfig_Provider_AmazonBedrock + *ModelProviderServiceConfig_Provider_Custom + *ModelProviderServiceConfig_Provider_MicrosoftFoundry + *ModelProviderServiceConfig_Provider_GeminiEnterprise +} + +// Amazon Bedrock provider configuration.. +type ModelProviderServiceConfig_AmazonBedrockProviderConfig struct { + // Direct (inline-credentials) form: caller supplies AWS region + auth + // (access-key pair) in the request body. Required on Create. Provider + // configuration mode. Exactly one variant may be set. (-- Wrapped in a oneof so + // future non-direct modes can be added as additional variants without a + // breaking change. --) + ProviderMode isModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode + _ [0]modelProviderServiceConfig_AmazonBedrockProviderConfigProviderModeFieldMaskMetadata `fieldmask_oneof:"ProviderMode"` +} + +type isModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode interface { + isModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode() +} + +// ModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode_Direct selects Direct for ModelProviderServiceConfig_AmazonBedrockProviderConfig.ProviderMode. +type ModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode_Direct struct { + Direct ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig `fieldmask:"direct"` +} + +func (*ModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode_Direct) isModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode() { +} + +type modelProviderServiceConfig_AmazonBedrockProviderConfigProviderModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode_Direct +} + +// Direct form of Amazon Bedrock provider config. +// +// Authentication is one of two mutually exclusive modes, exactly one of which +// must be supplied on Create: - Access keys: set `aws_access_key`, leave +// `service_credential` unset. - UC service credential: set +// `service_credential.name` to the AIP-122 resource-name form +// `credentials/{name}`, leave `aws_access_key` unset. The credential value +// lives in UC and is referenced by name, not held on this message. Setting more +// than one mode is rejected.. +type ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig struct { + // AWS region where the Bedrock endpoint is hosted (e.g., `us-east-1`). Required + // on Create. + Region *string `fieldmask:"region"` + // Authentication mode. Exactly one variant may be set. + AuthMode isModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode + _ [0]modelProviderServiceConfig_AmazonBedrockProviderDirectConfigAuthModeFieldMaskMetadata `fieldmask_oneof:"AuthMode"` +} + +type isModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode interface { + isModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode() +} + +// ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_ServiceCredential selects ServiceCredential for ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig.AuthMode. +// Reference to a UC service credential authorizing Bedrock requests. On Create +// the caller supplies `service_credential.name` in the AIP-122 resource-name +// form `credentials/{name}`. Required on Create when using +// UC-service-credential auth; mutually exclusive with `aws_access_key`. The +// credential is referenced by name; its value is not carried here. On read the +// resolved `id` and `is_deleted` are also populated. Only supported on +// AWS-hosted workspaces; Create requests from other clouds are rejected with +// INVALID_PARAMETER_VALUE. +type ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_ServiceCredential struct { + ServiceCredential ModelProviderServiceConfig_ServiceCredential `fieldmask:"service_credential"` +} + +func (*ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_ServiceCredential) isModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode() { +} + +// ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_AwsAccessKey selects AwsAccessKey for ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig.AuthMode. +// AWS access-key-pair auth. Mutually exclusive with `service_credential`. +type ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_AwsAccessKey struct { + AwsAccessKey ModelProviderServiceConfig_AwsAccessKey `fieldmask:"aws_access_key"` +} + +func (*ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_AwsAccessKey) isModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode() { +} + +type modelProviderServiceConfig_AmazonBedrockProviderDirectConfigAuthModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_ServiceCredential + *ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_AwsAccessKey +} + +// Anthropic provider configuration. Exactly one of `direct` or `relayed` must +// be set on Create; the two are mutually exclusive.. +type ModelProviderServiceConfig_AnthropicProviderConfig struct { + // Provider configuration mode. Exactly one variant may be set: an inline + // credential (`direct`) or credential-less relaying (`relayed`). (-- Anthropic + // is the only provider with a non-direct mode today. The oneof enforces + // direct-vs-relayed exclusivity on the wire; the validator still enforces that + // one of them is set on Create and per-mode completeness (e.g. + // relayed.plan_type). --) + ProviderMode isModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode + _ [0]modelProviderServiceConfig_AnthropicProviderConfigProviderModeFieldMaskMetadata `fieldmask_oneof:"ProviderMode"` +} + +type isModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode interface { + isModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode() +} + +// ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Direct selects Direct for ModelProviderServiceConfig_AnthropicProviderConfig.ProviderMode. +// Direct (inline-credentials) form: caller supplies the API key in the request +// body. Required on Create unless `relayed` is set. +type ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Direct struct { + Direct ModelProviderServiceConfig_AnthropicProviderDirectConfig `fieldmask:"direct"` +} + +func (*ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Direct) isModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode() { +} + +// ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Relayed selects Relayed for ModelProviderServiceConfig_AnthropicProviderConfig.ProviderMode. +// Relayed (credential-less) form: no Anthropic credential is stored. Each +// inference request instead carries the caller's own OAuth token, which the +// platform forwards to Anthropic on outbound requests. Mutually exclusive with +// `direct`; no `api_key` is required or persisted. +type ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Relayed struct { + Relayed ModelProviderServiceConfig_AnthropicProviderRelayedConfig `fieldmask:"relayed"` +} + +func (*ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Relayed) isModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode() { +} + +type modelProviderServiceConfig_AnthropicProviderConfigProviderModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Direct + *ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Relayed +} + +// Direct form of Anthropic provider config.. +type ModelProviderServiceConfig_AnthropicProviderDirectConfig struct { + // Authentication mode. Exactly one variant may be set. (-- Wrapped in a oneof + // so future auth modes (e.g. a UC service credential) can be added as + // additional variants without a breaking change. --) + AuthMode isModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode + _ [0]modelProviderServiceConfig_AnthropicProviderDirectConfigAuthModeFieldMaskMetadata `fieldmask_oneof:"AuthMode"` +} + +type isModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode interface { + isModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode() +} + +// ModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode_ApiKey selects ApiKey for ModelProviderServiceConfig_AnthropicProviderDirectConfig.AuthMode. +// Anthropic API key. Required on Create. Sent as the `x-api-key` header on +// outbound requests. Supplied as inline plaintext via +// `ProviderSecret.plaintext`. +type ModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode_ApiKey struct { + ApiKey ModelProviderServiceConfig_ProviderSecret `fieldmask:"api_key"` +} + +func (*ModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode_ApiKey) isModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode() { +} + +type modelProviderServiceConfig_AnthropicProviderDirectConfigAuthModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode_ApiKey +} + +// Relayed form of Anthropic provider config: no credential is stored. +// Authentication is the caller's own OAuth token, forwarded to Anthropic on +// outbound requests, so there is no persisted secret. Presence of this variant +// is the signal that the provider service uses relayed auth; `plan_type` +// further distinguishes which Anthropic subscription tier the token belongs to.. +type ModelProviderServiceConfig_AnthropicProviderRelayedConfig struct { + // Which Anthropic subscription tier the relayed token belongs to. Optional; + // when unset the MPS gets the full governance surface (see TEAM_ENTERPRISE). + // Immutable after Create, so the tier cannot be flipped in place. + PlanType ModelProviderServiceConfig_AnthropicProviderRelayedConfig_AnthropicRelayedPlanType `fieldmask:"plan_type"` +} + +// AWS access-key-pair auth for Amazon Bedrock: a SigV4-signing key pair.. +type ModelProviderServiceConfig_AwsAccessKey struct { + // AWS access key ID. Required on Create when using access-key auth. Treated as + // username-equivalent (not a secret value): round-trips on reads and is + // scrubbed from audit logs. + AccessKeyId *string `fieldmask:"access_key_id"` + // AWS secret access key paired with `access_key_id`. Required on Create when + // using access-key auth. Supplied as inline plaintext via + // `ProviderSecret.plaintext`. + SecretAccessKey *ModelProviderServiceConfig_ProviderSecret `fieldmask:"secret_access_key"` +} + +// Azure OpenAI provider configuration.. +type ModelProviderServiceConfig_AzureOpenAiProviderConfig struct { + // Direct (inline-credentials) form: caller supplies the auth secrets and the + // Azure endpoint base URL in the request body. Required on Create. Provider + // configuration mode. Exactly one variant may be set. (-- Wrapped in a oneof so + // future non-direct modes can be added as additional variants without a + // breaking change. --) + ProviderMode isModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode + _ [0]modelProviderServiceConfig_AzureOpenAiProviderConfigProviderModeFieldMaskMetadata `fieldmask_oneof:"ProviderMode"` +} + +type isModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode interface { + isModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode() +} + +// ModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode_Direct selects Direct for ModelProviderServiceConfig_AzureOpenAiProviderConfig.ProviderMode. +type ModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode_Direct struct { + Direct ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig `fieldmask:"direct"` +} + +func (*ModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode_Direct) isModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode() { +} + +type modelProviderServiceConfig_AzureOpenAiProviderConfigProviderModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode_Direct +} + +// Direct form of Azure OpenAI provider config. Exactly one of three +// mutually-exclusive auth modes must be supplied on Create: - API key: set +// `api_key`, leave `entra_service_principal` and `service_credential` unset. - +// Entra ID (service principal): set `entra_service_principal`, leave `api_key` +// and `service_credential` unset. - UC service credential: set +// `service_credential.name` to the AIP-122 resource-name form +// `credentials/{name}`, leave `api_key` and `entra_service_principal` unset. +// The credential value lives in UC and is referenced by name, not held on this +// message. Only supported on Azure-hosted workspaces. Setting more than one +// mode is rejected.. +type ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig struct { + // Full Azure OpenAI endpoint base URL, e.g. + // `https://myresource.openai.azure.com`. Required on Create. + BaseUrl *string `fieldmask:"base_url"` + // Authentication mode. Exactly one variant may be set. + AuthMode isModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode + _ [0]modelProviderServiceConfig_AzureOpenAiProviderDirectConfigAuthModeFieldMaskMetadata `fieldmask_oneof:"AuthMode"` +} + +type isModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode interface { + isModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode() +} + +// ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ApiKey selects ApiKey for ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode. +// Azure OpenAI API key. Mutually exclusive with the Entra and +// service-credential modes. Supplied as inline plaintext via +// `ProviderSecret.plaintext`. +type ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ApiKey struct { + ApiKey ModelProviderServiceConfig_ProviderSecret `fieldmask:"api_key"` +} + +func (*ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ApiKey) isModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode() { +} + +// ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ServiceCredential selects ServiceCredential for ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode. +// Reference to a UC service credential authorizing Azure OpenAI requests. On +// Create the caller supplies `service_credential.name` in the AIP-122 +// resource-name form `credentials/{name}`. Required on Create when using +// UC-service-credential auth; mutually exclusive with `api_key` and +// `entra_service_principal`. The credential is referenced by name; its value is +// not carried here. On read the resolved `id` and `is_deleted` are also +// populated. Only supported on Azure-hosted workspaces; Create requests from +// other clouds are rejected with INVALID_PARAMETER_VALUE. +type ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ServiceCredential struct { + ServiceCredential ModelProviderServiceConfig_ServiceCredential `fieldmask:"service_credential"` +} + +func (*ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ServiceCredential) isModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode() { +} + +// ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_EntraServicePrincipal selects EntraServicePrincipal for ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode. +// Entra ID (service principal) auth. Mutually exclusive with `api_key` and +// `service_credential`. +type ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_EntraServicePrincipal struct { + EntraServicePrincipal ModelProviderServiceConfig_EntraServicePrincipal `fieldmask:"entra_service_principal"` +} + +func (*ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_EntraServicePrincipal) isModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode() { +} + +type modelProviderServiceConfig_AzureOpenAiProviderDirectConfigAuthModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ApiKey + *ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ServiceCredential + *ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_EntraServicePrincipal +} + +// Custom provider configuration: arbitrary HTTP endpoint with bearer-token +// auth.. +type ModelProviderServiceConfig_CustomProviderConfig struct { + // Direct (inline-credentials) form: caller supplies the endpoint URL + bearer + // token in the request body. Required on Create. Provider configuration mode. + // Exactly one variant may be set. (-- Wrapped in a oneof so future non-direct + // modes can be added as additional variants without a breaking change. --) + ProviderMode isModelProviderServiceConfig_CustomProviderConfig_ProviderMode + _ [0]modelProviderServiceConfig_CustomProviderConfigProviderModeFieldMaskMetadata `fieldmask_oneof:"ProviderMode"` +} + +type isModelProviderServiceConfig_CustomProviderConfig_ProviderMode interface { + isModelProviderServiceConfig_CustomProviderConfig_ProviderMode() +} + +// ModelProviderServiceConfig_CustomProviderConfig_ProviderMode_Direct selects Direct for ModelProviderServiceConfig_CustomProviderConfig.ProviderMode. +type ModelProviderServiceConfig_CustomProviderConfig_ProviderMode_Direct struct { + Direct ModelProviderServiceConfig_CustomProviderDirectConfig `fieldmask:"direct"` +} + +func (*ModelProviderServiceConfig_CustomProviderConfig_ProviderMode_Direct) isModelProviderServiceConfig_CustomProviderConfig_ProviderMode() { +} + +type modelProviderServiceConfig_CustomProviderConfigProviderModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_CustomProviderConfig_ProviderMode_Direct +} + +// Direct form of custom provider config. +// +// Authentication is one of two mutually exclusive modes, exactly one of which +// must be supplied on Create: - Bearer: set `api_key`, leave `header_auth` +// unset. The secret is forwarded as `Authorization: Bearer `. - Header: +// set `header_auth`, leave `api_key` unset. The secret is forwarded as +// `: `. Setting both modes or neither mode is +// rejected.. +type ModelProviderServiceConfig_CustomProviderDirectConfig struct { + // Endpoint URL of the OpenAI-compatible service (e.g., + // `https://api.example.com/v1`). Required on Create. + BaseUrl *string `fieldmask:"base_url"` + // Authentication mode. Exactly one variant may be set. (-- Mutual exclusivity + // is enforced by the oneof on the wire. --) + AuthMode isModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode + _ [0]modelProviderServiceConfig_CustomProviderDirectConfigAuthModeFieldMaskMetadata `fieldmask_oneof:"AuthMode"` +} + +type isModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode interface { + isModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode() +} + +// ModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode_ApiKey selects ApiKey for ModelProviderServiceConfig_CustomProviderDirectConfig.AuthMode. +// Bearer token forwarded as the `Authorization: Bearer ...` header on outbound +// requests. Supplied as inline plaintext via `ProviderSecret.plaintext`. Set +// this for bearer-token auth. +type ModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode_ApiKey struct { + ApiKey ModelProviderServiceConfig_ProviderSecret `fieldmask:"api_key"` +} + +func (*ModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode_ApiKey) isModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode() { +} + +type modelProviderServiceConfig_CustomProviderDirectConfigAuthModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode_ApiKey +} + +// Entra ID (Azure AD) service-principal auth: AI Gateway exchanges the +// `tenant_id` + `client_id` identify the service principal, and the +// `credential` oneof proves that identity, exchanged for an Entra bearer token +// on outbound requests via the OAuth2 client-credentials grant. Shared by the +// Azure OpenAI and Microsoft Foundry provider configs.. +type ModelProviderServiceConfig_EntraServicePrincipal struct { + // Entra ID (Azure AD) tenant ID. Required on Create. + TenantId *string `fieldmask:"tenant_id"` + // Entra ID client (application) ID. Required on Create. + ClientId *string `fieldmask:"client_id"` + // How the service principal proves its identity. Exactly one variant must be + // set on Create. Today only `client_secret` is supported. (-- A oneof so + // additional proof mechanisms can be added as non-breaking variants without + // changing the tenant_id / client_id identity fields. --) + Credential isModelProviderServiceConfig_EntraServicePrincipal_Credential + _ [0]modelProviderServiceConfig_EntraServicePrincipalCredentialFieldMaskMetadata `fieldmask_oneof:"Credential"` +} + +type isModelProviderServiceConfig_EntraServicePrincipal_Credential interface { + isModelProviderServiceConfig_EntraServicePrincipal_Credential() +} + +// ModelProviderServiceConfig_EntraServicePrincipal_Credential_ClientSecret selects ClientSecret for ModelProviderServiceConfig_EntraServicePrincipal.Credential. +// Entra ID client secret. Supplied as inline plaintext via +// `ProviderSecret.plaintext`. +type ModelProviderServiceConfig_EntraServicePrincipal_Credential_ClientSecret struct { + ClientSecret ModelProviderServiceConfig_ProviderSecret `fieldmask:"client_secret"` +} + +func (*ModelProviderServiceConfig_EntraServicePrincipal_Credential_ClientSecret) isModelProviderServiceConfig_EntraServicePrincipal_Credential() { +} + +type modelProviderServiceConfig_EntraServicePrincipalCredentialFieldMaskMetadata struct { + *ModelProviderServiceConfig_EntraServicePrincipal_Credential_ClientSecret +} + +// Gemini Enterprise provider configuration.. +type ModelProviderServiceConfig_GeminiEnterpriseProviderConfig struct { + // Direct (inline-credentials) form: caller supplies the API key in the request + // body. Required on Create. Provider configuration mode. Exactly one variant + // may be set. (-- Wrapped in a oneof so future non-direct modes can be added as + // additional variants without a breaking change. --) + ProviderMode isModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode + _ [0]modelProviderServiceConfig_GeminiEnterpriseProviderConfigProviderModeFieldMaskMetadata `fieldmask_oneof:"ProviderMode"` +} + +type isModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode interface { + isModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode() +} + +// ModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode_Direct selects Direct for ModelProviderServiceConfig_GeminiEnterpriseProviderConfig.ProviderMode. +type ModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode_Direct struct { + Direct ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig `fieldmask:"direct"` +} + +func (*ModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode_Direct) isModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode() { +} + +type modelProviderServiceConfig_GeminiEnterpriseProviderConfigProviderModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode_Direct +} + +// Direct form of Gemini Enterprise provider config. +// +// Authentication is one of two mutually exclusive modes; exactly one must be +// supplied on Create: - API key: set `api_key`, leave `service_credential` +// unset. - UC service credential: set `service_credential`, leave `api_key` +// unset.. +type ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig struct { + // Authentication mode. Exactly one variant may be set. + AuthMode isModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode + // GCP project ID hosting the Gemini Enterprise endpoint. Required on Create. + ProjectId *string `fieldmask:"project_id"` + // GCP region of the Gemini Enterprise endpoint (e.g., `us-central1`). Required + // on Create. + Region *string `fieldmask:"region"` + _ [0]modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigAuthModeFieldMaskMetadata `fieldmask_oneof:"AuthMode"` +} + +type isModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode interface { + isModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode() +} + +// ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode_ApiKey selects ApiKey for ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig.AuthMode. +// Google Gemini Enterprise API key. Required on Create when using API-key auth; +// mutually exclusive with `service_credential`. Supplied as inline plaintext +// via `ProviderSecret.plaintext`. +type ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode_ApiKey struct { + ApiKey ModelProviderServiceConfig_ProviderSecret `fieldmask:"api_key"` +} + +func (*ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode_ApiKey) isModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode() { +} + +type modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigAuthModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode_ApiKey +} + +// Microsoft Foundry provider configuration.. +type ModelProviderServiceConfig_MicrosoftFoundryProviderConfig struct { + // Direct (inline-credentials) form: caller supplies the Foundry endpoint URL + + // API key in the request body. Required on Create. Provider configuration mode. + // Exactly one variant may be set. (-- Wrapped in a oneof so future non-direct + // modes can be added as additional variants without a breaking change. --) + ProviderMode isModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode + _ [0]modelProviderServiceConfig_MicrosoftFoundryProviderConfigProviderModeFieldMaskMetadata `fieldmask_oneof:"ProviderMode"` +} + +type isModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode interface { + isModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode() +} + +// ModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode_Direct selects Direct for ModelProviderServiceConfig_MicrosoftFoundryProviderConfig.ProviderMode. +type ModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode_Direct struct { + Direct ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig `fieldmask:"direct"` +} + +func (*ModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode_Direct) isModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode() { +} + +type modelProviderServiceConfig_MicrosoftFoundryProviderConfigProviderModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode_Direct +} + +// Direct form of Microsoft Foundry provider config. +// +// Authentication is one of three mutually exclusive modes, exactly one of which +// must be supplied on Create: - API key: set `api_key`, leave +// `entra_service_principal` and `service_credential` unset. - Entra ID (service +// principal): set `entra_service_principal`, leave `api_key` and +// `service_credential` unset. AI Gateway exchanges these for an Entra bearer +// token on outbound requests via the OAuth2 client-credentials grant. - UC +// service credential: set `service_credential.name` to the AIP-122 +// resource-name form `credentials/{name}`, leave `api_key` and +// `entra_service_principal` unset. The credential value lives in UC and is +// referenced by name, not held on this message. Only supported on Azure-hosted +// workspaces. Setting more than one mode is rejected.. +type ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig struct { + // Microsoft AI Foundry endpoint URL. Required on Create. + BaseUrl *string `fieldmask:"base_url"` + // Authentication mode. Exactly one variant may be set. + AuthMode isModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode + _ [0]modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigAuthModeFieldMaskMetadata `fieldmask_oneof:"AuthMode"` +} + +type isModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode interface { + isModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode() +} + +// ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ApiKey selects ApiKey for ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode. +// Microsoft AI Foundry API key. Mutually exclusive with the Entra and +// service-credential modes. Supplied as inline plaintext via +// `ProviderSecret.plaintext`. +type ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ApiKey struct { + ApiKey ModelProviderServiceConfig_ProviderSecret `fieldmask:"api_key"` +} + +func (*ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ApiKey) isModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode() { +} + +// ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ServiceCredential selects ServiceCredential for ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode. +// Reference to a UC service credential authorizing Microsoft Foundry requests. +// On Create the caller supplies `service_credential.name` in the AIP-122 +// resource-name form `credentials/{name}`. Required on Create when using +// UC-service-credential auth; mutually exclusive with `api_key` and +// `entra_service_principal`. The credential is referenced by name; its value is +// not carried here. On read the resolved `id` and `is_deleted` are also +// populated. Only supported on Azure-hosted workspaces; Create requests from +// other clouds are rejected with INVALID_PARAMETER_VALUE. +type ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ServiceCredential struct { + ServiceCredential ModelProviderServiceConfig_ServiceCredential `fieldmask:"service_credential"` +} + +func (*ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ServiceCredential) isModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode() { +} + +// ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_EntraServicePrincipal selects EntraServicePrincipal for ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode. +// Entra ID (service principal) auth. Mutually exclusive with `api_key` and +// `service_credential`. +type ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_EntraServicePrincipal struct { + EntraServicePrincipal ModelProviderServiceConfig_EntraServicePrincipal `fieldmask:"entra_service_principal"` +} + +func (*ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_EntraServicePrincipal) isModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode() { +} + +type modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigAuthModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ApiKey + *ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ServiceCredential + *ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_EntraServicePrincipal +} + +// Model target configuration for an external model destination.. +type ModelProviderServiceConfig_ModelTargetConfig struct { + // Provider-side model identifier (e.g. "gpt-5", "claude-opus-4-7"). This is a + // string on the LLM provider's side, not a UC entity. The UC governance hook + // for external destinations is the ModelProviderService referenced by + // `ExternalModelConfig.model_provider_service`, not the model itself. + Model *string + // Provider-native API types the model supports (e.g. + // "openai/v1/chat/completions"). Used by the platform for request/response + // translation from the unified API type. At most 64 entries of at most 256 + // characters each; the list is persisted into the destination binding's bounded + // storage envelope. + NativeApiTypes []string +} + +// OpenAI provider configuration.. +type ModelProviderServiceConfig_OpenAiProviderConfig struct { + // Direct (inline-credentials) form: caller supplies the auth secrets in the + // request body. Required on Create. Secret values are stored encrypted and + // omitted from reads. Provider configuration mode. Exactly one variant may be + // set. (-- Wrapped in a oneof so future non-direct modes can be added as + // additional variants without a breaking change. --) + ProviderMode isModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode + _ [0]modelProviderServiceConfig_OpenAiProviderConfigProviderModeFieldMaskMetadata `fieldmask_oneof:"ProviderMode"` +} + +type isModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode interface { + isModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode() +} + +// ModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode_Direct selects Direct for ModelProviderServiceConfig_OpenAiProviderConfig.ProviderMode. +type ModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode_Direct struct { + Direct ModelProviderServiceConfig_OpenAiProviderDirectConfig `fieldmask:"direct"` +} + +func (*ModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode_Direct) isModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode() { +} + +type modelProviderServiceConfig_OpenAiProviderConfigProviderModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode_Direct +} + +// Direct (inline-credentials) form of the OpenAI provider config.. +type ModelProviderServiceConfig_OpenAiProviderDirectConfig struct { + // Authentication mode. Exactly one variant may be set. (-- Wrapped in a oneof + // so future auth modes (e.g. a UC service credential) can be added as + // additional variants without a breaking change. --) + AuthMode isModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode + // Optional OpenAI organization ID. When set, the platform forwards it as the + // `OpenAI-Organization` header. + Organization *string `fieldmask:"organization"` + // Optional custom base URL. Defaults to `https://api.openai.com/v1`. Use for + // OpenAI-API-compatible third-party endpoints or in-network proxies. + BaseUrl *string `fieldmask:"base_url"` + _ [0]modelProviderServiceConfig_OpenAiProviderDirectConfigAuthModeFieldMaskMetadata `fieldmask_oneof:"AuthMode"` +} + +type isModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode interface { + isModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode() +} + +// ModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode_ApiKey selects ApiKey for ModelProviderServiceConfig_OpenAiProviderDirectConfig.AuthMode. +// OpenAI API key. Required on Create. Supplied as inline plaintext via +// `ProviderSecret.plaintext`. +type ModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode_ApiKey struct { + ApiKey ModelProviderServiceConfig_ProviderSecret `fieldmask:"api_key"` +} + +func (*ModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode_ApiKey) isModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode() { +} + +type modelProviderServiceConfig_OpenAiProviderDirectConfigAuthModeFieldMaskMetadata struct { + *ModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode_ApiKey +} + +// A secret value supplied as part of an inline provider config. The caller +// supplies the value as inline `plaintext` on writes; the platform stores it +// encrypted. The `plaintext` field is `INPUT_ONLY` and never round-trips on +// reads.. +type ModelProviderServiceConfig_ProviderSecret struct { + // How the credential value is supplied. Exactly one variant may be set. (-- + // Wrapped in a oneof so a future non-plaintext source (e.g. a Databricks secret + // reference `{{secrets//}}`, mirroring AIGW v2's ProviderSecret) + // can be added as an additional variant without a breaking change. --) + Value isModelProviderServiceConfig_ProviderSecret_Value + _ [0]modelProviderServiceConfig_ProviderSecretValueFieldMaskMetadata `fieldmask_oneof:"Value"` +} + +type isModelProviderServiceConfig_ProviderSecret_Value interface { + isModelProviderServiceConfig_ProviderSecret_Value() +} + +// ModelProviderServiceConfig_ProviderSecret_Value_Plaintext selects Plaintext for ModelProviderServiceConfig_ProviderSecret.Value. +// Inline plaintext credential. INPUT_ONLY: the value never round-trips on +// reads. Get and List responses omit `plaintext`; the field's presence in the +// read shape only indicates that a secret is configured. +type ModelProviderServiceConfig_ProviderSecret_Value_Plaintext struct { + Plaintext string `fieldmask:"plaintext"` +} + +func (*ModelProviderServiceConfig_ProviderSecret_Value_Plaintext) isModelProviderServiceConfig_ProviderSecret_Value() { +} + +type modelProviderServiceConfig_ProviderSecretValueFieldMaskMetadata struct { + *ModelProviderServiceConfig_ProviderSecret_Value_Plaintext +} + +// ---- Provider configuration (nested; see the `provider` oneof below) ---- The +// customer-owned UC service credential a ModelProviderService uses to +// authenticate to its provider, referenced by name.. +type ModelProviderServiceConfig_ServiceCredential struct { + // Resource name of the bound UC service credential, in the AIP-122 form + // `credentials/{name}` (a metastore-level single-part credential name). On + // create the caller supplies the name here. On read it reflects the + // credential's current name at read time. + Name *string `fieldmask:"name"` +} + +// A governed AI Gateway endpoint in Unity Catalog that routes inference +// requests to one or more model destinations (for example a foundation model or +// an external LLM reached through a ModelProviderService). Applies centralized +// access control, rate limits, guardrails, and auditing to the traffic it +// serves.. +type ModelService struct { + // Resource name of the model service. Format: + // `model-services/{catalog}.{schema}.{model_service}`. Each `{...}` component + // is capped at 255 characters individually. Server-derived on Create from + // `parent` + `model_service_id`; required and immutable on Update/Get/Delete. + Name *string `fieldmask:"name"` + // The owner of the model service. Write-only; read owner via effective_owner. + Owner *string `fieldmask:"owner"` + // The resolved owner of the ModelService. Falls back to the caller's identity + // when `owner` is not explicitly set on creation. + EffectiveOwner *string `fieldmask:"effective_owner"` + // Metastore hosting the model service. + MetastoreId *string `fieldmask:"metastore_id"` + // When the model service was created. + CreateTime *types.Time `fieldmask:"create_time"` + // Creator identity. + CreatedBy *string `fieldmask:"created_by"` + // When the model service was last modified. + UpdateTime *types.Time `fieldmask:"update_time"` + // Identity of the last updater. + UpdatedBy *string `fieldmask:"updated_by"` + // User-provided description. + Comment *string `fieldmask:"comment"` + // Operational configuration: destinations, routing, rate limits, inference + // table. Required on CreateModelService; on UpdateModelService it is required + // only when `config` (or a `config.*` subpath) appears in `update_mask`. + Config *ModelServiceConfig `fieldmask:"config"` + // Optimistic concurrency control token. Server-generated from the entity's + // state and returned on every read. To use it as an if-match precondition on a + // mutation, echo the last-read value back via the dedicated `etag` field on the + // Update / Delete request; the server rejects the mutation if the stored etag + // differs. + Etag []byte `fieldmask:"etag"` + // Unified API types this endpoint supports (e.g. "chat", "embeddings", + // "completions"). Derived from the destinations' backing models / providers at + // read time. + SupportedApiTypes []string `fieldmask:"supported_api_types"` +} + +// Operational configuration wrapped around the ModelService resource.. +type ModelServiceConfig struct { + // Routing configuration: destinations, routing strategy, and fallback. + Routing *ModelServiceConfig_RoutingConfig `fieldmask:"routing"` + // Rate limits applied to requests routed through this model service. + RateLimits []RateLimit `fieldmask:"rate_limits"` + // Inference table config for payload logging. + InferenceTable *InferenceTableConfig `fieldmask:"inference_table"` +} + +// A destination the model service can route traffic to. Exactly one of the +// per-type configs inside `type_config` must be set, and it must match +// `destination_type`.. +type ModelServiceConfig_DestinationConfig struct { + // User-facing label for this destination, used in routing references. + Name *string + // Backing-model category. Determines which oneof variant is populated. + DestinationType ModelServiceConfig_DestinationConfig_DestinationType + // Share of traffic sent to this destination, 0-100. Optional on fallback + // destinations; see FallbackConfig. + TrafficPercentage *int + // Destination-type-specific configuration. + TypeConfig isModelServiceConfig_DestinationConfig_TypeConfig + // True when the destination's backing UC entity (MODEL for foundation-model + // destinations, MODEL_PROVIDER_SERVICE for external destinations) has been + // deleted but the destination row still references it. The dangling destination + // is surfaced (not silently dropped) so callers can see the broken routing. + // Inference traffic through this destination fails closed (BAD_REQUEST / + // FAILED_PRECONDITION). + IsDeleted *bool +} + +type isModelServiceConfig_DestinationConfig_TypeConfig interface { + isModelServiceConfig_DestinationConfig_TypeConfig() +} + +// ModelServiceConfig_DestinationConfig_TypeConfig_PayPerTokenConfig selects PayPerTokenConfig for ModelServiceConfig_DestinationConfig.TypeConfig. +type ModelServiceConfig_DestinationConfig_TypeConfig_PayPerTokenConfig struct { + PayPerTokenConfig ModelServiceConfig_PayPerTokenConfig +} + +func (*ModelServiceConfig_DestinationConfig_TypeConfig_PayPerTokenConfig) isModelServiceConfig_DestinationConfig_TypeConfig() { +} + +// ModelServiceConfig_DestinationConfig_TypeConfig_ProvisionedThroughputConfig selects ProvisionedThroughputConfig for ModelServiceConfig_DestinationConfig.TypeConfig. +type ModelServiceConfig_DestinationConfig_TypeConfig_ProvisionedThroughputConfig struct { + ProvisionedThroughputConfig ModelServiceConfig_ProvisionedThroughputConfig +} + +func (*ModelServiceConfig_DestinationConfig_TypeConfig_ProvisionedThroughputConfig) isModelServiceConfig_DestinationConfig_TypeConfig() { +} + +// ModelServiceConfig_DestinationConfig_TypeConfig_ExternalModelConfig selects ExternalModelConfig for ModelServiceConfig_DestinationConfig.TypeConfig. +type ModelServiceConfig_DestinationConfig_TypeConfig_ExternalModelConfig struct { + ExternalModelConfig ModelServiceConfig_ExternalModelConfig +} + +func (*ModelServiceConfig_DestinationConfig_TypeConfig_ExternalModelConfig) isModelServiceConfig_DestinationConfig_TypeConfig() { +} + +// Configuration for an external-foundation-model destination. Provider auth and +// provider-specific cloud configuration are owned by a separate, governed +// ModelProviderService entity referenced via `model_provider_service`; the +// platform resolves the provider at invocation time.. +type ModelServiceConfig_ExternalModelConfig struct { + // Resource name of the governed ModelProviderService that owns provider auth + // and provider-specific configuration. The referenced ModelProviderService also + // carries the provider type, so this message does not surface it directly. + // Format: + // `model-provider-services/{catalog}.{schema}.{model_provider_service}`. Each + // `{...}` component is capped at 255 characters individually. + ModelProviderService *string + // Routing target for the destination: the provider-side model selected from the + // referenced ModelProviderService's `targets` catalog, plus the unified API + // types the platform should translate to/from at request time. + Target *ModelProviderServiceConfig_ModelTargetConfig +} + +// Fallback routing, applied after the primary destination returns a retryable +// error. Traversal is in list order; the attempt count is the length of the +// list.. +type ModelServiceConfig_FallbackConfig struct { + // Ordered list of fallback destinations. Traversal is in list order; the + // attempt count is the length of the list. At most 5 are allowed. + Destinations []ModelServiceConfig_DestinationConfig `fieldmask:"destinations"` +} + +// Configuration for a pay-per-token foundation-model destination. Identifies +// the foundation model by its UC resource name; the platform resolves it to a +// Model Serving endpoint at request time.. +type ModelServiceConfig_PayPerTokenConfig struct { + // Resource name of the UC model. Format: `models/{catalog}.{schema}.{model}`. + Model *string +} + +// Configuration for a provisioned-throughput foundation-model destination. +// References a pre-existing Model Serving endpoint that serves the model; +// sizing (provisioned throughput, burst scaling, model version) is owned by the +// Model Serving endpoint itself, not by this message.. +type ModelServiceConfig_ProvisionedThroughputConfig struct { + // Name of the backing Model Serving endpoint serving the provisioned- + // throughput foundation model, as the AIP-122 typed resource name + // `serving-endpoints/{name}`. The same UC model can be served on multiple Model + // Serving endpoints (different throughput / region / config); the caller picks + // which one this destination routes to. The endpoint must exist at create time. + ModelServingEndpoint *string + // UC model FQN of the model served by the backing endpoint (e.g., + // `system.ai.databricks-claude-opus-4-6`). Resolved from Model Serving at + // Create/Update time. + Model *string +} + +// Routing configuration for a model service, nesting destinations, routing +// strategy, and fallback under a single sub-message.. +type ModelServiceConfig_RoutingConfig struct { + // Primary routing destinations. At most 10 are allowed. At least one is + // required on CreateModelService; on UpdateModelService it is required only + // when `config.routing` (or a `config.routing.*` subpath) appears in + // `update_mask`. + Destinations []ModelServiceConfig_DestinationConfig `fieldmask:"destinations"` + // Selects how requests are distributed across destinations. + RoutingStrategy isModelServiceConfig_RoutingConfig_RoutingStrategy + // Fallback routing config, applied after primary destinations fail. + Fallback *ModelServiceConfig_FallbackConfig `fieldmask:"fallback"` + // Timeout for the first token of a streaming response. If a destination does + // not return its first token within this duration, AI Gateway aborts the + // attempt and fails over to the next destination. Applies to streaming requests + // only. Leave unset for no first-token timeout. + FirstTokenTimeout *types.Duration `fieldmask:"first_token_timeout"` + _ [0]modelServiceConfig_RoutingConfigRoutingStrategyFieldMaskMetadata `fieldmask_oneof:"RoutingStrategy"` +} + +type isModelServiceConfig_RoutingConfig_RoutingStrategy interface { + isModelServiceConfig_RoutingConfig_RoutingStrategy() +} + +// ModelServiceConfig_RoutingConfig_RoutingStrategy_TrafficSplitting selects TrafficSplitting for ModelServiceConfig_RoutingConfig.RoutingStrategy. +// Marker message selecting request-based traffic splitting. Traffic is +// distributed according to each destination's traffic_percentage value; no +// configuration lives on this message itself. +type ModelServiceConfig_RoutingConfig_RoutingStrategy_TrafficSplitting struct { + TrafficSplitting ModelServiceConfig_RoutingConfig_TrafficSplitting `fieldmask:"traffic_splitting"` +} + +func (*ModelServiceConfig_RoutingConfig_RoutingStrategy_TrafficSplitting) isModelServiceConfig_RoutingConfig_RoutingStrategy() { +} + +type modelServiceConfig_RoutingConfigRoutingStrategyFieldMaskMetadata struct { + *ModelServiceConfig_RoutingConfig_RoutingStrategy_TrafficSplitting +} + +// Marker message selecting request-based traffic splitting across primary +// destinations. Split weights are read from each +// DestinationConfig.traffic_percentage.. +type ModelServiceConfig_RoutingConfig_TrafficSplitting struct { +} + +// A rate limit applied to service requests. Leave `requests` or `tokens` unset +// to impose no limit on that dimension; set a value to cap that dimension +// within the renewal period.. +type RateLimit struct { + // Scope key. Determines whether `principal` is required. + Key RateLimit_RateLimitKey + // Renewal period. + RenewalPeriod RateLimit_RateLimitRenewalPeriod + // Principal this limit applies to: user email, group name, or service principal + // application ID. Required unless `key` is `RATE_LIMIT_KEY_SERVICE`, + // `RATE_LIMIT_KEY_USER_DEFAULT`, or `RATE_LIMIT_KEY_REQUEST_TAG` (which must + // not set a principal). + Principal *string + // Max requests allowed within a renewal period. Leave unset for no request + // limit. + Requests *int64 + // Max tokens allowed within a renewal period. Leave unset for no token limit. + Tokens *int64 + // Request tag key this limit applies to. Required when `key` is + // `RATE_LIMIT_KEY_REQUEST_TAG`, forbidden otherwise. + RequestTagKey *string + // Request tag value this limit applies to. Only valid when `key` is + // `RATE_LIMIT_KEY_REQUEST_TAG`. Leave unset to apply the limit to every value + // of `request_tag_key` (an any-value default); a set value is a specific + // override for that value. + RequestTagValue *string +} + +// Request to update an MCP service. `name` cannot appear in `update_mask`.. +type UpdateMcpServiceRequest struct { + // The MCP service with the updated field values. `name` identifies the resource + // (`mcp-services/{catalog}.{schema}.{mcp_service}`); only fields listed in + // `update_mask` are applied. + McpService *McpService + // The list of fields to update. The framework validates each path against the + // `mcp_service` field above. Wildcard paths (`paths: ["*"]`) are not supported; + // list each field path explicitly. + UpdateMask *types.FieldMask[McpService] + // If-match precondition: when set, the update proceeds only if the current + // server-side etag matches. Empty means an unconditional update. + Etag []byte +} + +// Request to update a model provider service. `name` and `provider_type` cannot +// appear in `update_mask`.. +type UpdateModelProviderServiceRequest struct { + // The model provider service with the updated field values. `name` identifies + // the resource + // (`model-provider-services/{catalog}.{schema}.{model_provider_service}`); only + // fields listed in `update_mask` are applied. + ModelProviderService *ModelProviderService + // The list of fields to update. The framework validates each path against the + // `model_provider_service` field above. Wildcard paths (`paths: ["*"]`) are not + // supported; list each field path explicitly. + UpdateMask *types.FieldMask[ModelProviderService] + // If-match precondition: when set, the update proceeds only if the current + // server-side etag matches. Empty means an unconditional update. + Etag []byte +} + +// Request to update a model service. `name` cannot appear in `update_mask`; the +// model service name is immutable.. +type UpdateModelServiceRequest struct { + // The model service with the updated field values. `name` identifies the + // resource (`model-services/{catalog}.{schema}.{model_service}`); only fields + // listed in `update_mask` are applied. + ModelService *ModelService + // The list of fields to update. The framework validates each path against the + // `model_service` field above. Wildcard paths (`paths: ["*"]`) are not + // supported; list each field path explicitly. + UpdateMask *types.FieldMask[ModelService] + // If-match precondition: when set, the update proceeds only if the current + // server-side etag matches. Empty means an unconditional update. + Etag []byte +} diff --git a/aigateway/v1/wire.go b/aigateway/v1/wire.go new file mode 100755 index 0000000..d18cab0 --- /dev/null +++ b/aigateway/v1/wire.go @@ -0,0 +1,2321 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package aigateway + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createMcpServiceRequestWire struct { + Parent *string `json:"parent,omitempty"` + McpServiceId *string `json:"mcp_service_id,omitempty"` + McpService *mcpServiceWire `json:"mcp_service,omitempty"` +} + +func createMcpServiceRequestToWire(v *CreateMcpServiceRequest) (*createMcpServiceRequestWire, error) { + if v == nil { + return nil, nil + } + mcpServiceWireValue, err := mcpServiceToWire(v.McpService) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateMcpServiceRequest.McpService", err) + } + return &createMcpServiceRequestWire{ + Parent: v.Parent, + McpServiceId: v.McpServiceId, + McpService: mcpServiceWireValue, + }, nil +} + +type createModelProviderServiceRequestWire struct { + Parent *string `json:"parent,omitempty"` + ModelProviderServiceId *string `json:"model_provider_service_id,omitempty"` + ModelProviderService *modelProviderServiceWire `json:"model_provider_service,omitempty"` +} + +func createModelProviderServiceRequestToWire(v *CreateModelProviderServiceRequest) (*createModelProviderServiceRequestWire, error) { + if v == nil { + return nil, nil + } + modelProviderServiceWireValue, err := modelProviderServiceToWire(v.ModelProviderService) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateModelProviderServiceRequest.ModelProviderService", err) + } + return &createModelProviderServiceRequestWire{ + Parent: v.Parent, + ModelProviderServiceId: v.ModelProviderServiceId, + ModelProviderService: modelProviderServiceWireValue, + }, nil +} + +type createModelServiceRequestWire struct { + Parent *string `json:"parent,omitempty"` + ModelServiceId *string `json:"model_service_id,omitempty"` + ModelService *modelServiceWire `json:"model_service,omitempty"` +} + +func createModelServiceRequestToWire(v *CreateModelServiceRequest) (*createModelServiceRequestWire, error) { + if v == nil { + return nil, nil + } + modelServiceWireValue, err := modelServiceToWire(v.ModelService) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateModelServiceRequest.ModelService", err) + } + return &createModelServiceRequestWire{ + Parent: v.Parent, + ModelServiceId: v.ModelServiceId, + ModelService: modelServiceWireValue, + }, nil +} + +type deleteMcpServiceRequestWire struct { + Name *string `json:"name,omitempty"` + Etag []byte `json:"etag,omitempty"` +} + +func deleteMcpServiceRequestToWire(v *DeleteMcpServiceRequest) (*deleteMcpServiceRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteMcpServiceRequestWire{ + Name: v.Name, + Etag: v.Etag, + }, nil +} + +type deleteModelProviderServiceRequestWire struct { + Name *string `json:"name,omitempty"` + Etag []byte `json:"etag,omitempty"` +} + +func deleteModelProviderServiceRequestToWire(v *DeleteModelProviderServiceRequest) (*deleteModelProviderServiceRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteModelProviderServiceRequestWire{ + Name: v.Name, + Etag: v.Etag, + }, nil +} + +type deleteModelServiceRequestWire struct { + Name *string `json:"name,omitempty"` + Etag []byte `json:"etag,omitempty"` +} + +func deleteModelServiceRequestToWire(v *DeleteModelServiceRequest) (*deleteModelServiceRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteModelServiceRequestWire{ + Name: v.Name, + Etag: v.Etag, + }, nil +} + +type inferenceTableConfigWire struct { + Parent *string `json:"parent,omitempty"` + TableNamePrefix *string `json:"table_name_prefix,omitempty"` + Disabled *bool `json:"disabled,omitempty"` + Table *string `json:"table,omitempty"` + IsDeleted *bool `json:"is_deleted,omitempty"` +} + +func inferenceTableConfigToWire(v *InferenceTableConfig) (*inferenceTableConfigWire, error) { + if v == nil { + return nil, nil + } + return &inferenceTableConfigWire{ + Parent: v.Parent, + TableNamePrefix: v.TableNamePrefix, + Disabled: v.Disabled, + Table: v.Table, + IsDeleted: v.IsDeleted, + }, nil +} + +func inferenceTableConfigFromWire(w *inferenceTableConfigWire) (*InferenceTableConfig, error) { + if w == nil { + return nil, nil + } + return &InferenceTableConfig{ + Parent: w.Parent, + TableNamePrefix: w.TableNamePrefix, + Disabled: w.Disabled, + Table: w.Table, + IsDeleted: w.IsDeleted, + }, nil +} + +type listMcpServicesRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` + View ListMcpServicesRequest_View `json:"view,omitempty"` +} + +func listMcpServicesRequestToWire(v *ListMcpServicesRequest) (*listMcpServicesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listMcpServicesRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + View: v.View, + }, nil +} + +type listMcpServicesResponseWire struct { + McpServices []mcpServiceWire `json:"mcp_services,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listMcpServicesResponseFromWire(w *listMcpServicesResponseWire) (*ListMcpServicesResponse, error) { + if w == nil { + return nil, nil + } + mcpServicesPublicValue, err := convertSlice(w.McpServices, mcpServiceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListMcpServicesResponse.McpServices", err) + } + return &ListMcpServicesResponse{ + McpServices: mcpServicesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listModelProviderServicesRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` + View ListModelProviderServicesRequest_View `json:"view,omitempty"` +} + +func listModelProviderServicesRequestToWire(v *ListModelProviderServicesRequest) (*listModelProviderServicesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listModelProviderServicesRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + View: v.View, + }, nil +} + +type listModelProviderServicesResponseWire struct { + ModelProviderServices []modelProviderServiceWire `json:"model_provider_services,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listModelProviderServicesResponseFromWire(w *listModelProviderServicesResponseWire) (*ListModelProviderServicesResponse, error) { + if w == nil { + return nil, nil + } + modelProviderServicesPublicValue, err := convertSlice(w.ModelProviderServices, modelProviderServiceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListModelProviderServicesResponse.ModelProviderServices", err) + } + return &ListModelProviderServicesResponse{ + ModelProviderServices: modelProviderServicesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listModelServicesRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` + View ListModelServicesRequest_View `json:"view,omitempty"` +} + +func listModelServicesRequestToWire(v *ListModelServicesRequest) (*listModelServicesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listModelServicesRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + View: v.View, + }, nil +} + +type listModelServicesResponseWire struct { + ModelServices []modelServiceWire `json:"model_services,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listModelServicesResponseFromWire(w *listModelServicesResponseWire) (*ListModelServicesResponse, error) { + if w == nil { + return nil, nil + } + modelServicesPublicValue, err := convertSlice(w.ModelServices, modelServiceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListModelServicesResponse.ModelServices", err) + } + return &ListModelServicesResponse{ + ModelServices: modelServicesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type mcpServiceWire struct { + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + EffectiveOwner *string `json:"effective_owner,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Comment *string `json:"comment,omitempty"` + Config *mcpServiceConfigWire `json:"config,omitempty"` + Etag []byte `json:"etag,omitempty"` +} + +func mcpServiceToWire(v *McpService) (*mcpServiceWire, error) { + if v == nil { + return nil, nil + } + configWireValue, err := mcpServiceConfigToWire(v.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "McpService.Config", err) + } + return &mcpServiceWire{ + Name: v.Name, + Owner: v.Owner, + EffectiveOwner: v.EffectiveOwner, + MetastoreId: v.MetastoreId, + CreateTime: v.CreateTime, + CreatedBy: v.CreatedBy, + UpdateTime: v.UpdateTime, + UpdatedBy: v.UpdatedBy, + Comment: v.Comment, + Config: configWireValue, + Etag: v.Etag, + }, nil +} + +func mcpServiceFromWire(w *mcpServiceWire) (*McpService, error) { + if w == nil { + return nil, nil + } + configPublicValue, err := mcpServiceConfigFromWire(w.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "McpService.Config", err) + } + return &McpService{ + Name: w.Name, + Owner: w.Owner, + EffectiveOwner: w.EffectiveOwner, + MetastoreId: w.MetastoreId, + CreateTime: w.CreateTime, + CreatedBy: w.CreatedBy, + UpdateTime: w.UpdateTime, + UpdatedBy: w.UpdatedBy, + Comment: w.Comment, + Config: configPublicValue, + Etag: w.Etag, + }, nil +} + +type mcpServiceConfigWire struct { + SourceConnection *mcpServiceConfig_SourceConnectionWire `json:"source_connection,omitempty"` + IncludeToolSelectors []string `json:"include_tool_selectors,omitempty"` + RateLimits []rateLimitWire `json:"rate_limits,omitempty"` +} + +func mcpServiceConfigToWire(v *McpServiceConfig) (*mcpServiceConfigWire, error) { + if v == nil { + return nil, nil + } + rateLimitsWireValue, err := convertSlice(v.RateLimits, rateLimitToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "McpServiceConfig.RateLimits", err) + } + var sourceSourceConnectionWire *mcpServiceConfig_SourceConnectionWire + switch value := v.Source.(type) { + case nil: + case *McpServiceConfig_Source_SourceConnection: + if value != nil { + sourceSourceConnectionConverted, err := mcpServiceConfig_SourceConnectionToWire(&value.SourceConnection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "McpServiceConfig.Source.SourceConnection", err) + } + sourceSourceConnectionWire = sourceSourceConnectionConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "McpServiceConfig.Source", value) + } + return &mcpServiceConfigWire{ + SourceConnection: sourceSourceConnectionWire, + IncludeToolSelectors: v.IncludeToolSelectors, + RateLimits: rateLimitsWireValue, + }, nil +} + +func mcpServiceConfigFromWire(w *mcpServiceConfigWire) (*McpServiceConfig, error) { + if w == nil { + return nil, nil + } + sourceMembers := 0 + if w.SourceConnection != nil { + sourceMembers++ + } + if sourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "McpServiceConfig.Source") + } + rateLimitsPublicValue, err := convertSlice(w.RateLimits, rateLimitFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "McpServiceConfig.RateLimits", err) + } + var sourceSelection isMcpServiceConfig_Source + switch { + case w.SourceConnection != nil: + sourceSourceConnectionConverted, err := mcpServiceConfig_SourceConnectionFromWire(w.SourceConnection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "McpServiceConfig.Source.SourceConnection", err) + } + sourceSelection = &McpServiceConfig_Source_SourceConnection{SourceConnection: *sourceSourceConnectionConverted} + } + return &McpServiceConfig{ + IncludeToolSelectors: w.IncludeToolSelectors, + RateLimits: rateLimitsPublicValue, + Source: sourceSelection, + }, nil +} + +type mcpServiceConfig_SourceConnectionWire struct { + Name *string `json:"name,omitempty"` + IsDeleted *bool `json:"is_deleted,omitempty"` +} + +func mcpServiceConfig_SourceConnectionToWire(v *McpServiceConfig_SourceConnection) (*mcpServiceConfig_SourceConnectionWire, error) { + if v == nil { + return nil, nil + } + return &mcpServiceConfig_SourceConnectionWire{ + Name: v.Name, + IsDeleted: v.IsDeleted, + }, nil +} + +func mcpServiceConfig_SourceConnectionFromWire(w *mcpServiceConfig_SourceConnectionWire) (*McpServiceConfig_SourceConnection, error) { + if w == nil { + return nil, nil + } + return &McpServiceConfig_SourceConnection{ + Name: w.Name, + IsDeleted: w.IsDeleted, + }, nil +} + +type modelProviderServiceWire struct { + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + EffectiveOwner *string `json:"effective_owner,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Comment *string `json:"comment,omitempty"` + Etag []byte `json:"etag,omitempty"` + Config *modelProviderServiceConfigWire `json:"config,omitempty"` +} + +func modelProviderServiceToWire(v *ModelProviderService) (*modelProviderServiceWire, error) { + if v == nil { + return nil, nil + } + configWireValue, err := modelProviderServiceConfigToWire(v.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderService.Config", err) + } + return &modelProviderServiceWire{ + Name: v.Name, + Owner: v.Owner, + EffectiveOwner: v.EffectiveOwner, + MetastoreId: v.MetastoreId, + CreateTime: v.CreateTime, + CreatedBy: v.CreatedBy, + UpdateTime: v.UpdateTime, + UpdatedBy: v.UpdatedBy, + Comment: v.Comment, + Etag: v.Etag, + Config: configWireValue, + }, nil +} + +func modelProviderServiceFromWire(w *modelProviderServiceWire) (*ModelProviderService, error) { + if w == nil { + return nil, nil + } + configPublicValue, err := modelProviderServiceConfigFromWire(w.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderService.Config", err) + } + return &ModelProviderService{ + Name: w.Name, + Owner: w.Owner, + EffectiveOwner: w.EffectiveOwner, + MetastoreId: w.MetastoreId, + CreateTime: w.CreateTime, + CreatedBy: w.CreatedBy, + UpdateTime: w.UpdateTime, + UpdatedBy: w.UpdatedBy, + Comment: w.Comment, + Etag: w.Etag, + Config: configPublicValue, + }, nil +} + +type modelProviderServiceConfigWire struct { + ProviderType ModelProviderServiceConfig_ExternalModelProviderType `json:"provider_type,omitempty"` + Openai *modelProviderServiceConfig_OpenAiProviderConfigWire `json:"openai,omitempty"` + AzureOpenai *modelProviderServiceConfig_AzureOpenAiProviderConfigWire `json:"azure_openai,omitempty"` + Anthropic *modelProviderServiceConfig_AnthropicProviderConfigWire `json:"anthropic,omitempty"` + AmazonBedrock *modelProviderServiceConfig_AmazonBedrockProviderConfigWire `json:"amazon_bedrock,omitempty"` + Custom *modelProviderServiceConfig_CustomProviderConfigWire `json:"custom,omitempty"` + MicrosoftFoundry *modelProviderServiceConfig_MicrosoftFoundryProviderConfigWire `json:"microsoft_foundry,omitempty"` + GeminiEnterprise *modelProviderServiceConfig_GeminiEnterpriseProviderConfigWire `json:"gemini_enterprise,omitempty"` + AllowAllTargets *bool `json:"allow_all_targets,omitempty"` + Targets []modelProviderServiceConfig_ModelTargetConfigWire `json:"targets,omitempty"` + ForwardHeaders *bool `json:"forward_headers,omitempty"` + ForwardQueryParameters *bool `json:"forward_query_parameters,omitempty"` + ForwardUnmanagedPaths *bool `json:"forward_unmanaged_paths,omitempty"` + RateLimits []rateLimitWire `json:"rate_limits,omitempty"` + InferenceTable *inferenceTableConfigWire `json:"inference_table,omitempty"` +} + +func modelProviderServiceConfigToWire(v *ModelProviderServiceConfig) (*modelProviderServiceConfigWire, error) { + if v == nil { + return nil, nil + } + targetsWireValue, err := convertSlice(v.Targets, modelProviderServiceConfig_ModelTargetConfigToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Targets", err) + } + rateLimitsWireValue, err := convertSlice(v.RateLimits, rateLimitToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.RateLimits", err) + } + inferenceTableWireValue, err := inferenceTableConfigToWire(v.InferenceTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.InferenceTable", err) + } + var providerOpenaiWire *modelProviderServiceConfig_OpenAiProviderConfigWire + var providerAzureOpenaiWire *modelProviderServiceConfig_AzureOpenAiProviderConfigWire + var providerAnthropicWire *modelProviderServiceConfig_AnthropicProviderConfigWire + var providerAmazonBedrockWire *modelProviderServiceConfig_AmazonBedrockProviderConfigWire + var providerCustomWire *modelProviderServiceConfig_CustomProviderConfigWire + var providerMicrosoftFoundryWire *modelProviderServiceConfig_MicrosoftFoundryProviderConfigWire + var providerGeminiEnterpriseWire *modelProviderServiceConfig_GeminiEnterpriseProviderConfigWire + switch value := v.Provider.(type) { + case nil: + case *ModelProviderServiceConfig_Provider_Openai: + if value != nil { + providerOpenaiConverted, err := modelProviderServiceConfig_OpenAiProviderConfigToWire(&value.Openai) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.Openai", err) + } + providerOpenaiWire = providerOpenaiConverted + } + case *ModelProviderServiceConfig_Provider_AzureOpenai: + if value != nil { + providerAzureOpenaiConverted, err := modelProviderServiceConfig_AzureOpenAiProviderConfigToWire(&value.AzureOpenai) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.AzureOpenai", err) + } + providerAzureOpenaiWire = providerAzureOpenaiConverted + } + case *ModelProviderServiceConfig_Provider_Anthropic: + if value != nil { + providerAnthropicConverted, err := modelProviderServiceConfig_AnthropicProviderConfigToWire(&value.Anthropic) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.Anthropic", err) + } + providerAnthropicWire = providerAnthropicConverted + } + case *ModelProviderServiceConfig_Provider_AmazonBedrock: + if value != nil { + providerAmazonBedrockConverted, err := modelProviderServiceConfig_AmazonBedrockProviderConfigToWire(&value.AmazonBedrock) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.AmazonBedrock", err) + } + providerAmazonBedrockWire = providerAmazonBedrockConverted + } + case *ModelProviderServiceConfig_Provider_Custom: + if value != nil { + providerCustomConverted, err := modelProviderServiceConfig_CustomProviderConfigToWire(&value.Custom) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.Custom", err) + } + providerCustomWire = providerCustomConverted + } + case *ModelProviderServiceConfig_Provider_MicrosoftFoundry: + if value != nil { + providerMicrosoftFoundryConverted, err := modelProviderServiceConfig_MicrosoftFoundryProviderConfigToWire(&value.MicrosoftFoundry) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.MicrosoftFoundry", err) + } + providerMicrosoftFoundryWire = providerMicrosoftFoundryConverted + } + case *ModelProviderServiceConfig_Provider_GeminiEnterprise: + if value != nil { + providerGeminiEnterpriseConverted, err := modelProviderServiceConfig_GeminiEnterpriseProviderConfigToWire(&value.GeminiEnterprise) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.GeminiEnterprise", err) + } + providerGeminiEnterpriseWire = providerGeminiEnterpriseConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig.Provider", value) + } + return &modelProviderServiceConfigWire{ + ProviderType: v.ProviderType, + Openai: providerOpenaiWire, + AzureOpenai: providerAzureOpenaiWire, + Anthropic: providerAnthropicWire, + AmazonBedrock: providerAmazonBedrockWire, + Custom: providerCustomWire, + MicrosoftFoundry: providerMicrosoftFoundryWire, + GeminiEnterprise: providerGeminiEnterpriseWire, + AllowAllTargets: v.AllowAllTargets, + Targets: targetsWireValue, + ForwardHeaders: v.ForwardHeaders, + ForwardQueryParameters: v.ForwardQueryParameters, + ForwardUnmanagedPaths: v.ForwardUnmanagedPaths, + RateLimits: rateLimitsWireValue, + InferenceTable: inferenceTableWireValue, + }, nil +} + +func modelProviderServiceConfigFromWire(w *modelProviderServiceConfigWire) (*ModelProviderServiceConfig, error) { + if w == nil { + return nil, nil + } + providerMembers := 0 + if w.Openai != nil { + providerMembers++ + } + if w.AzureOpenai != nil { + providerMembers++ + } + if w.Anthropic != nil { + providerMembers++ + } + if w.AmazonBedrock != nil { + providerMembers++ + } + if w.Custom != nil { + providerMembers++ + } + if w.MicrosoftFoundry != nil { + providerMembers++ + } + if w.GeminiEnterprise != nil { + providerMembers++ + } + if providerMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig.Provider") + } + targetsPublicValue, err := convertSlice(w.Targets, modelProviderServiceConfig_ModelTargetConfigFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Targets", err) + } + rateLimitsPublicValue, err := convertSlice(w.RateLimits, rateLimitFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.RateLimits", err) + } + inferenceTablePublicValue, err := inferenceTableConfigFromWire(w.InferenceTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.InferenceTable", err) + } + var providerSelection isModelProviderServiceConfig_Provider + switch { + case w.Openai != nil: + providerOpenaiConverted, err := modelProviderServiceConfig_OpenAiProviderConfigFromWire(w.Openai) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.Openai", err) + } + providerSelection = &ModelProviderServiceConfig_Provider_Openai{Openai: *providerOpenaiConverted} + case w.AzureOpenai != nil: + providerAzureOpenaiConverted, err := modelProviderServiceConfig_AzureOpenAiProviderConfigFromWire(w.AzureOpenai) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.AzureOpenai", err) + } + providerSelection = &ModelProviderServiceConfig_Provider_AzureOpenai{AzureOpenai: *providerAzureOpenaiConverted} + case w.Anthropic != nil: + providerAnthropicConverted, err := modelProviderServiceConfig_AnthropicProviderConfigFromWire(w.Anthropic) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.Anthropic", err) + } + providerSelection = &ModelProviderServiceConfig_Provider_Anthropic{Anthropic: *providerAnthropicConverted} + case w.AmazonBedrock != nil: + providerAmazonBedrockConverted, err := modelProviderServiceConfig_AmazonBedrockProviderConfigFromWire(w.AmazonBedrock) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.AmazonBedrock", err) + } + providerSelection = &ModelProviderServiceConfig_Provider_AmazonBedrock{AmazonBedrock: *providerAmazonBedrockConverted} + case w.Custom != nil: + providerCustomConverted, err := modelProviderServiceConfig_CustomProviderConfigFromWire(w.Custom) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.Custom", err) + } + providerSelection = &ModelProviderServiceConfig_Provider_Custom{Custom: *providerCustomConverted} + case w.MicrosoftFoundry != nil: + providerMicrosoftFoundryConverted, err := modelProviderServiceConfig_MicrosoftFoundryProviderConfigFromWire(w.MicrosoftFoundry) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.MicrosoftFoundry", err) + } + providerSelection = &ModelProviderServiceConfig_Provider_MicrosoftFoundry{MicrosoftFoundry: *providerMicrosoftFoundryConverted} + case w.GeminiEnterprise != nil: + providerGeminiEnterpriseConverted, err := modelProviderServiceConfig_GeminiEnterpriseProviderConfigFromWire(w.GeminiEnterprise) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig.Provider.GeminiEnterprise", err) + } + providerSelection = &ModelProviderServiceConfig_Provider_GeminiEnterprise{GeminiEnterprise: *providerGeminiEnterpriseConverted} + } + return &ModelProviderServiceConfig{ + ProviderType: w.ProviderType, + AllowAllTargets: w.AllowAllTargets, + Targets: targetsPublicValue, + ForwardHeaders: w.ForwardHeaders, + ForwardQueryParameters: w.ForwardQueryParameters, + ForwardUnmanagedPaths: w.ForwardUnmanagedPaths, + RateLimits: rateLimitsPublicValue, + InferenceTable: inferenceTablePublicValue, + Provider: providerSelection, + }, nil +} + +type modelProviderServiceConfig_AmazonBedrockProviderConfigWire struct { + Direct *modelProviderServiceConfig_AmazonBedrockProviderDirectConfigWire `json:"direct,omitempty"` +} + +func modelProviderServiceConfig_AmazonBedrockProviderConfigToWire(v *ModelProviderServiceConfig_AmazonBedrockProviderConfig) (*modelProviderServiceConfig_AmazonBedrockProviderConfigWire, error) { + if v == nil { + return nil, nil + } + var providerModeDirectWire *modelProviderServiceConfig_AmazonBedrockProviderDirectConfigWire + switch value := v.ProviderMode.(type) { + case nil: + case *ModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode_Direct: + if value != nil { + providerModeDirectConverted, err := modelProviderServiceConfig_AmazonBedrockProviderDirectConfigToWire(&value.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AmazonBedrockProviderConfig.ProviderMode.Direct", err) + } + providerModeDirectWire = providerModeDirectConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_AmazonBedrockProviderConfig.ProviderMode", value) + } + return &modelProviderServiceConfig_AmazonBedrockProviderConfigWire{ + Direct: providerModeDirectWire, + }, nil +} + +func modelProviderServiceConfig_AmazonBedrockProviderConfigFromWire(w *modelProviderServiceConfig_AmazonBedrockProviderConfigWire) (*ModelProviderServiceConfig_AmazonBedrockProviderConfig, error) { + if w == nil { + return nil, nil + } + providerModeMembers := 0 + if w.Direct != nil { + providerModeMembers++ + } + if providerModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_AmazonBedrockProviderConfig.ProviderMode") + } + var providerModeSelection isModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode + switch { + case w.Direct != nil: + providerModeDirectConverted, err := modelProviderServiceConfig_AmazonBedrockProviderDirectConfigFromWire(w.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AmazonBedrockProviderConfig.ProviderMode.Direct", err) + } + providerModeSelection = &ModelProviderServiceConfig_AmazonBedrockProviderConfig_ProviderMode_Direct{Direct: *providerModeDirectConverted} + } + return &ModelProviderServiceConfig_AmazonBedrockProviderConfig{ + ProviderMode: providerModeSelection, + }, nil +} + +type modelProviderServiceConfig_AmazonBedrockProviderDirectConfigWire struct { + Region *string `json:"region,omitempty"` + ServiceCredential *modelProviderServiceConfig_ServiceCredentialWire `json:"service_credential,omitempty"` + AwsAccessKey *modelProviderServiceConfig_AwsAccessKeyWire `json:"aws_access_key,omitempty"` +} + +func modelProviderServiceConfig_AmazonBedrockProviderDirectConfigToWire(v *ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig) (*modelProviderServiceConfig_AmazonBedrockProviderDirectConfigWire, error) { + if v == nil { + return nil, nil + } + var authModeServiceCredentialWire *modelProviderServiceConfig_ServiceCredentialWire + var authModeAwsAccessKeyWire *modelProviderServiceConfig_AwsAccessKeyWire + switch value := v.AuthMode.(type) { + case nil: + case *ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_ServiceCredential: + if value != nil { + authModeServiceCredentialConverted, err := modelProviderServiceConfig_ServiceCredentialToWire(&value.ServiceCredential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig.AuthMode.ServiceCredential", err) + } + authModeServiceCredentialWire = authModeServiceCredentialConverted + } + case *ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_AwsAccessKey: + if value != nil { + authModeAwsAccessKeyConverted, err := modelProviderServiceConfig_AwsAccessKeyToWire(&value.AwsAccessKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig.AuthMode.AwsAccessKey", err) + } + authModeAwsAccessKeyWire = authModeAwsAccessKeyConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig.AuthMode", value) + } + return &modelProviderServiceConfig_AmazonBedrockProviderDirectConfigWire{ + Region: v.Region, + ServiceCredential: authModeServiceCredentialWire, + AwsAccessKey: authModeAwsAccessKeyWire, + }, nil +} + +func modelProviderServiceConfig_AmazonBedrockProviderDirectConfigFromWire(w *modelProviderServiceConfig_AmazonBedrockProviderDirectConfigWire) (*ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig, error) { + if w == nil { + return nil, nil + } + authModeMembers := 0 + if w.ServiceCredential != nil { + authModeMembers++ + } + if w.AwsAccessKey != nil { + authModeMembers++ + } + if authModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig.AuthMode") + } + var authModeSelection isModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode + switch { + case w.ServiceCredential != nil: + authModeServiceCredentialConverted, err := modelProviderServiceConfig_ServiceCredentialFromWire(w.ServiceCredential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig.AuthMode.ServiceCredential", err) + } + authModeSelection = &ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_ServiceCredential{ServiceCredential: *authModeServiceCredentialConverted} + case w.AwsAccessKey != nil: + authModeAwsAccessKeyConverted, err := modelProviderServiceConfig_AwsAccessKeyFromWire(w.AwsAccessKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig.AuthMode.AwsAccessKey", err) + } + authModeSelection = &ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig_AuthMode_AwsAccessKey{AwsAccessKey: *authModeAwsAccessKeyConverted} + } + return &ModelProviderServiceConfig_AmazonBedrockProviderDirectConfig{ + Region: w.Region, + AuthMode: authModeSelection, + }, nil +} + +type modelProviderServiceConfig_AnthropicProviderConfigWire struct { + Direct *modelProviderServiceConfig_AnthropicProviderDirectConfigWire `json:"direct,omitempty"` + Relayed *modelProviderServiceConfig_AnthropicProviderRelayedConfigWire `json:"relayed,omitempty"` +} + +func modelProviderServiceConfig_AnthropicProviderConfigToWire(v *ModelProviderServiceConfig_AnthropicProviderConfig) (*modelProviderServiceConfig_AnthropicProviderConfigWire, error) { + if v == nil { + return nil, nil + } + var providerModeDirectWire *modelProviderServiceConfig_AnthropicProviderDirectConfigWire + var providerModeRelayedWire *modelProviderServiceConfig_AnthropicProviderRelayedConfigWire + switch value := v.ProviderMode.(type) { + case nil: + case *ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Direct: + if value != nil { + providerModeDirectConverted, err := modelProviderServiceConfig_AnthropicProviderDirectConfigToWire(&value.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AnthropicProviderConfig.ProviderMode.Direct", err) + } + providerModeDirectWire = providerModeDirectConverted + } + case *ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Relayed: + if value != nil { + providerModeRelayedConverted, err := modelProviderServiceConfig_AnthropicProviderRelayedConfigToWire(&value.Relayed) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AnthropicProviderConfig.ProviderMode.Relayed", err) + } + providerModeRelayedWire = providerModeRelayedConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_AnthropicProviderConfig.ProviderMode", value) + } + return &modelProviderServiceConfig_AnthropicProviderConfigWire{ + Direct: providerModeDirectWire, + Relayed: providerModeRelayedWire, + }, nil +} + +func modelProviderServiceConfig_AnthropicProviderConfigFromWire(w *modelProviderServiceConfig_AnthropicProviderConfigWire) (*ModelProviderServiceConfig_AnthropicProviderConfig, error) { + if w == nil { + return nil, nil + } + providerModeMembers := 0 + if w.Direct != nil { + providerModeMembers++ + } + if w.Relayed != nil { + providerModeMembers++ + } + if providerModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_AnthropicProviderConfig.ProviderMode") + } + var providerModeSelection isModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode + switch { + case w.Direct != nil: + providerModeDirectConverted, err := modelProviderServiceConfig_AnthropicProviderDirectConfigFromWire(w.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AnthropicProviderConfig.ProviderMode.Direct", err) + } + providerModeSelection = &ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Direct{Direct: *providerModeDirectConverted} + case w.Relayed != nil: + providerModeRelayedConverted, err := modelProviderServiceConfig_AnthropicProviderRelayedConfigFromWire(w.Relayed) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AnthropicProviderConfig.ProviderMode.Relayed", err) + } + providerModeSelection = &ModelProviderServiceConfig_AnthropicProviderConfig_ProviderMode_Relayed{Relayed: *providerModeRelayedConverted} + } + return &ModelProviderServiceConfig_AnthropicProviderConfig{ + ProviderMode: providerModeSelection, + }, nil +} + +type modelProviderServiceConfig_AnthropicProviderDirectConfigWire struct { + ApiKey *modelProviderServiceConfig_ProviderSecretWire `json:"api_key,omitempty"` +} + +func modelProviderServiceConfig_AnthropicProviderDirectConfigToWire(v *ModelProviderServiceConfig_AnthropicProviderDirectConfig) (*modelProviderServiceConfig_AnthropicProviderDirectConfigWire, error) { + if v == nil { + return nil, nil + } + var authModeApiKeyWire *modelProviderServiceConfig_ProviderSecretWire + switch value := v.AuthMode.(type) { + case nil: + case *ModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode_ApiKey: + if value != nil { + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretToWire(&value.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AnthropicProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeApiKeyWire = authModeApiKeyConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_AnthropicProviderDirectConfig.AuthMode", value) + } + return &modelProviderServiceConfig_AnthropicProviderDirectConfigWire{ + ApiKey: authModeApiKeyWire, + }, nil +} + +func modelProviderServiceConfig_AnthropicProviderDirectConfigFromWire(w *modelProviderServiceConfig_AnthropicProviderDirectConfigWire) (*ModelProviderServiceConfig_AnthropicProviderDirectConfig, error) { + if w == nil { + return nil, nil + } + authModeMembers := 0 + if w.ApiKey != nil { + authModeMembers++ + } + if authModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_AnthropicProviderDirectConfig.AuthMode") + } + var authModeSelection isModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode + switch { + case w.ApiKey != nil: + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretFromWire(w.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AnthropicProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeSelection = &ModelProviderServiceConfig_AnthropicProviderDirectConfig_AuthMode_ApiKey{ApiKey: *authModeApiKeyConverted} + } + return &ModelProviderServiceConfig_AnthropicProviderDirectConfig{ + AuthMode: authModeSelection, + }, nil +} + +type modelProviderServiceConfig_AnthropicProviderRelayedConfigWire struct { + PlanType ModelProviderServiceConfig_AnthropicProviderRelayedConfig_AnthropicRelayedPlanType `json:"plan_type,omitempty"` +} + +func modelProviderServiceConfig_AnthropicProviderRelayedConfigToWire(v *ModelProviderServiceConfig_AnthropicProviderRelayedConfig) (*modelProviderServiceConfig_AnthropicProviderRelayedConfigWire, error) { + if v == nil { + return nil, nil + } + return &modelProviderServiceConfig_AnthropicProviderRelayedConfigWire{ + PlanType: v.PlanType, + }, nil +} + +func modelProviderServiceConfig_AnthropicProviderRelayedConfigFromWire(w *modelProviderServiceConfig_AnthropicProviderRelayedConfigWire) (*ModelProviderServiceConfig_AnthropicProviderRelayedConfig, error) { + if w == nil { + return nil, nil + } + return &ModelProviderServiceConfig_AnthropicProviderRelayedConfig{ + PlanType: w.PlanType, + }, nil +} + +type modelProviderServiceConfig_AwsAccessKeyWire struct { + AccessKeyId *string `json:"access_key_id,omitempty"` + SecretAccessKey *modelProviderServiceConfig_ProviderSecretWire `json:"secret_access_key,omitempty"` +} + +func modelProviderServiceConfig_AwsAccessKeyToWire(v *ModelProviderServiceConfig_AwsAccessKey) (*modelProviderServiceConfig_AwsAccessKeyWire, error) { + if v == nil { + return nil, nil + } + secretAccessKeyWireValue, err := modelProviderServiceConfig_ProviderSecretToWire(v.SecretAccessKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AwsAccessKey.SecretAccessKey", err) + } + return &modelProviderServiceConfig_AwsAccessKeyWire{ + AccessKeyId: v.AccessKeyId, + SecretAccessKey: secretAccessKeyWireValue, + }, nil +} + +func modelProviderServiceConfig_AwsAccessKeyFromWire(w *modelProviderServiceConfig_AwsAccessKeyWire) (*ModelProviderServiceConfig_AwsAccessKey, error) { + if w == nil { + return nil, nil + } + secretAccessKeyPublicValue, err := modelProviderServiceConfig_ProviderSecretFromWire(w.SecretAccessKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AwsAccessKey.SecretAccessKey", err) + } + return &ModelProviderServiceConfig_AwsAccessKey{ + AccessKeyId: w.AccessKeyId, + SecretAccessKey: secretAccessKeyPublicValue, + }, nil +} + +type modelProviderServiceConfig_AzureOpenAiProviderConfigWire struct { + Direct *modelProviderServiceConfig_AzureOpenAiProviderDirectConfigWire `json:"direct,omitempty"` +} + +func modelProviderServiceConfig_AzureOpenAiProviderConfigToWire(v *ModelProviderServiceConfig_AzureOpenAiProviderConfig) (*modelProviderServiceConfig_AzureOpenAiProviderConfigWire, error) { + if v == nil { + return nil, nil + } + var providerModeDirectWire *modelProviderServiceConfig_AzureOpenAiProviderDirectConfigWire + switch value := v.ProviderMode.(type) { + case nil: + case *ModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode_Direct: + if value != nil { + providerModeDirectConverted, err := modelProviderServiceConfig_AzureOpenAiProviderDirectConfigToWire(&value.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AzureOpenAiProviderConfig.ProviderMode.Direct", err) + } + providerModeDirectWire = providerModeDirectConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_AzureOpenAiProviderConfig.ProviderMode", value) + } + return &modelProviderServiceConfig_AzureOpenAiProviderConfigWire{ + Direct: providerModeDirectWire, + }, nil +} + +func modelProviderServiceConfig_AzureOpenAiProviderConfigFromWire(w *modelProviderServiceConfig_AzureOpenAiProviderConfigWire) (*ModelProviderServiceConfig_AzureOpenAiProviderConfig, error) { + if w == nil { + return nil, nil + } + providerModeMembers := 0 + if w.Direct != nil { + providerModeMembers++ + } + if providerModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_AzureOpenAiProviderConfig.ProviderMode") + } + var providerModeSelection isModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode + switch { + case w.Direct != nil: + providerModeDirectConverted, err := modelProviderServiceConfig_AzureOpenAiProviderDirectConfigFromWire(w.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AzureOpenAiProviderConfig.ProviderMode.Direct", err) + } + providerModeSelection = &ModelProviderServiceConfig_AzureOpenAiProviderConfig_ProviderMode_Direct{Direct: *providerModeDirectConverted} + } + return &ModelProviderServiceConfig_AzureOpenAiProviderConfig{ + ProviderMode: providerModeSelection, + }, nil +} + +type modelProviderServiceConfig_AzureOpenAiProviderDirectConfigWire struct { + BaseUrl *string `json:"base_url,omitempty"` + ApiKey *modelProviderServiceConfig_ProviderSecretWire `json:"api_key,omitempty"` + ServiceCredential *modelProviderServiceConfig_ServiceCredentialWire `json:"service_credential,omitempty"` + EntraServicePrincipal *modelProviderServiceConfig_EntraServicePrincipalWire `json:"entra_service_principal,omitempty"` +} + +func modelProviderServiceConfig_AzureOpenAiProviderDirectConfigToWire(v *ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig) (*modelProviderServiceConfig_AzureOpenAiProviderDirectConfigWire, error) { + if v == nil { + return nil, nil + } + var authModeApiKeyWire *modelProviderServiceConfig_ProviderSecretWire + var authModeServiceCredentialWire *modelProviderServiceConfig_ServiceCredentialWire + var authModeEntraServicePrincipalWire *modelProviderServiceConfig_EntraServicePrincipalWire + switch value := v.AuthMode.(type) { + case nil: + case *ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ApiKey: + if value != nil { + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretToWire(&value.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeApiKeyWire = authModeApiKeyConverted + } + case *ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ServiceCredential: + if value != nil { + authModeServiceCredentialConverted, err := modelProviderServiceConfig_ServiceCredentialToWire(&value.ServiceCredential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode.ServiceCredential", err) + } + authModeServiceCredentialWire = authModeServiceCredentialConverted + } + case *ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_EntraServicePrincipal: + if value != nil { + authModeEntraServicePrincipalConverted, err := modelProviderServiceConfig_EntraServicePrincipalToWire(&value.EntraServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode.EntraServicePrincipal", err) + } + authModeEntraServicePrincipalWire = authModeEntraServicePrincipalConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode", value) + } + return &modelProviderServiceConfig_AzureOpenAiProviderDirectConfigWire{ + BaseUrl: v.BaseUrl, + ApiKey: authModeApiKeyWire, + ServiceCredential: authModeServiceCredentialWire, + EntraServicePrincipal: authModeEntraServicePrincipalWire, + }, nil +} + +func modelProviderServiceConfig_AzureOpenAiProviderDirectConfigFromWire(w *modelProviderServiceConfig_AzureOpenAiProviderDirectConfigWire) (*ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig, error) { + if w == nil { + return nil, nil + } + authModeMembers := 0 + if w.ApiKey != nil { + authModeMembers++ + } + if w.ServiceCredential != nil { + authModeMembers++ + } + if w.EntraServicePrincipal != nil { + authModeMembers++ + } + if authModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode") + } + var authModeSelection isModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode + switch { + case w.ApiKey != nil: + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretFromWire(w.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeSelection = &ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ApiKey{ApiKey: *authModeApiKeyConverted} + case w.ServiceCredential != nil: + authModeServiceCredentialConverted, err := modelProviderServiceConfig_ServiceCredentialFromWire(w.ServiceCredential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode.ServiceCredential", err) + } + authModeSelection = &ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_ServiceCredential{ServiceCredential: *authModeServiceCredentialConverted} + case w.EntraServicePrincipal != nil: + authModeEntraServicePrincipalConverted, err := modelProviderServiceConfig_EntraServicePrincipalFromWire(w.EntraServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig.AuthMode.EntraServicePrincipal", err) + } + authModeSelection = &ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig_AuthMode_EntraServicePrincipal{EntraServicePrincipal: *authModeEntraServicePrincipalConverted} + } + return &ModelProviderServiceConfig_AzureOpenAiProviderDirectConfig{ + BaseUrl: w.BaseUrl, + AuthMode: authModeSelection, + }, nil +} + +type modelProviderServiceConfig_CustomProviderConfigWire struct { + Direct *modelProviderServiceConfig_CustomProviderDirectConfigWire `json:"direct,omitempty"` +} + +func modelProviderServiceConfig_CustomProviderConfigToWire(v *ModelProviderServiceConfig_CustomProviderConfig) (*modelProviderServiceConfig_CustomProviderConfigWire, error) { + if v == nil { + return nil, nil + } + var providerModeDirectWire *modelProviderServiceConfig_CustomProviderDirectConfigWire + switch value := v.ProviderMode.(type) { + case nil: + case *ModelProviderServiceConfig_CustomProviderConfig_ProviderMode_Direct: + if value != nil { + providerModeDirectConverted, err := modelProviderServiceConfig_CustomProviderDirectConfigToWire(&value.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_CustomProviderConfig.ProviderMode.Direct", err) + } + providerModeDirectWire = providerModeDirectConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_CustomProviderConfig.ProviderMode", value) + } + return &modelProviderServiceConfig_CustomProviderConfigWire{ + Direct: providerModeDirectWire, + }, nil +} + +func modelProviderServiceConfig_CustomProviderConfigFromWire(w *modelProviderServiceConfig_CustomProviderConfigWire) (*ModelProviderServiceConfig_CustomProviderConfig, error) { + if w == nil { + return nil, nil + } + providerModeMembers := 0 + if w.Direct != nil { + providerModeMembers++ + } + if providerModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_CustomProviderConfig.ProviderMode") + } + var providerModeSelection isModelProviderServiceConfig_CustomProviderConfig_ProviderMode + switch { + case w.Direct != nil: + providerModeDirectConverted, err := modelProviderServiceConfig_CustomProviderDirectConfigFromWire(w.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_CustomProviderConfig.ProviderMode.Direct", err) + } + providerModeSelection = &ModelProviderServiceConfig_CustomProviderConfig_ProviderMode_Direct{Direct: *providerModeDirectConverted} + } + return &ModelProviderServiceConfig_CustomProviderConfig{ + ProviderMode: providerModeSelection, + }, nil +} + +type modelProviderServiceConfig_CustomProviderDirectConfigWire struct { + BaseUrl *string `json:"base_url,omitempty"` + ApiKey *modelProviderServiceConfig_ProviderSecretWire `json:"api_key,omitempty"` +} + +func modelProviderServiceConfig_CustomProviderDirectConfigToWire(v *ModelProviderServiceConfig_CustomProviderDirectConfig) (*modelProviderServiceConfig_CustomProviderDirectConfigWire, error) { + if v == nil { + return nil, nil + } + var authModeApiKeyWire *modelProviderServiceConfig_ProviderSecretWire + switch value := v.AuthMode.(type) { + case nil: + case *ModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode_ApiKey: + if value != nil { + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretToWire(&value.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_CustomProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeApiKeyWire = authModeApiKeyConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_CustomProviderDirectConfig.AuthMode", value) + } + return &modelProviderServiceConfig_CustomProviderDirectConfigWire{ + BaseUrl: v.BaseUrl, + ApiKey: authModeApiKeyWire, + }, nil +} + +func modelProviderServiceConfig_CustomProviderDirectConfigFromWire(w *modelProviderServiceConfig_CustomProviderDirectConfigWire) (*ModelProviderServiceConfig_CustomProviderDirectConfig, error) { + if w == nil { + return nil, nil + } + authModeMembers := 0 + if w.ApiKey != nil { + authModeMembers++ + } + if authModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_CustomProviderDirectConfig.AuthMode") + } + var authModeSelection isModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode + switch { + case w.ApiKey != nil: + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretFromWire(w.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_CustomProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeSelection = &ModelProviderServiceConfig_CustomProviderDirectConfig_AuthMode_ApiKey{ApiKey: *authModeApiKeyConverted} + } + return &ModelProviderServiceConfig_CustomProviderDirectConfig{ + BaseUrl: w.BaseUrl, + AuthMode: authModeSelection, + }, nil +} + +type modelProviderServiceConfig_EntraServicePrincipalWire struct { + TenantId *string `json:"tenant_id,omitempty"` + ClientId *string `json:"client_id,omitempty"` + ClientSecret *modelProviderServiceConfig_ProviderSecretWire `json:"client_secret,omitempty"` +} + +func modelProviderServiceConfig_EntraServicePrincipalToWire(v *ModelProviderServiceConfig_EntraServicePrincipal) (*modelProviderServiceConfig_EntraServicePrincipalWire, error) { + if v == nil { + return nil, nil + } + var credentialClientSecretWire *modelProviderServiceConfig_ProviderSecretWire + switch value := v.Credential.(type) { + case nil: + case *ModelProviderServiceConfig_EntraServicePrincipal_Credential_ClientSecret: + if value != nil { + credentialClientSecretConverted, err := modelProviderServiceConfig_ProviderSecretToWire(&value.ClientSecret) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_EntraServicePrincipal.Credential.ClientSecret", err) + } + credentialClientSecretWire = credentialClientSecretConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_EntraServicePrincipal.Credential", value) + } + return &modelProviderServiceConfig_EntraServicePrincipalWire{ + TenantId: v.TenantId, + ClientId: v.ClientId, + ClientSecret: credentialClientSecretWire, + }, nil +} + +func modelProviderServiceConfig_EntraServicePrincipalFromWire(w *modelProviderServiceConfig_EntraServicePrincipalWire) (*ModelProviderServiceConfig_EntraServicePrincipal, error) { + if w == nil { + return nil, nil + } + credentialMembers := 0 + if w.ClientSecret != nil { + credentialMembers++ + } + if credentialMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_EntraServicePrincipal.Credential") + } + var credentialSelection isModelProviderServiceConfig_EntraServicePrincipal_Credential + switch { + case w.ClientSecret != nil: + credentialClientSecretConverted, err := modelProviderServiceConfig_ProviderSecretFromWire(w.ClientSecret) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_EntraServicePrincipal.Credential.ClientSecret", err) + } + credentialSelection = &ModelProviderServiceConfig_EntraServicePrincipal_Credential_ClientSecret{ClientSecret: *credentialClientSecretConverted} + } + return &ModelProviderServiceConfig_EntraServicePrincipal{ + TenantId: w.TenantId, + ClientId: w.ClientId, + Credential: credentialSelection, + }, nil +} + +type modelProviderServiceConfig_GeminiEnterpriseProviderConfigWire struct { + Direct *modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigWire `json:"direct,omitempty"` +} + +func modelProviderServiceConfig_GeminiEnterpriseProviderConfigToWire(v *ModelProviderServiceConfig_GeminiEnterpriseProviderConfig) (*modelProviderServiceConfig_GeminiEnterpriseProviderConfigWire, error) { + if v == nil { + return nil, nil + } + var providerModeDirectWire *modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigWire + switch value := v.ProviderMode.(type) { + case nil: + case *ModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode_Direct: + if value != nil { + providerModeDirectConverted, err := modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigToWire(&value.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_GeminiEnterpriseProviderConfig.ProviderMode.Direct", err) + } + providerModeDirectWire = providerModeDirectConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_GeminiEnterpriseProviderConfig.ProviderMode", value) + } + return &modelProviderServiceConfig_GeminiEnterpriseProviderConfigWire{ + Direct: providerModeDirectWire, + }, nil +} + +func modelProviderServiceConfig_GeminiEnterpriseProviderConfigFromWire(w *modelProviderServiceConfig_GeminiEnterpriseProviderConfigWire) (*ModelProviderServiceConfig_GeminiEnterpriseProviderConfig, error) { + if w == nil { + return nil, nil + } + providerModeMembers := 0 + if w.Direct != nil { + providerModeMembers++ + } + if providerModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_GeminiEnterpriseProviderConfig.ProviderMode") + } + var providerModeSelection isModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode + switch { + case w.Direct != nil: + providerModeDirectConverted, err := modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigFromWire(w.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_GeminiEnterpriseProviderConfig.ProviderMode.Direct", err) + } + providerModeSelection = &ModelProviderServiceConfig_GeminiEnterpriseProviderConfig_ProviderMode_Direct{Direct: *providerModeDirectConverted} + } + return &ModelProviderServiceConfig_GeminiEnterpriseProviderConfig{ + ProviderMode: providerModeSelection, + }, nil +} + +type modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigWire struct { + ApiKey *modelProviderServiceConfig_ProviderSecretWire `json:"api_key,omitempty"` + ProjectId *string `json:"project_id,omitempty"` + Region *string `json:"region,omitempty"` +} + +func modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigToWire(v *ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig) (*modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigWire, error) { + if v == nil { + return nil, nil + } + var authModeApiKeyWire *modelProviderServiceConfig_ProviderSecretWire + switch value := v.AuthMode.(type) { + case nil: + case *ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode_ApiKey: + if value != nil { + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretToWire(&value.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeApiKeyWire = authModeApiKeyConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig.AuthMode", value) + } + return &modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigWire{ + ApiKey: authModeApiKeyWire, + ProjectId: v.ProjectId, + Region: v.Region, + }, nil +} + +func modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigFromWire(w *modelProviderServiceConfig_GeminiEnterpriseProviderDirectConfigWire) (*ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig, error) { + if w == nil { + return nil, nil + } + authModeMembers := 0 + if w.ApiKey != nil { + authModeMembers++ + } + if authModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig.AuthMode") + } + var authModeSelection isModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode + switch { + case w.ApiKey != nil: + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretFromWire(w.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeSelection = &ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig_AuthMode_ApiKey{ApiKey: *authModeApiKeyConverted} + } + return &ModelProviderServiceConfig_GeminiEnterpriseProviderDirectConfig{ + ProjectId: w.ProjectId, + Region: w.Region, + AuthMode: authModeSelection, + }, nil +} + +type modelProviderServiceConfig_MicrosoftFoundryProviderConfigWire struct { + Direct *modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigWire `json:"direct,omitempty"` +} + +func modelProviderServiceConfig_MicrosoftFoundryProviderConfigToWire(v *ModelProviderServiceConfig_MicrosoftFoundryProviderConfig) (*modelProviderServiceConfig_MicrosoftFoundryProviderConfigWire, error) { + if v == nil { + return nil, nil + } + var providerModeDirectWire *modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigWire + switch value := v.ProviderMode.(type) { + case nil: + case *ModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode_Direct: + if value != nil { + providerModeDirectConverted, err := modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigToWire(&value.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_MicrosoftFoundryProviderConfig.ProviderMode.Direct", err) + } + providerModeDirectWire = providerModeDirectConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_MicrosoftFoundryProviderConfig.ProviderMode", value) + } + return &modelProviderServiceConfig_MicrosoftFoundryProviderConfigWire{ + Direct: providerModeDirectWire, + }, nil +} + +func modelProviderServiceConfig_MicrosoftFoundryProviderConfigFromWire(w *modelProviderServiceConfig_MicrosoftFoundryProviderConfigWire) (*ModelProviderServiceConfig_MicrosoftFoundryProviderConfig, error) { + if w == nil { + return nil, nil + } + providerModeMembers := 0 + if w.Direct != nil { + providerModeMembers++ + } + if providerModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_MicrosoftFoundryProviderConfig.ProviderMode") + } + var providerModeSelection isModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode + switch { + case w.Direct != nil: + providerModeDirectConverted, err := modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigFromWire(w.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_MicrosoftFoundryProviderConfig.ProviderMode.Direct", err) + } + providerModeSelection = &ModelProviderServiceConfig_MicrosoftFoundryProviderConfig_ProviderMode_Direct{Direct: *providerModeDirectConverted} + } + return &ModelProviderServiceConfig_MicrosoftFoundryProviderConfig{ + ProviderMode: providerModeSelection, + }, nil +} + +type modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigWire struct { + BaseUrl *string `json:"base_url,omitempty"` + ApiKey *modelProviderServiceConfig_ProviderSecretWire `json:"api_key,omitempty"` + ServiceCredential *modelProviderServiceConfig_ServiceCredentialWire `json:"service_credential,omitempty"` + EntraServicePrincipal *modelProviderServiceConfig_EntraServicePrincipalWire `json:"entra_service_principal,omitempty"` +} + +func modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigToWire(v *ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig) (*modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigWire, error) { + if v == nil { + return nil, nil + } + var authModeApiKeyWire *modelProviderServiceConfig_ProviderSecretWire + var authModeServiceCredentialWire *modelProviderServiceConfig_ServiceCredentialWire + var authModeEntraServicePrincipalWire *modelProviderServiceConfig_EntraServicePrincipalWire + switch value := v.AuthMode.(type) { + case nil: + case *ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ApiKey: + if value != nil { + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretToWire(&value.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeApiKeyWire = authModeApiKeyConverted + } + case *ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ServiceCredential: + if value != nil { + authModeServiceCredentialConverted, err := modelProviderServiceConfig_ServiceCredentialToWire(&value.ServiceCredential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode.ServiceCredential", err) + } + authModeServiceCredentialWire = authModeServiceCredentialConverted + } + case *ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_EntraServicePrincipal: + if value != nil { + authModeEntraServicePrincipalConverted, err := modelProviderServiceConfig_EntraServicePrincipalToWire(&value.EntraServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode.EntraServicePrincipal", err) + } + authModeEntraServicePrincipalWire = authModeEntraServicePrincipalConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode", value) + } + return &modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigWire{ + BaseUrl: v.BaseUrl, + ApiKey: authModeApiKeyWire, + ServiceCredential: authModeServiceCredentialWire, + EntraServicePrincipal: authModeEntraServicePrincipalWire, + }, nil +} + +func modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigFromWire(w *modelProviderServiceConfig_MicrosoftFoundryProviderDirectConfigWire) (*ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig, error) { + if w == nil { + return nil, nil + } + authModeMembers := 0 + if w.ApiKey != nil { + authModeMembers++ + } + if w.ServiceCredential != nil { + authModeMembers++ + } + if w.EntraServicePrincipal != nil { + authModeMembers++ + } + if authModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode") + } + var authModeSelection isModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode + switch { + case w.ApiKey != nil: + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretFromWire(w.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeSelection = &ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ApiKey{ApiKey: *authModeApiKeyConverted} + case w.ServiceCredential != nil: + authModeServiceCredentialConverted, err := modelProviderServiceConfig_ServiceCredentialFromWire(w.ServiceCredential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode.ServiceCredential", err) + } + authModeSelection = &ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_ServiceCredential{ServiceCredential: *authModeServiceCredentialConverted} + case w.EntraServicePrincipal != nil: + authModeEntraServicePrincipalConverted, err := modelProviderServiceConfig_EntraServicePrincipalFromWire(w.EntraServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig.AuthMode.EntraServicePrincipal", err) + } + authModeSelection = &ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig_AuthMode_EntraServicePrincipal{EntraServicePrincipal: *authModeEntraServicePrincipalConverted} + } + return &ModelProviderServiceConfig_MicrosoftFoundryProviderDirectConfig{ + BaseUrl: w.BaseUrl, + AuthMode: authModeSelection, + }, nil +} + +type modelProviderServiceConfig_ModelTargetConfigWire struct { + Model *string `json:"model,omitempty"` + NativeApiTypes []string `json:"native_api_types,omitempty"` +} + +func modelProviderServiceConfig_ModelTargetConfigToWire(v *ModelProviderServiceConfig_ModelTargetConfig) (*modelProviderServiceConfig_ModelTargetConfigWire, error) { + if v == nil { + return nil, nil + } + return &modelProviderServiceConfig_ModelTargetConfigWire{ + Model: v.Model, + NativeApiTypes: v.NativeApiTypes, + }, nil +} + +func modelProviderServiceConfig_ModelTargetConfigFromWire(w *modelProviderServiceConfig_ModelTargetConfigWire) (*ModelProviderServiceConfig_ModelTargetConfig, error) { + if w == nil { + return nil, nil + } + return &ModelProviderServiceConfig_ModelTargetConfig{ + Model: w.Model, + NativeApiTypes: w.NativeApiTypes, + }, nil +} + +type modelProviderServiceConfig_OpenAiProviderConfigWire struct { + Direct *modelProviderServiceConfig_OpenAiProviderDirectConfigWire `json:"direct,omitempty"` +} + +func modelProviderServiceConfig_OpenAiProviderConfigToWire(v *ModelProviderServiceConfig_OpenAiProviderConfig) (*modelProviderServiceConfig_OpenAiProviderConfigWire, error) { + if v == nil { + return nil, nil + } + var providerModeDirectWire *modelProviderServiceConfig_OpenAiProviderDirectConfigWire + switch value := v.ProviderMode.(type) { + case nil: + case *ModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode_Direct: + if value != nil { + providerModeDirectConverted, err := modelProviderServiceConfig_OpenAiProviderDirectConfigToWire(&value.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_OpenAiProviderConfig.ProviderMode.Direct", err) + } + providerModeDirectWire = providerModeDirectConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_OpenAiProviderConfig.ProviderMode", value) + } + return &modelProviderServiceConfig_OpenAiProviderConfigWire{ + Direct: providerModeDirectWire, + }, nil +} + +func modelProviderServiceConfig_OpenAiProviderConfigFromWire(w *modelProviderServiceConfig_OpenAiProviderConfigWire) (*ModelProviderServiceConfig_OpenAiProviderConfig, error) { + if w == nil { + return nil, nil + } + providerModeMembers := 0 + if w.Direct != nil { + providerModeMembers++ + } + if providerModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_OpenAiProviderConfig.ProviderMode") + } + var providerModeSelection isModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode + switch { + case w.Direct != nil: + providerModeDirectConverted, err := modelProviderServiceConfig_OpenAiProviderDirectConfigFromWire(w.Direct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_OpenAiProviderConfig.ProviderMode.Direct", err) + } + providerModeSelection = &ModelProviderServiceConfig_OpenAiProviderConfig_ProviderMode_Direct{Direct: *providerModeDirectConverted} + } + return &ModelProviderServiceConfig_OpenAiProviderConfig{ + ProviderMode: providerModeSelection, + }, nil +} + +type modelProviderServiceConfig_OpenAiProviderDirectConfigWire struct { + ApiKey *modelProviderServiceConfig_ProviderSecretWire `json:"api_key,omitempty"` + Organization *string `json:"organization,omitempty"` + BaseUrl *string `json:"base_url,omitempty"` +} + +func modelProviderServiceConfig_OpenAiProviderDirectConfigToWire(v *ModelProviderServiceConfig_OpenAiProviderDirectConfig) (*modelProviderServiceConfig_OpenAiProviderDirectConfigWire, error) { + if v == nil { + return nil, nil + } + var authModeApiKeyWire *modelProviderServiceConfig_ProviderSecretWire + switch value := v.AuthMode.(type) { + case nil: + case *ModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode_ApiKey: + if value != nil { + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretToWire(&value.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_OpenAiProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeApiKeyWire = authModeApiKeyConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_OpenAiProviderDirectConfig.AuthMode", value) + } + return &modelProviderServiceConfig_OpenAiProviderDirectConfigWire{ + ApiKey: authModeApiKeyWire, + Organization: v.Organization, + BaseUrl: v.BaseUrl, + }, nil +} + +func modelProviderServiceConfig_OpenAiProviderDirectConfigFromWire(w *modelProviderServiceConfig_OpenAiProviderDirectConfigWire) (*ModelProviderServiceConfig_OpenAiProviderDirectConfig, error) { + if w == nil { + return nil, nil + } + authModeMembers := 0 + if w.ApiKey != nil { + authModeMembers++ + } + if authModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_OpenAiProviderDirectConfig.AuthMode") + } + var authModeSelection isModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode + switch { + case w.ApiKey != nil: + authModeApiKeyConverted, err := modelProviderServiceConfig_ProviderSecretFromWire(w.ApiKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelProviderServiceConfig_OpenAiProviderDirectConfig.AuthMode.ApiKey", err) + } + authModeSelection = &ModelProviderServiceConfig_OpenAiProviderDirectConfig_AuthMode_ApiKey{ApiKey: *authModeApiKeyConverted} + } + return &ModelProviderServiceConfig_OpenAiProviderDirectConfig{ + Organization: w.Organization, + BaseUrl: w.BaseUrl, + AuthMode: authModeSelection, + }, nil +} + +type modelProviderServiceConfig_ProviderSecretWire struct { + Plaintext *string `json:"plaintext,omitempty"` +} + +func modelProviderServiceConfig_ProviderSecretToWire(v *ModelProviderServiceConfig_ProviderSecret) (*modelProviderServiceConfig_ProviderSecretWire, error) { + if v == nil { + return nil, nil + } + var valuePlaintextWire *string + switch value := v.Value.(type) { + case nil: + case *ModelProviderServiceConfig_ProviderSecret_Value_Plaintext: + if value != nil { + valuePlaintextWire = new(value.Plaintext) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelProviderServiceConfig_ProviderSecret.Value", value) + } + return &modelProviderServiceConfig_ProviderSecretWire{ + Plaintext: valuePlaintextWire, + }, nil +} + +func modelProviderServiceConfig_ProviderSecretFromWire(w *modelProviderServiceConfig_ProviderSecretWire) (*ModelProviderServiceConfig_ProviderSecret, error) { + if w == nil { + return nil, nil + } + valueMembers := 0 + if w.Plaintext != nil { + valueMembers++ + } + if valueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelProviderServiceConfig_ProviderSecret.Value") + } + var valueSelection isModelProviderServiceConfig_ProviderSecret_Value + switch { + case w.Plaintext != nil: + valueSelection = &ModelProviderServiceConfig_ProviderSecret_Value_Plaintext{Plaintext: *w.Plaintext} + } + return &ModelProviderServiceConfig_ProviderSecret{ + Value: valueSelection, + }, nil +} + +type modelProviderServiceConfig_ServiceCredentialWire struct { + Name *string `json:"name,omitempty"` +} + +func modelProviderServiceConfig_ServiceCredentialToWire(v *ModelProviderServiceConfig_ServiceCredential) (*modelProviderServiceConfig_ServiceCredentialWire, error) { + if v == nil { + return nil, nil + } + return &modelProviderServiceConfig_ServiceCredentialWire{ + Name: v.Name, + }, nil +} + +func modelProviderServiceConfig_ServiceCredentialFromWire(w *modelProviderServiceConfig_ServiceCredentialWire) (*ModelProviderServiceConfig_ServiceCredential, error) { + if w == nil { + return nil, nil + } + return &ModelProviderServiceConfig_ServiceCredential{ + Name: w.Name, + }, nil +} + +type modelServiceWire struct { + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + EffectiveOwner *string `json:"effective_owner,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Comment *string `json:"comment,omitempty"` + Config *modelServiceConfigWire `json:"config,omitempty"` + Etag []byte `json:"etag,omitempty"` + SupportedApiTypes []string `json:"supported_api_types,omitempty"` +} + +func modelServiceToWire(v *ModelService) (*modelServiceWire, error) { + if v == nil { + return nil, nil + } + configWireValue, err := modelServiceConfigToWire(v.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelService.Config", err) + } + return &modelServiceWire{ + Name: v.Name, + Owner: v.Owner, + EffectiveOwner: v.EffectiveOwner, + MetastoreId: v.MetastoreId, + CreateTime: v.CreateTime, + CreatedBy: v.CreatedBy, + UpdateTime: v.UpdateTime, + UpdatedBy: v.UpdatedBy, + Comment: v.Comment, + Config: configWireValue, + Etag: v.Etag, + SupportedApiTypes: v.SupportedApiTypes, + }, nil +} + +func modelServiceFromWire(w *modelServiceWire) (*ModelService, error) { + if w == nil { + return nil, nil + } + configPublicValue, err := modelServiceConfigFromWire(w.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelService.Config", err) + } + return &ModelService{ + Name: w.Name, + Owner: w.Owner, + EffectiveOwner: w.EffectiveOwner, + MetastoreId: w.MetastoreId, + CreateTime: w.CreateTime, + CreatedBy: w.CreatedBy, + UpdateTime: w.UpdateTime, + UpdatedBy: w.UpdatedBy, + Comment: w.Comment, + Config: configPublicValue, + Etag: w.Etag, + SupportedApiTypes: w.SupportedApiTypes, + }, nil +} + +type modelServiceConfigWire struct { + Routing *modelServiceConfig_RoutingConfigWire `json:"routing,omitempty"` + RateLimits []rateLimitWire `json:"rate_limits,omitempty"` + InferenceTable *inferenceTableConfigWire `json:"inference_table,omitempty"` +} + +func modelServiceConfigToWire(v *ModelServiceConfig) (*modelServiceConfigWire, error) { + if v == nil { + return nil, nil + } + routingWireValue, err := modelServiceConfig_RoutingConfigToWire(v.Routing) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig.Routing", err) + } + rateLimitsWireValue, err := convertSlice(v.RateLimits, rateLimitToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig.RateLimits", err) + } + inferenceTableWireValue, err := inferenceTableConfigToWire(v.InferenceTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig.InferenceTable", err) + } + return &modelServiceConfigWire{ + Routing: routingWireValue, + RateLimits: rateLimitsWireValue, + InferenceTable: inferenceTableWireValue, + }, nil +} + +func modelServiceConfigFromWire(w *modelServiceConfigWire) (*ModelServiceConfig, error) { + if w == nil { + return nil, nil + } + routingPublicValue, err := modelServiceConfig_RoutingConfigFromWire(w.Routing) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig.Routing", err) + } + rateLimitsPublicValue, err := convertSlice(w.RateLimits, rateLimitFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig.RateLimits", err) + } + inferenceTablePublicValue, err := inferenceTableConfigFromWire(w.InferenceTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig.InferenceTable", err) + } + return &ModelServiceConfig{ + Routing: routingPublicValue, + RateLimits: rateLimitsPublicValue, + InferenceTable: inferenceTablePublicValue, + }, nil +} + +type modelServiceConfig_DestinationConfigWire struct { + Name *string `json:"name,omitempty"` + DestinationType ModelServiceConfig_DestinationConfig_DestinationType `json:"destination_type,omitempty"` + TrafficPercentage *int `json:"traffic_percentage,omitempty"` + PayPerTokenConfig *modelServiceConfig_PayPerTokenConfigWire `json:"pay_per_token_config,omitempty"` + ProvisionedThroughputConfig *modelServiceConfig_ProvisionedThroughputConfigWire `json:"provisioned_throughput_config,omitempty"` + ExternalModelConfig *modelServiceConfig_ExternalModelConfigWire `json:"external_model_config,omitempty"` + IsDeleted *bool `json:"is_deleted,omitempty"` +} + +func modelServiceConfig_DestinationConfigToWire(v *ModelServiceConfig_DestinationConfig) (*modelServiceConfig_DestinationConfigWire, error) { + if v == nil { + return nil, nil + } + var typeConfigPayPerTokenConfigWire *modelServiceConfig_PayPerTokenConfigWire + var typeConfigProvisionedThroughputConfigWire *modelServiceConfig_ProvisionedThroughputConfigWire + var typeConfigExternalModelConfigWire *modelServiceConfig_ExternalModelConfigWire + switch value := v.TypeConfig.(type) { + case nil: + case *ModelServiceConfig_DestinationConfig_TypeConfig_PayPerTokenConfig: + if value != nil { + typeConfigPayPerTokenConfigConverted, err := modelServiceConfig_PayPerTokenConfigToWire(&value.PayPerTokenConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_DestinationConfig.TypeConfig.PayPerTokenConfig", err) + } + typeConfigPayPerTokenConfigWire = typeConfigPayPerTokenConfigConverted + } + case *ModelServiceConfig_DestinationConfig_TypeConfig_ProvisionedThroughputConfig: + if value != nil { + typeConfigProvisionedThroughputConfigConverted, err := modelServiceConfig_ProvisionedThroughputConfigToWire(&value.ProvisionedThroughputConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_DestinationConfig.TypeConfig.ProvisionedThroughputConfig", err) + } + typeConfigProvisionedThroughputConfigWire = typeConfigProvisionedThroughputConfigConverted + } + case *ModelServiceConfig_DestinationConfig_TypeConfig_ExternalModelConfig: + if value != nil { + typeConfigExternalModelConfigConverted, err := modelServiceConfig_ExternalModelConfigToWire(&value.ExternalModelConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_DestinationConfig.TypeConfig.ExternalModelConfig", err) + } + typeConfigExternalModelConfigWire = typeConfigExternalModelConfigConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelServiceConfig_DestinationConfig.TypeConfig", value) + } + return &modelServiceConfig_DestinationConfigWire{ + Name: v.Name, + DestinationType: v.DestinationType, + TrafficPercentage: v.TrafficPercentage, + PayPerTokenConfig: typeConfigPayPerTokenConfigWire, + ProvisionedThroughputConfig: typeConfigProvisionedThroughputConfigWire, + ExternalModelConfig: typeConfigExternalModelConfigWire, + IsDeleted: v.IsDeleted, + }, nil +} + +func modelServiceConfig_DestinationConfigFromWire(w *modelServiceConfig_DestinationConfigWire) (*ModelServiceConfig_DestinationConfig, error) { + if w == nil { + return nil, nil + } + typeConfigMembers := 0 + if w.PayPerTokenConfig != nil { + typeConfigMembers++ + } + if w.ProvisionedThroughputConfig != nil { + typeConfigMembers++ + } + if w.ExternalModelConfig != nil { + typeConfigMembers++ + } + if typeConfigMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelServiceConfig_DestinationConfig.TypeConfig") + } + var typeConfigSelection isModelServiceConfig_DestinationConfig_TypeConfig + switch { + case w.PayPerTokenConfig != nil: + typeConfigPayPerTokenConfigConverted, err := modelServiceConfig_PayPerTokenConfigFromWire(w.PayPerTokenConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_DestinationConfig.TypeConfig.PayPerTokenConfig", err) + } + typeConfigSelection = &ModelServiceConfig_DestinationConfig_TypeConfig_PayPerTokenConfig{PayPerTokenConfig: *typeConfigPayPerTokenConfigConverted} + case w.ProvisionedThroughputConfig != nil: + typeConfigProvisionedThroughputConfigConverted, err := modelServiceConfig_ProvisionedThroughputConfigFromWire(w.ProvisionedThroughputConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_DestinationConfig.TypeConfig.ProvisionedThroughputConfig", err) + } + typeConfigSelection = &ModelServiceConfig_DestinationConfig_TypeConfig_ProvisionedThroughputConfig{ProvisionedThroughputConfig: *typeConfigProvisionedThroughputConfigConverted} + case w.ExternalModelConfig != nil: + typeConfigExternalModelConfigConverted, err := modelServiceConfig_ExternalModelConfigFromWire(w.ExternalModelConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_DestinationConfig.TypeConfig.ExternalModelConfig", err) + } + typeConfigSelection = &ModelServiceConfig_DestinationConfig_TypeConfig_ExternalModelConfig{ExternalModelConfig: *typeConfigExternalModelConfigConverted} + } + return &ModelServiceConfig_DestinationConfig{ + Name: w.Name, + DestinationType: w.DestinationType, + TrafficPercentage: w.TrafficPercentage, + IsDeleted: w.IsDeleted, + TypeConfig: typeConfigSelection, + }, nil +} + +type modelServiceConfig_ExternalModelConfigWire struct { + ModelProviderService *string `json:"model_provider_service,omitempty"` + Target *modelProviderServiceConfig_ModelTargetConfigWire `json:"target,omitempty"` +} + +func modelServiceConfig_ExternalModelConfigToWire(v *ModelServiceConfig_ExternalModelConfig) (*modelServiceConfig_ExternalModelConfigWire, error) { + if v == nil { + return nil, nil + } + targetWireValue, err := modelProviderServiceConfig_ModelTargetConfigToWire(v.Target) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_ExternalModelConfig.Target", err) + } + return &modelServiceConfig_ExternalModelConfigWire{ + ModelProviderService: v.ModelProviderService, + Target: targetWireValue, + }, nil +} + +func modelServiceConfig_ExternalModelConfigFromWire(w *modelServiceConfig_ExternalModelConfigWire) (*ModelServiceConfig_ExternalModelConfig, error) { + if w == nil { + return nil, nil + } + targetPublicValue, err := modelProviderServiceConfig_ModelTargetConfigFromWire(w.Target) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_ExternalModelConfig.Target", err) + } + return &ModelServiceConfig_ExternalModelConfig{ + ModelProviderService: w.ModelProviderService, + Target: targetPublicValue, + }, nil +} + +type modelServiceConfig_FallbackConfigWire struct { + Destinations []modelServiceConfig_DestinationConfigWire `json:"destinations,omitempty"` +} + +func modelServiceConfig_FallbackConfigToWire(v *ModelServiceConfig_FallbackConfig) (*modelServiceConfig_FallbackConfigWire, error) { + if v == nil { + return nil, nil + } + destinationsWireValue, err := convertSlice(v.Destinations, modelServiceConfig_DestinationConfigToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_FallbackConfig.Destinations", err) + } + return &modelServiceConfig_FallbackConfigWire{ + Destinations: destinationsWireValue, + }, nil +} + +func modelServiceConfig_FallbackConfigFromWire(w *modelServiceConfig_FallbackConfigWire) (*ModelServiceConfig_FallbackConfig, error) { + if w == nil { + return nil, nil + } + destinationsPublicValue, err := convertSlice(w.Destinations, modelServiceConfig_DestinationConfigFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_FallbackConfig.Destinations", err) + } + return &ModelServiceConfig_FallbackConfig{ + Destinations: destinationsPublicValue, + }, nil +} + +type modelServiceConfig_PayPerTokenConfigWire struct { + Model *string `json:"model,omitempty"` +} + +func modelServiceConfig_PayPerTokenConfigToWire(v *ModelServiceConfig_PayPerTokenConfig) (*modelServiceConfig_PayPerTokenConfigWire, error) { + if v == nil { + return nil, nil + } + return &modelServiceConfig_PayPerTokenConfigWire{ + Model: v.Model, + }, nil +} + +func modelServiceConfig_PayPerTokenConfigFromWire(w *modelServiceConfig_PayPerTokenConfigWire) (*ModelServiceConfig_PayPerTokenConfig, error) { + if w == nil { + return nil, nil + } + return &ModelServiceConfig_PayPerTokenConfig{ + Model: w.Model, + }, nil +} + +type modelServiceConfig_ProvisionedThroughputConfigWire struct { + ModelServingEndpoint *string `json:"model_serving_endpoint,omitempty"` + Model *string `json:"model,omitempty"` +} + +func modelServiceConfig_ProvisionedThroughputConfigToWire(v *ModelServiceConfig_ProvisionedThroughputConfig) (*modelServiceConfig_ProvisionedThroughputConfigWire, error) { + if v == nil { + return nil, nil + } + return &modelServiceConfig_ProvisionedThroughputConfigWire{ + ModelServingEndpoint: v.ModelServingEndpoint, + Model: v.Model, + }, nil +} + +func modelServiceConfig_ProvisionedThroughputConfigFromWire(w *modelServiceConfig_ProvisionedThroughputConfigWire) (*ModelServiceConfig_ProvisionedThroughputConfig, error) { + if w == nil { + return nil, nil + } + return &ModelServiceConfig_ProvisionedThroughputConfig{ + ModelServingEndpoint: w.ModelServingEndpoint, + Model: w.Model, + }, nil +} + +type modelServiceConfig_RoutingConfigWire struct { + Destinations []modelServiceConfig_DestinationConfigWire `json:"destinations,omitempty"` + TrafficSplitting *modelServiceConfig_RoutingConfig_TrafficSplittingWire `json:"traffic_splitting,omitempty"` + Fallback *modelServiceConfig_FallbackConfigWire `json:"fallback,omitempty"` + FirstTokenTimeout *types.Duration `json:"first_token_timeout,omitempty"` +} + +func modelServiceConfig_RoutingConfigToWire(v *ModelServiceConfig_RoutingConfig) (*modelServiceConfig_RoutingConfigWire, error) { + if v == nil { + return nil, nil + } + destinationsWireValue, err := convertSlice(v.Destinations, modelServiceConfig_DestinationConfigToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_RoutingConfig.Destinations", err) + } + fallbackWireValue, err := modelServiceConfig_FallbackConfigToWire(v.Fallback) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_RoutingConfig.Fallback", err) + } + var routingStrategyTrafficSplittingWire *modelServiceConfig_RoutingConfig_TrafficSplittingWire + switch value := v.RoutingStrategy.(type) { + case nil: + case *ModelServiceConfig_RoutingConfig_RoutingStrategy_TrafficSplitting: + if value != nil { + routingStrategyTrafficSplittingConverted, err := modelServiceConfig_RoutingConfig_TrafficSplittingToWire(&value.TrafficSplitting) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_RoutingConfig.RoutingStrategy.TrafficSplitting", err) + } + routingStrategyTrafficSplittingWire = routingStrategyTrafficSplittingConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ModelServiceConfig_RoutingConfig.RoutingStrategy", value) + } + return &modelServiceConfig_RoutingConfigWire{ + Destinations: destinationsWireValue, + TrafficSplitting: routingStrategyTrafficSplittingWire, + Fallback: fallbackWireValue, + FirstTokenTimeout: v.FirstTokenTimeout, + }, nil +} + +func modelServiceConfig_RoutingConfigFromWire(w *modelServiceConfig_RoutingConfigWire) (*ModelServiceConfig_RoutingConfig, error) { + if w == nil { + return nil, nil + } + routingStrategyMembers := 0 + if w.TrafficSplitting != nil { + routingStrategyMembers++ + } + if routingStrategyMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ModelServiceConfig_RoutingConfig.RoutingStrategy") + } + destinationsPublicValue, err := convertSlice(w.Destinations, modelServiceConfig_DestinationConfigFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_RoutingConfig.Destinations", err) + } + fallbackPublicValue, err := modelServiceConfig_FallbackConfigFromWire(w.Fallback) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_RoutingConfig.Fallback", err) + } + var routingStrategySelection isModelServiceConfig_RoutingConfig_RoutingStrategy + switch { + case w.TrafficSplitting != nil: + routingStrategyTrafficSplittingConverted, err := modelServiceConfig_RoutingConfig_TrafficSplittingFromWire(w.TrafficSplitting) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelServiceConfig_RoutingConfig.RoutingStrategy.TrafficSplitting", err) + } + routingStrategySelection = &ModelServiceConfig_RoutingConfig_RoutingStrategy_TrafficSplitting{TrafficSplitting: *routingStrategyTrafficSplittingConverted} + } + return &ModelServiceConfig_RoutingConfig{ + Destinations: destinationsPublicValue, + Fallback: fallbackPublicValue, + FirstTokenTimeout: w.FirstTokenTimeout, + RoutingStrategy: routingStrategySelection, + }, nil +} + +type modelServiceConfig_RoutingConfig_TrafficSplittingWire struct { +} + +func modelServiceConfig_RoutingConfig_TrafficSplittingToWire(v *ModelServiceConfig_RoutingConfig_TrafficSplitting) (*modelServiceConfig_RoutingConfig_TrafficSplittingWire, error) { + if v == nil { + return nil, nil + } + return &modelServiceConfig_RoutingConfig_TrafficSplittingWire{}, nil +} + +func modelServiceConfig_RoutingConfig_TrafficSplittingFromWire(w *modelServiceConfig_RoutingConfig_TrafficSplittingWire) (*ModelServiceConfig_RoutingConfig_TrafficSplitting, error) { + if w == nil { + return nil, nil + } + return &ModelServiceConfig_RoutingConfig_TrafficSplitting{}, nil +} + +type rateLimitWire struct { + Key RateLimit_RateLimitKey `json:"key,omitempty"` + RenewalPeriod RateLimit_RateLimitRenewalPeriod `json:"renewal_period,omitempty"` + Principal *string `json:"principal,omitempty"` + Requests *int64 `json:"requests,omitempty"` + Tokens *int64 `json:"tokens,omitempty"` + RequestTagKey *string `json:"request_tag_key,omitempty"` + RequestTagValue *string `json:"request_tag_value,omitempty"` +} + +func rateLimitToWire(v *RateLimit) (*rateLimitWire, error) { + if v == nil { + return nil, nil + } + return &rateLimitWire{ + Key: v.Key, + RenewalPeriod: v.RenewalPeriod, + Principal: v.Principal, + Requests: v.Requests, + Tokens: v.Tokens, + RequestTagKey: v.RequestTagKey, + RequestTagValue: v.RequestTagValue, + }, nil +} + +func rateLimitFromWire(w *rateLimitWire) (*RateLimit, error) { + if w == nil { + return nil, nil + } + return &RateLimit{ + Key: w.Key, + RenewalPeriod: w.RenewalPeriod, + Principal: w.Principal, + Requests: w.Requests, + Tokens: w.Tokens, + RequestTagKey: w.RequestTagKey, + RequestTagValue: w.RequestTagValue, + }, nil +} + +type updateMcpServiceRequestWire struct { + McpService *mcpServiceWire `json:"mcp_service,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` + Etag []byte `json:"etag,omitempty"` +} + +func updateMcpServiceRequestToWire(v *UpdateMcpServiceRequest) (*updateMcpServiceRequestWire, error) { + if v == nil { + return nil, nil + } + mcpServiceWireValue, err := mcpServiceToWire(v.McpService) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateMcpServiceRequest.McpService", err) + } + return &updateMcpServiceRequestWire{ + McpService: mcpServiceWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + Etag: v.Etag, + }, nil +} + +type updateModelProviderServiceRequestWire struct { + ModelProviderService *modelProviderServiceWire `json:"model_provider_service,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` + Etag []byte `json:"etag,omitempty"` +} + +func updateModelProviderServiceRequestToWire(v *UpdateModelProviderServiceRequest) (*updateModelProviderServiceRequestWire, error) { + if v == nil { + return nil, nil + } + modelProviderServiceWireValue, err := modelProviderServiceToWire(v.ModelProviderService) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateModelProviderServiceRequest.ModelProviderService", err) + } + return &updateModelProviderServiceRequestWire{ + ModelProviderService: modelProviderServiceWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + Etag: v.Etag, + }, nil +} + +type updateModelServiceRequestWire struct { + ModelService *modelServiceWire `json:"model_service,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` + Etag []byte `json:"etag,omitempty"` +} + +func updateModelServiceRequestToWire(v *UpdateModelServiceRequest) (*updateModelServiceRequestWire, error) { + if v == nil { + return nil, nil + } + modelServiceWireValue, err := modelServiceToWire(v.ModelService) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateModelServiceRequest.ModelService", err) + } + return &updateModelServiceRequestWire{ + ModelService: modelServiceWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + Etag: v.Etag, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/alerts/.package.json b/alerts/.package.json new file mode 100644 index 0000000..e991708 --- /dev/null +++ b/alerts/.package.json @@ -0,0 +1,3 @@ +{ + "package": "alerts" +} diff --git a/alerts/CHANGELOG.md b/alerts/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/alerts/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/alerts/README.md b/alerts/README.md new file mode 100644 index 0000000..f317999 --- /dev/null +++ b/alerts/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/alerts + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/alerts@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/alerts/v1" + +client, err := alerts.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/alerts/go.mod b/alerts/go.mod new file mode 100644 index 0000000..27c5afe --- /dev/null +++ b/alerts/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/alerts + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/alerts/internal/version.go b/alerts/internal/version.go new file mode 100644 index 0000000..52ae2e5 --- /dev/null +++ b/alerts/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-alerts" + +const Version = "0.0.1-dev.1" diff --git a/alerts/v1/client.go b/alerts/v1/client.go new file mode 100755 index 0000000..e66367e --- /dev/null +++ b/alerts/v1/client.go @@ -0,0 +1,439 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package alerts + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/alerts/internal" + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates an alert. +func (c *internalClient) CreateAlert(ctx context.Context, req *CreateAlertRequest, opts ...call.Option) (*Alert, error) { + wireReq, err := createAlertRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/sql/alerts" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Alert + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp alertWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = alertFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an alert. +func (c *internalClient) GetAlert(ctx context.Context, req *GetAlertRequest, opts ...call.Option) (*Alert, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/alerts/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Alert + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp alertWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = alertFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a list of alerts accessible to the user, ordered by creation time. +// **Warning:** Calling this API concurrently 10 or more times could result in +// throttling, service degradation, or a temporary ban. +func (c *internalClient) ListAlerts(ctx context.Context, req *ListAlertsRequest, opts ...call.Option) (*ListAlertsResponse, error) { + wireReq, err := listAlertsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/sql/alerts" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAlertsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAlertsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAlertsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListAlertsIter returns an iterator that iterates +// over the results of ListAlerts. +// +// For example: +// +// for item, err := range c.ListAlertsIter(ctx, &ListAlertsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListAlerts call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListAlerts directly. +func (c *internalClient) ListAlertsIter(ctx context.Context, req *ListAlertsRequest, opts ...call.Option) iter.Seq2[*ListAlertsResponseAlert, error] { + return func(yield func(*ListAlertsResponseAlert, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListAlertsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListAlerts(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Results { + if !yield(&resp.Results[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Moves an alert to the trash. Trashed alerts immediately disappear from +// searches and list views, and can no longer trigger. You can restore a trashed +// alert through the UI. A trashed alert is permanently deleted after 30 days. +func (c *internalClient) TrashAlert(ctx context.Context, req *TrashAlertRequest, opts ...call.Option) (*Empty, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/alerts/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Empty + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &Empty{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an alert. +func (c *internalClient) UpdateAlert(ctx context.Context, req *UpdateAlertRequest, opts ...call.Option) (*Alert, error) { + wireReq, err := updateAlertRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/alerts/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Alert + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp alertWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = alertFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/alerts/v1/genhelper.go b/alerts/v1/genhelper.go new file mode 100755 index 0000000..b39ebc3 --- /dev/null +++ b/alerts/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package alerts + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/alerts/v1/model.go b/alerts/v1/model.go new file mode 100755 index 0000000..fca7b7a --- /dev/null +++ b/alerts/v1/model.go @@ -0,0 +1,330 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package alerts + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type AlertOperator string + +const ( + AlertOperator_Unspecified AlertOperator = "" + AlertOperator_GreaterThan AlertOperator = "GREATER_THAN" + AlertOperator_GreaterThanOrEqual AlertOperator = "GREATER_THAN_OR_EQUAL" + AlertOperator_LessThan AlertOperator = "LESS_THAN" + AlertOperator_LessThanOrEqual AlertOperator = "LESS_THAN_OR_EQUAL" + AlertOperator_Equal AlertOperator = "EQUAL" + AlertOperator_NotEqual AlertOperator = "NOT_EQUAL" + AlertOperator_IsNull AlertOperator = "IS_NULL" +) + +type AlertState string + +const ( + AlertState_Unspecified AlertState = "" + AlertState_Unknown AlertState = "UNKNOWN" + AlertState_Ok AlertState = "OK" + AlertState_Triggered AlertState = "TRIGGERED" +) + +type LifecycleState string + +const ( + LifecycleState_Unspecified LifecycleState = "" + LifecycleState_Active LifecycleState = "ACTIVE" + LifecycleState_Trashed LifecycleState = "TRASHED" +) + +type Alert struct { + // UUID identifying the alert. + Id *string + // The display name of the alert. + DisplayName *string + // UUID of the query attached to the alert. + QueryId *string + // Current state of the alert's trigger status. This field is set to UNKNOWN if + // the alert has not yet been evaluated or ran into an error during the last + // evaluation. + State AlertState + // Number of seconds an alert must wait after being triggered to rearm itself. + // After rearming, it can be triggered again. If 0 or not specified, the alert + // will not be triggered again. + SecondsToRetrigger *int + // The workspace state of the alert. Used for tracking trashed status. + LifecycleState LifecycleState + // Timestamp when the alert was last triggered, if the alert has been triggered + // before. + TriggerTime *types.Time + // Custom body of alert notification, if it exists. See + // [here](/sql/user/alerts/index.html) for custom templating instructions. + CustomBody *string + // Custom subject of alert notification, if it exists. This can include email + // subject entries and Slack notification headers, for example. See + // [here](/sql/user/alerts/index.html) for custom templating instructions. + CustomSubject *string + // Trigger conditions of the alert. + Condition *AlertCondition + // The owner's username. This field is set to "Unavailable" if the user has been + // deleted. + OwnerUserName *string + // The workspace path of the folder containing the alert. + ParentPath *string + // The timestamp indicating when the alert was created. + CreateTime *types.Time + // The timestamp indicating when the alert was updated. + UpdateTime *types.Time + // Whether to notify alert subscribers when alert returns back to normal. + NotifyOnOk *bool +} + +type AlertCondition struct { + // Operator used for comparison in alert evaluation. + Op AlertOperator `fieldmask:"op"` + // Name of the column from the query result to use for comparison in alert + // evaluation. + Operand *AlertOperand `fieldmask:"operand"` + // Threshold value used for comparison in alert evaluation. + Threshold *AlertOperand `fieldmask:"threshold"` + // Alert state if result is empty. + EmptyResultState AlertState `fieldmask:"empty_result_state"` +} + +type AlertOperand struct { + // Only one of the following fields may be set, depending on the type of + // operand/threshold. + Operand isAlertOperand_Operand + _ [0]alertOperandOperandFieldMaskMetadata `fieldmask_oneof:"Operand"` +} + +type isAlertOperand_Operand interface { + isAlertOperand_Operand() +} + +// AlertOperand_Operand_Value selects Value for AlertOperand.Operand. +type AlertOperand_Operand_Value struct { + Value AlertOperandValue `fieldmask:"value"` +} + +func (*AlertOperand_Operand_Value) isAlertOperand_Operand() {} + +// AlertOperand_Operand_Column selects Column for AlertOperand.Operand. +type AlertOperand_Operand_Column struct { + Column AlertOperandColumn `fieldmask:"column"` +} + +func (*AlertOperand_Operand_Column) isAlertOperand_Operand() {} + +type alertOperandOperandFieldMaskMetadata struct { + *AlertOperand_Operand_Value + *AlertOperand_Operand_Column +} + +type AlertOperandColumn struct { + Name *string `fieldmask:"name"` +} + +type AlertOperandValue struct { + // Only one of the following fields may be set, depending on the type of + // threshold value. + ThresholdValue isAlertOperandValue_ThresholdValue + _ [0]alertOperandValueThresholdValueFieldMaskMetadata `fieldmask_oneof:"ThresholdValue"` +} + +type isAlertOperandValue_ThresholdValue interface { + isAlertOperandValue_ThresholdValue() +} + +// AlertOperandValue_ThresholdValue_StringValue selects StringValue for AlertOperandValue.ThresholdValue. +type AlertOperandValue_ThresholdValue_StringValue struct { + StringValue string `fieldmask:"string_value"` +} + +func (*AlertOperandValue_ThresholdValue_StringValue) isAlertOperandValue_ThresholdValue() {} + +// AlertOperandValue_ThresholdValue_DoubleValue selects DoubleValue for AlertOperandValue.ThresholdValue. +type AlertOperandValue_ThresholdValue_DoubleValue struct { + DoubleValue float64 `fieldmask:"double_value"` +} + +func (*AlertOperandValue_ThresholdValue_DoubleValue) isAlertOperandValue_ThresholdValue() {} + +// AlertOperandValue_ThresholdValue_BoolValue selects BoolValue for AlertOperandValue.ThresholdValue. +type AlertOperandValue_ThresholdValue_BoolValue struct { + BoolValue bool `fieldmask:"bool_value"` +} + +func (*AlertOperandValue_ThresholdValue_BoolValue) isAlertOperandValue_ThresholdValue() {} + +type alertOperandValueThresholdValueFieldMaskMetadata struct { + *AlertOperandValue_ThresholdValue_StringValue + *AlertOperandValue_ThresholdValue_DoubleValue + *AlertOperandValue_ThresholdValue_BoolValue +} + +type CreateAlertRequest struct { + Alert *CreateAlertRequestAlert + // If true, automatically resolve alert display name conflicts. Otherwise, fail + // the request if the alert's display name conflicts with an existing alert's + // display name. + AutoResolveDisplayName *bool +} + +type CreateAlertRequestAlert struct { + // UUID identifying the alert. + Id *string + // The display name of the alert. + DisplayName *string + // UUID of the query attached to the alert. + QueryId *string + // Current state of the alert's trigger status. This field is set to UNKNOWN if + // the alert has not yet been evaluated or ran into an error during the last + // evaluation. + State AlertState + // Number of seconds an alert must wait after being triggered to rearm itself. + // After rearming, it can be triggered again. If 0 or not specified, the alert + // will not be triggered again. + SecondsToRetrigger *int + // The workspace state of the alert. Used for tracking trashed status. + LifecycleState LifecycleState + // Timestamp when the alert was last triggered, if the alert has been triggered + // before. + TriggerTime *types.Time + // Custom body of alert notification, if it exists. See + // [here](/sql/user/alerts/index.html) for custom templating instructions. + CustomBody *string + // Custom subject of alert notification, if it exists. This can include email + // subject entries and Slack notification headers, for example. See + // [here](/sql/user/alerts/index.html) for custom templating instructions. + CustomSubject *string + // Trigger conditions of the alert. + Condition *AlertCondition + // The owner's username. This field is set to "Unavailable" if the user has been + // deleted. + OwnerUserName *string + // The workspace path of the folder containing the alert. + ParentPath *string + // The timestamp indicating when the alert was created. + CreateTime *types.Time + // The timestamp indicating when the alert was updated. + UpdateTime *types.Time + // Whether to notify alert subscribers when alert returns back to normal. + NotifyOnOk *bool +} + +// Represents an empty message, similar to google.protobuf.Empty, which is not +// available in the firm right now.. +type Empty struct { +} + +type GetAlertRequest struct { + Id *string +} + +type ListAlertsRequest struct { + PageToken *string + PageSize *int +} + +type ListAlertsResponse struct { + Results []ListAlertsResponseAlert + NextPageToken *string +} + +type ListAlertsResponseAlert struct { + // UUID identifying the alert. + Id *string + // The display name of the alert. + DisplayName *string + // UUID of the query attached to the alert. + QueryId *string + // Current state of the alert's trigger status. This field is set to UNKNOWN if + // the alert has not yet been evaluated or ran into an error during the last + // evaluation. + State AlertState + // Number of seconds an alert must wait after being triggered to rearm itself. + // After rearming, it can be triggered again. If 0 or not specified, the alert + // will not be triggered again. + SecondsToRetrigger *int + // The workspace state of the alert. Used for tracking trashed status. + LifecycleState LifecycleState + // Timestamp when the alert was last triggered, if the alert has been triggered + // before. + TriggerTime *types.Time + // Custom body of alert notification, if it exists. See + // [here](/sql/user/alerts/index.html) for custom templating instructions. + CustomBody *string + // Custom subject of alert notification, if it exists. This can include email + // subject entries and Slack notification headers, for example. See + // [here](/sql/user/alerts/index.html) for custom templating instructions. + CustomSubject *string + // Trigger conditions of the alert. + Condition *AlertCondition + // The owner's username. This field is set to "Unavailable" if the user has been + // deleted. + OwnerUserName *string + // The workspace path of the folder containing the alert. + ParentPath *string + // The timestamp indicating when the alert was created. + CreateTime *types.Time + // The timestamp indicating when the alert was updated. + UpdateTime *types.Time + // Whether to notify alert subscribers when alert returns back to normal. + NotifyOnOk *bool +} + +type TrashAlertRequest struct { + Id *string +} + +type UpdateAlertRequest struct { + Alert *UpdateAlertRequestAlert + UpdateMask *types.FieldMask[UpdateAlertRequestAlert] + Id *string + // If true, automatically resolve alert display name conflicts. Otherwise, fail + // the request if the alert's display name conflicts with an existing alert's + // display name. + AutoResolveDisplayName *bool +} + +type UpdateAlertRequestAlert struct { + // UUID identifying the alert. + Id *string `fieldmask:"id"` + // The display name of the alert. + DisplayName *string `fieldmask:"display_name"` + // UUID of the query attached to the alert. + QueryId *string `fieldmask:"query_id"` + // Current state of the alert's trigger status. This field is set to UNKNOWN if + // the alert has not yet been evaluated or ran into an error during the last + // evaluation. + State AlertState `fieldmask:"state"` + // Number of seconds an alert must wait after being triggered to rearm itself. + // After rearming, it can be triggered again. If 0 or not specified, the alert + // will not be triggered again. + SecondsToRetrigger *int `fieldmask:"seconds_to_retrigger"` + // The workspace state of the alert. Used for tracking trashed status. + LifecycleState LifecycleState `fieldmask:"lifecycle_state"` + // Timestamp when the alert was last triggered, if the alert has been triggered + // before. + TriggerTime *types.Time `fieldmask:"trigger_time"` + // Custom body of alert notification, if it exists. See + // [here](/sql/user/alerts/index.html) for custom templating instructions. + CustomBody *string `fieldmask:"custom_body"` + // Custom subject of alert notification, if it exists. This can include email + // subject entries and Slack notification headers, for example. See + // [here](/sql/user/alerts/index.html) for custom templating instructions. + CustomSubject *string `fieldmask:"custom_subject"` + // Trigger conditions of the alert. + Condition *AlertCondition `fieldmask:"condition"` + // The owner's username. This field is set to "Unavailable" if the user has been + // deleted. + OwnerUserName *string `fieldmask:"owner_user_name"` + // The workspace path of the folder containing the alert. + ParentPath *string `fieldmask:"parent_path"` + // The timestamp indicating when the alert was created. + CreateTime *types.Time `fieldmask:"create_time"` + // The timestamp indicating when the alert was updated. + UpdateTime *types.Time `fieldmask:"update_time"` + // Whether to notify alert subscribers when alert returns back to normal. + NotifyOnOk *bool `fieldmask:"notify_on_ok"` +} diff --git a/alerts/v1/wire.go b/alerts/v1/wire.go new file mode 100755 index 0000000..e168297 --- /dev/null +++ b/alerts/v1/wire.go @@ -0,0 +1,497 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package alerts + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type alertWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + QueryId *string `json:"query_id,omitempty"` + State AlertState `json:"state,omitempty"` + SecondsToRetrigger *int `json:"seconds_to_retrigger,omitempty"` + LifecycleState LifecycleState `json:"lifecycle_state,omitempty"` + TriggerTime *types.Time `json:"trigger_time,omitempty"` + CustomBody *string `json:"custom_body,omitempty"` + CustomSubject *string `json:"custom_subject,omitempty"` + Condition *alertConditionWire `json:"condition,omitempty"` + OwnerUserName *string `json:"owner_user_name,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + NotifyOnOk *bool `json:"notify_on_ok,omitempty"` +} + +func alertFromWire(w *alertWire) (*Alert, error) { + if w == nil { + return nil, nil + } + conditionPublicValue, err := alertConditionFromWire(w.Condition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.Condition", err) + } + return &Alert{ + Id: w.Id, + DisplayName: w.DisplayName, + QueryId: w.QueryId, + State: w.State, + SecondsToRetrigger: w.SecondsToRetrigger, + LifecycleState: w.LifecycleState, + TriggerTime: w.TriggerTime, + CustomBody: w.CustomBody, + CustomSubject: w.CustomSubject, + Condition: conditionPublicValue, + OwnerUserName: w.OwnerUserName, + ParentPath: w.ParentPath, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + NotifyOnOk: w.NotifyOnOk, + }, nil +} + +type alertConditionWire struct { + Op AlertOperator `json:"op,omitempty"` + Operand *alertOperandWire `json:"operand,omitempty"` + Threshold *alertOperandWire `json:"threshold,omitempty"` + EmptyResultState AlertState `json:"empty_result_state,omitempty"` +} + +func alertConditionToWire(v *AlertCondition) (*alertConditionWire, error) { + if v == nil { + return nil, nil + } + operandWireValue, err := alertOperandToWire(v.Operand) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertCondition.Operand", err) + } + thresholdWireValue, err := alertOperandToWire(v.Threshold) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertCondition.Threshold", err) + } + return &alertConditionWire{ + Op: v.Op, + Operand: operandWireValue, + Threshold: thresholdWireValue, + EmptyResultState: v.EmptyResultState, + }, nil +} + +func alertConditionFromWire(w *alertConditionWire) (*AlertCondition, error) { + if w == nil { + return nil, nil + } + operandPublicValue, err := alertOperandFromWire(w.Operand) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertCondition.Operand", err) + } + thresholdPublicValue, err := alertOperandFromWire(w.Threshold) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertCondition.Threshold", err) + } + return &AlertCondition{ + Op: w.Op, + Operand: operandPublicValue, + Threshold: thresholdPublicValue, + EmptyResultState: w.EmptyResultState, + }, nil +} + +type alertOperandWire struct { + Value *alertOperandValueWire `json:"value,omitempty"` + Column *alertOperandColumnWire `json:"column,omitempty"` +} + +func alertOperandToWire(v *AlertOperand) (*alertOperandWire, error) { + if v == nil { + return nil, nil + } + var operandValueWire *alertOperandValueWire + var operandColumnWire *alertOperandColumnWire + switch value := v.Operand.(type) { + case nil: + case *AlertOperand_Operand_Value: + if value != nil { + operandValueConverted, err := alertOperandValueToWire(&value.Value) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertOperand.Operand.Value", err) + } + operandValueWire = operandValueConverted + } + case *AlertOperand_Operand_Column: + if value != nil { + operandColumnConverted, err := alertOperandColumnToWire(&value.Column) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertOperand.Operand.Column", err) + } + operandColumnWire = operandColumnConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AlertOperand.Operand", value) + } + return &alertOperandWire{ + Value: operandValueWire, + Column: operandColumnWire, + }, nil +} + +func alertOperandFromWire(w *alertOperandWire) (*AlertOperand, error) { + if w == nil { + return nil, nil + } + operandMembers := 0 + if w.Value != nil { + operandMembers++ + } + if w.Column != nil { + operandMembers++ + } + if operandMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AlertOperand.Operand") + } + var operandSelection isAlertOperand_Operand + switch { + case w.Value != nil: + operandValueConverted, err := alertOperandValueFromWire(w.Value) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertOperand.Operand.Value", err) + } + operandSelection = &AlertOperand_Operand_Value{Value: *operandValueConverted} + case w.Column != nil: + operandColumnConverted, err := alertOperandColumnFromWire(w.Column) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertOperand.Operand.Column", err) + } + operandSelection = &AlertOperand_Operand_Column{Column: *operandColumnConverted} + } + return &AlertOperand{ + Operand: operandSelection, + }, nil +} + +type alertOperandColumnWire struct { + Name *string `json:"name,omitempty"` +} + +func alertOperandColumnToWire(v *AlertOperandColumn) (*alertOperandColumnWire, error) { + if v == nil { + return nil, nil + } + return &alertOperandColumnWire{ + Name: v.Name, + }, nil +} + +func alertOperandColumnFromWire(w *alertOperandColumnWire) (*AlertOperandColumn, error) { + if w == nil { + return nil, nil + } + return &AlertOperandColumn{ + Name: w.Name, + }, nil +} + +type alertOperandValueWire struct { + StringValue *string `json:"string_value,omitempty"` + DoubleValue *float64 `json:"double_value,omitempty"` + BoolValue *bool `json:"bool_value,omitempty"` +} + +func alertOperandValueToWire(v *AlertOperandValue) (*alertOperandValueWire, error) { + if v == nil { + return nil, nil + } + var thresholdValueStringValueWire *string + var thresholdValueDoubleValueWire *float64 + var thresholdValueBoolValueWire *bool + switch value := v.ThresholdValue.(type) { + case nil: + case *AlertOperandValue_ThresholdValue_StringValue: + if value != nil { + thresholdValueStringValueWire = new(value.StringValue) + } + case *AlertOperandValue_ThresholdValue_DoubleValue: + if value != nil { + thresholdValueDoubleValueWire = new(value.DoubleValue) + } + case *AlertOperandValue_ThresholdValue_BoolValue: + if value != nil { + thresholdValueBoolValueWire = new(value.BoolValue) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AlertOperandValue.ThresholdValue", value) + } + return &alertOperandValueWire{ + StringValue: thresholdValueStringValueWire, + DoubleValue: thresholdValueDoubleValueWire, + BoolValue: thresholdValueBoolValueWire, + }, nil +} + +func alertOperandValueFromWire(w *alertOperandValueWire) (*AlertOperandValue, error) { + if w == nil { + return nil, nil + } + thresholdValueMembers := 0 + if w.StringValue != nil { + thresholdValueMembers++ + } + if w.DoubleValue != nil { + thresholdValueMembers++ + } + if w.BoolValue != nil { + thresholdValueMembers++ + } + if thresholdValueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AlertOperandValue.ThresholdValue") + } + var thresholdValueSelection isAlertOperandValue_ThresholdValue + switch { + case w.StringValue != nil: + thresholdValueSelection = &AlertOperandValue_ThresholdValue_StringValue{StringValue: *w.StringValue} + case w.DoubleValue != nil: + thresholdValueSelection = &AlertOperandValue_ThresholdValue_DoubleValue{DoubleValue: *w.DoubleValue} + case w.BoolValue != nil: + thresholdValueSelection = &AlertOperandValue_ThresholdValue_BoolValue{BoolValue: *w.BoolValue} + } + return &AlertOperandValue{ + ThresholdValue: thresholdValueSelection, + }, nil +} + +type createAlertRequestWire struct { + Alert *createAlertRequestAlertWire `json:"alert,omitempty"` + AutoResolveDisplayName *bool `json:"auto_resolve_display_name,omitempty"` +} + +func createAlertRequestToWire(v *CreateAlertRequest) (*createAlertRequestWire, error) { + if v == nil { + return nil, nil + } + alertWireValue, err := createAlertRequestAlertToWire(v.Alert) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAlertRequest.Alert", err) + } + return &createAlertRequestWire{ + Alert: alertWireValue, + AutoResolveDisplayName: v.AutoResolveDisplayName, + }, nil +} + +type createAlertRequestAlertWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + QueryId *string `json:"query_id,omitempty"` + State AlertState `json:"state,omitempty"` + SecondsToRetrigger *int `json:"seconds_to_retrigger,omitempty"` + LifecycleState LifecycleState `json:"lifecycle_state,omitempty"` + TriggerTime *types.Time `json:"trigger_time,omitempty"` + CustomBody *string `json:"custom_body,omitempty"` + CustomSubject *string `json:"custom_subject,omitempty"` + Condition *alertConditionWire `json:"condition,omitempty"` + OwnerUserName *string `json:"owner_user_name,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + NotifyOnOk *bool `json:"notify_on_ok,omitempty"` +} + +func createAlertRequestAlertToWire(v *CreateAlertRequestAlert) (*createAlertRequestAlertWire, error) { + if v == nil { + return nil, nil + } + conditionWireValue, err := alertConditionToWire(v.Condition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAlertRequestAlert.Condition", err) + } + return &createAlertRequestAlertWire{ + Id: v.Id, + DisplayName: v.DisplayName, + QueryId: v.QueryId, + State: v.State, + SecondsToRetrigger: v.SecondsToRetrigger, + LifecycleState: v.LifecycleState, + TriggerTime: v.TriggerTime, + CustomBody: v.CustomBody, + CustomSubject: v.CustomSubject, + Condition: conditionWireValue, + OwnerUserName: v.OwnerUserName, + ParentPath: v.ParentPath, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + NotifyOnOk: v.NotifyOnOk, + }, nil +} + +type listAlertsRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listAlertsRequestToWire(v *ListAlertsRequest) (*listAlertsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAlertsRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listAlertsResponseWire struct { + Results []listAlertsResponseAlertWire `json:"results,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listAlertsResponseFromWire(w *listAlertsResponseWire) (*ListAlertsResponse, error) { + if w == nil { + return nil, nil + } + resultsPublicValue, err := convertSlice(w.Results, listAlertsResponseAlertFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAlertsResponse.Results", err) + } + return &ListAlertsResponse{ + Results: resultsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listAlertsResponseAlertWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + QueryId *string `json:"query_id,omitempty"` + State AlertState `json:"state,omitempty"` + SecondsToRetrigger *int `json:"seconds_to_retrigger,omitempty"` + LifecycleState LifecycleState `json:"lifecycle_state,omitempty"` + TriggerTime *types.Time `json:"trigger_time,omitempty"` + CustomBody *string `json:"custom_body,omitempty"` + CustomSubject *string `json:"custom_subject,omitempty"` + Condition *alertConditionWire `json:"condition,omitempty"` + OwnerUserName *string `json:"owner_user_name,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + NotifyOnOk *bool `json:"notify_on_ok,omitempty"` +} + +func listAlertsResponseAlertFromWire(w *listAlertsResponseAlertWire) (*ListAlertsResponseAlert, error) { + if w == nil { + return nil, nil + } + conditionPublicValue, err := alertConditionFromWire(w.Condition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAlertsResponseAlert.Condition", err) + } + return &ListAlertsResponseAlert{ + Id: w.Id, + DisplayName: w.DisplayName, + QueryId: w.QueryId, + State: w.State, + SecondsToRetrigger: w.SecondsToRetrigger, + LifecycleState: w.LifecycleState, + TriggerTime: w.TriggerTime, + CustomBody: w.CustomBody, + CustomSubject: w.CustomSubject, + Condition: conditionPublicValue, + OwnerUserName: w.OwnerUserName, + ParentPath: w.ParentPath, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + NotifyOnOk: w.NotifyOnOk, + }, nil +} + +type updateAlertRequestWire struct { + Alert *updateAlertRequestAlertWire `json:"alert,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` + Id *string `json:"id,omitempty"` + AutoResolveDisplayName *bool `json:"auto_resolve_display_name,omitempty"` +} + +func updateAlertRequestToWire(v *UpdateAlertRequest) (*updateAlertRequestWire, error) { + if v == nil { + return nil, nil + } + alertWireValue, err := updateAlertRequestAlertToWire(v.Alert) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAlertRequest.Alert", err) + } + return &updateAlertRequestWire{ + Alert: alertWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + Id: v.Id, + AutoResolveDisplayName: v.AutoResolveDisplayName, + }, nil +} + +type updateAlertRequestAlertWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + QueryId *string `json:"query_id,omitempty"` + State AlertState `json:"state,omitempty"` + SecondsToRetrigger *int `json:"seconds_to_retrigger,omitempty"` + LifecycleState LifecycleState `json:"lifecycle_state,omitempty"` + TriggerTime *types.Time `json:"trigger_time,omitempty"` + CustomBody *string `json:"custom_body,omitempty"` + CustomSubject *string `json:"custom_subject,omitempty"` + Condition *alertConditionWire `json:"condition,omitempty"` + OwnerUserName *string `json:"owner_user_name,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + NotifyOnOk *bool `json:"notify_on_ok,omitempty"` +} + +func updateAlertRequestAlertToWire(v *UpdateAlertRequestAlert) (*updateAlertRequestAlertWire, error) { + if v == nil { + return nil, nil + } + conditionWireValue, err := alertConditionToWire(v.Condition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAlertRequestAlert.Condition", err) + } + return &updateAlertRequestAlertWire{ + Id: v.Id, + DisplayName: v.DisplayName, + QueryId: v.QueryId, + State: v.State, + SecondsToRetrigger: v.SecondsToRetrigger, + LifecycleState: v.LifecycleState, + TriggerTime: v.TriggerTime, + CustomBody: v.CustomBody, + CustomSubject: v.CustomSubject, + Condition: conditionWireValue, + OwnerUserName: v.OwnerUserName, + ParentPath: v.ParentPath, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + NotifyOnOk: v.NotifyOnOk, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/alerts/v2/client.go b/alerts/v2/client.go new file mode 100755 index 0000000..14f9d32 --- /dev/null +++ b/alerts/v2/client.go @@ -0,0 +1,447 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package alerts + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/alerts/internal" + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create Alert +func (c *internalClient) CreateAlert(ctx context.Context, req *CreateAlertRequest, opts ...call.Option) (*Alert, error) { + wireReq, err := createAlertRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Alert) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/alerts" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Alert + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp alertWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = alertFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an alert. +func (c *internalClient) GetAlert(ctx context.Context, req *GetAlertRequest, opts ...call.Option) (*Alert, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/alerts/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Alert + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp alertWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = alertFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a list of alerts accessible to the user, ordered by creation time. +func (c *internalClient) ListAlerts(ctx context.Context, req *ListAlertsRequest, opts ...call.Option) (*ListAlertsResponse, error) { + wireReq, err := listAlertsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/alerts" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAlertsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAlertsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAlertsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListAlertsIter returns an iterator that iterates +// over the results of ListAlerts. +// +// For example: +// +// for item, err := range c.ListAlertsIter(ctx, &ListAlertsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListAlerts call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListAlerts directly. +func (c *internalClient) ListAlertsIter(ctx context.Context, req *ListAlertsRequest, opts ...call.Option) iter.Seq2[*Alert, error] { + return func(yield func(*Alert, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListAlertsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListAlerts(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Alerts { + if !yield(&resp.Alerts[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Moves an alert to the trash. Trashed alerts immediately disappear from list +// views, and can no longer trigger. You can restore a trashed alert through the +// UI. A trashed alert is permanently deleted after 30 days. +func (c *internalClient) TrashAlert(ctx context.Context, req *TrashAlertRequest, opts ...call.Option) (*Empty, error) { + wireReq, err := trashAlertRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/alerts/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "purge", wireReq.Purge); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Empty + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &Empty{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update alert +func (c *internalClient) UpdateAlert(ctx context.Context, req *UpdateAlertRequest, opts ...call.Option) (*Alert, error) { + wireReq, err := updateAlertRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Alert) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/alerts/") + pb.singleSegment(*req.Alert.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Alert + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp alertWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = alertFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/alerts/v2/genhelper.go b/alerts/v2/genhelper.go new file mode 100755 index 0000000..b39ebc3 --- /dev/null +++ b/alerts/v2/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package alerts + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/alerts/v2/model.go b/alerts/v2/model.go new file mode 100755 index 0000000..5f03318 --- /dev/null +++ b/alerts/v2/model.go @@ -0,0 +1,342 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package alerts + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type Aggregation string + +const ( + Aggregation_Unspecified Aggregation = "" + Aggregation_Sum Aggregation = "SUM" + Aggregation_Count Aggregation = "COUNT" + Aggregation_CountDistinct Aggregation = "COUNT_DISTINCT" + Aggregation_Avg Aggregation = "AVG" + Aggregation_Median Aggregation = "MEDIAN" + Aggregation_Min Aggregation = "MIN" + Aggregation_Max Aggregation = "MAX" + Aggregation_Stddev Aggregation = "STDDEV" +) + +// UNSPECIFIED - default unspecify value for proto enum, do not use it in the +// code UNKNOWN - alert not yet evaluated TRIGGERED - alert is triggered OK - +// alert is not triggered ERROR - alert evaluation failed +type AlertEvaluationState string + +const ( + AlertEvaluationState_Unspecified AlertEvaluationState = "" + // Deprecated. Please avoid using `UNKNOWN` as empty_result_state. + AlertEvaluationState_Unknown AlertEvaluationState = "UNKNOWN" + AlertEvaluationState_Triggered AlertEvaluationState = "TRIGGERED" + AlertEvaluationState_Ok AlertEvaluationState = "OK" + AlertEvaluationState_Error AlertEvaluationState = "ERROR" +) + +type AlertLifecycleState string + +const ( + AlertLifecycleState_Unspecified AlertLifecycleState = "" + AlertLifecycleState_Active AlertLifecycleState = "ACTIVE" + AlertLifecycleState_Deleted AlertLifecycleState = "DELETED" +) + +type ComparisonOperator string + +const ( + ComparisonOperator_Unspecified ComparisonOperator = "" + ComparisonOperator_LessThan ComparisonOperator = "LESS_THAN" + ComparisonOperator_GreaterThan ComparisonOperator = "GREATER_THAN" + ComparisonOperator_Equal ComparisonOperator = "EQUAL" + ComparisonOperator_NotEqual ComparisonOperator = "NOT_EQUAL" + ComparisonOperator_GreaterThanOrEqual ComparisonOperator = "GREATER_THAN_OR_EQUAL" + ComparisonOperator_LessThanOrEqual ComparisonOperator = "LESS_THAN_OR_EQUAL" + ComparisonOperator_IsNull ComparisonOperator = "IS_NULL" + ComparisonOperator_IsNotNull ComparisonOperator = "IS_NOT_NULL" +) + +type SchedulePauseStatus string + +const ( + SchedulePauseStatus_Unspecified SchedulePauseStatus = "" + SchedulePauseStatus_Unpaused SchedulePauseStatus = "UNPAUSED" + SchedulePauseStatus_Paused SchedulePauseStatus = "PAUSED" +) + +type Alert struct { + // UUID identifying the alert. + Id *string `fieldmask:"id"` + // The display name of the alert. + DisplayName *string `fieldmask:"display_name"` + // The owner's username. This field is set to "Unavailable" if the user has been + // deleted. + OwnerUserName *string `fieldmask:"owner_user_name"` + // The timestamp indicating when the alert was created. + CreateTime *types.Time `fieldmask:"create_time"` + // The timestamp indicating when the alert was updated. + UpdateTime *types.Time `fieldmask:"update_time"` + // The workspace path of the folder containing the alert. Can only be set on + // create, and cannot be updated. + ParentPath *string `fieldmask:"parent_path"` + // Text of the query to be run. + QueryText *string `fieldmask:"query_text"` + // ID of the SQL warehouse attached to the alert. + WarehouseId *string `fieldmask:"warehouse_id"` + // The run as username or application ID of service principal. On Create and + // Update, this field can be set to application ID of an active service + // principal. Setting this field requires the servicePrincipal/user role. + // Deprecated: Use `run_as` field instead. This field will be removed in a + // future release. + RunAsUserName *string `fieldmask:"run_as_user_name"` + Evaluation *AlertEvaluation `fieldmask:"evaluation"` + Schedule *CronSchedule `fieldmask:"schedule"` + // Indicates whether the query is trashed. + LifecycleState AlertLifecycleState `fieldmask:"lifecycle_state"` + // Custom summary for the alert. support mustache template. + CustomSummary *string `fieldmask:"custom_summary"` + // Custom description for the alert. support mustache template. + CustomDescription *string `fieldmask:"custom_description"` + // Specifies the identity that will be used to run the alert. This field allows + // you to configure alerts to run as a specific user or service principal. - For + // user identity: Set `user_name` to the email of an active workspace user. + // Users can only set this to their own email. - For service principal: Set + // `service_principal_name` to the application ID. Requires the + // `servicePrincipal/user` role. If not specified, the alert will run as the + // request user. + RunAs *AlertRunAs `fieldmask:"run_as"` + // The actual identity that will be used to execute the alert. This is an + // output-only field that shows the resolved run-as identity after applying + // permissions and defaults. + EffectiveRunAs *AlertRunAs `fieldmask:"effective_run_as"` + // Query parameters bound when executing the alert query, referenced in the + // query text with `:name` syntax. Static values only. + Parameters []AlertStatementParameter `fieldmask:"parameters"` +} + +type AlertEvaluation struct { + // Source column from result to use to evaluate alert + Source *AlertOperandColumn `fieldmask:"source"` + // Operator used for comparison in alert evaluation. + ComparisonOperator ComparisonOperator `fieldmask:"comparison_operator"` + // Threshold to user for alert evaluation, can be a column or a value. + Threshold *AlertOperand `fieldmask:"threshold"` + // User or Notification Destination to notify when alert is triggered. + Notification *AlertNotification `fieldmask:"notification"` + // Latest state of alert evaluation. + State AlertEvaluationState `fieldmask:"state"` + // Timestamp of the last evaluation. + LastEvaluatedAt *types.Time `fieldmask:"last_evaluated_at"` + // Alert state if result is empty. Please avoid setting this field to be + // `UNKNOWN` because `UNKNOWN` state is planned to be deprecated. + EmptyResultState AlertEvaluationState `fieldmask:"empty_result_state"` +} + +type AlertNotification struct { + Subscriptions []AlertSubscription `fieldmask:"subscriptions"` + // Number of seconds an alert waits after being triggered before it is allowed + // to send another notification. If set to 0 or omitted, the alert will not send + // any further notifications after the first trigger Setting this value to 1 + // allows the alert to send a notification on every evaluation where the + // condition is met, effectively making it always retrigger for notification + // purposes. + RetriggerSeconds *int `fieldmask:"retrigger_seconds"` + // Whether to notify alert subscribers when alert returns back to normal. + NotifyOnOk *bool `fieldmask:"notify_on_ok"` +} + +type AlertOperand struct { + // Only one of the following fields may be set, depending on the type of + // operand/threshold. + Operand isAlertOperand_Operand + _ [0]alertOperandOperandFieldMaskMetadata `fieldmask_oneof:"Operand"` +} + +type isAlertOperand_Operand interface { + isAlertOperand_Operand() +} + +// AlertOperand_Operand_Column selects Column for AlertOperand.Operand. +type AlertOperand_Operand_Column struct { + Column AlertOperandColumn `fieldmask:"column"` +} + +func (*AlertOperand_Operand_Column) isAlertOperand_Operand() {} + +// AlertOperand_Operand_Value selects Value for AlertOperand.Operand. +type AlertOperand_Operand_Value struct { + Value AlertOperandValue `fieldmask:"value"` +} + +func (*AlertOperand_Operand_Value) isAlertOperand_Operand() {} + +type alertOperandOperandFieldMaskMetadata struct { + *AlertOperand_Operand_Column + *AlertOperand_Operand_Value +} + +type AlertOperandColumn struct { + Name *string `fieldmask:"name"` + Display *string `fieldmask:"display"` + // If not set, the behavior is equivalent to using `First row` in the UI. + Aggregation Aggregation `fieldmask:"aggregation"` +} + +type AlertOperandValue struct { + // Only one of the following fields may be set, depending on the type of + // threshold value. + Value isAlertOperandValue_Value + _ [0]alertOperandValueValueFieldMaskMetadata `fieldmask_oneof:"Value"` +} + +type isAlertOperandValue_Value interface { + isAlertOperandValue_Value() +} + +// AlertOperandValue_Value_StringValue selects StringValue for AlertOperandValue.Value. +type AlertOperandValue_Value_StringValue struct { + StringValue string `fieldmask:"string_value"` +} + +func (*AlertOperandValue_Value_StringValue) isAlertOperandValue_Value() {} + +// AlertOperandValue_Value_DoubleValue selects DoubleValue for AlertOperandValue.Value. +type AlertOperandValue_Value_DoubleValue struct { + DoubleValue float64 `fieldmask:"double_value"` +} + +func (*AlertOperandValue_Value_DoubleValue) isAlertOperandValue_Value() {} + +// AlertOperandValue_Value_BoolValue selects BoolValue for AlertOperandValue.Value. +type AlertOperandValue_Value_BoolValue struct { + BoolValue bool `fieldmask:"bool_value"` +} + +func (*AlertOperandValue_Value_BoolValue) isAlertOperandValue_Value() {} + +type alertOperandValueValueFieldMaskMetadata struct { + *AlertOperandValue_Value_StringValue + *AlertOperandValue_Value_DoubleValue + *AlertOperandValue_Value_BoolValue +} + +type AlertRunAs struct { + Identity isAlertRunAs_Identity + _ [0]alertRunAsIdentityFieldMaskMetadata `fieldmask_oneof:"Identity"` +} + +type isAlertRunAs_Identity interface { + isAlertRunAs_Identity() +} + +// AlertRunAs_Identity_UserName selects UserName for AlertRunAs.Identity. +// The email of an active workspace user. Can only set this field to their own +// email. +type AlertRunAs_Identity_UserName struct { + UserName string `fieldmask:"user_name"` +} + +func (*AlertRunAs_Identity_UserName) isAlertRunAs_Identity() {} + +// AlertRunAs_Identity_ServicePrincipalName selects ServicePrincipalName for AlertRunAs.Identity. +// Application ID of an active service principal. Setting this field requires +// the `servicePrincipal/user` role. +type AlertRunAs_Identity_ServicePrincipalName struct { + ServicePrincipalName string `fieldmask:"service_principal_name"` +} + +func (*AlertRunAs_Identity_ServicePrincipalName) isAlertRunAs_Identity() {} + +type alertRunAsIdentityFieldMaskMetadata struct { + *AlertRunAs_Identity_UserName + *AlertRunAs_Identity_ServicePrincipalName +} + +// Redash-owned copy of the internal StatementParameter for the external AlertV2 +// API. The internal `ordinal` and `args` fields are intentionally omitted: the +// public API supports only flat, named scalar parameters; complex types (ARRAY, +// MAP, STRUCT) are not supported. This mirrors SEA's public StatementParameter +// schema, see: cmdexec/sql-exec-api/proto/sql_exec_api_service.proto:763-779. +type AlertStatementParameter struct { + // The name of the parameter, referenced in the query as `:name`. + Name *string + // The bound value for the parameter, given as a string. If omitted, the value + // is interpreted as NULL. + Value *string + // The SQL data type of the parameter, e.g. STRING, INT, or DATE. Defaults to + // STRING. This is a string rather than an enum because scalar subtypes such as + // DECIMAL(10, 4) cannot be enumerated. Complex types such as ARRAY, MAP, and + // STRUCT are not supported. + Type *string +} + +type AlertSubscription struct { + SubscriptionType isAlertSubscription_SubscriptionType +} + +type isAlertSubscription_SubscriptionType interface { + isAlertSubscription_SubscriptionType() +} + +// AlertSubscription_SubscriptionType_UserEmail selects UserEmail for AlertSubscription.SubscriptionType. +type AlertSubscription_SubscriptionType_UserEmail struct { + UserEmail string +} + +func (*AlertSubscription_SubscriptionType_UserEmail) isAlertSubscription_SubscriptionType() {} + +// AlertSubscription_SubscriptionType_DestinationId selects DestinationId for AlertSubscription.SubscriptionType. +type AlertSubscription_SubscriptionType_DestinationId struct { + DestinationId string +} + +func (*AlertSubscription_SubscriptionType_DestinationId) isAlertSubscription_SubscriptionType() {} + +type CreateAlertRequest struct { + Alert *Alert +} + +type CronSchedule struct { + // A cron expression using quartz syntax that specifies the schedule for this + // pipeline. Should use the quartz format described here: + // http://www.quartz-scheduler.org/documentation/quartz-2.1.7/tutorials/tutorial-lesson-06.html + QuartzCronSchedule *string `fieldmask:"quartz_cron_schedule"` + // A Java timezone id. The schedule will be resolved using this timezone. This + // will be combined with the quartz_cron_schedule to determine the schedule. See + // https://docs.databricks.com/sql/language-manual/sql-ref-syntax-aux-conf-mgmt-set-timezone.html + // for details. + TimezoneId *string `fieldmask:"timezone_id"` + // Indicate whether this schedule is paused or not. + PauseStatus SchedulePauseStatus `fieldmask:"pause_status"` +} + +// Represents an empty message, similar to google.protobuf.Empty, which is not +// available in the firm right now.. +type Empty struct { +} + +type GetAlertRequest struct { + Id *string +} + +type ListAlertsRequest struct { + PageToken *string + PageSize *int +} + +type ListAlertsResponse struct { + Alerts []Alert + NextPageToken *string +} + +type TrashAlertRequest struct { + Id *string + // Whether to permanently delete the alert. If not set, the alert will only be + // soft deleted. + Purge *bool +} + +type UpdateAlertRequest struct { + Alert *Alert + UpdateMask *types.FieldMask[Alert] +} diff --git a/alerts/v2/wire.go b/alerts/v2/wire.go new file mode 100755 index 0000000..8b3c329 --- /dev/null +++ b/alerts/v2/wire.go @@ -0,0 +1,663 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package alerts + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type alertWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + OwnerUserName *string `json:"owner_user_name,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + QueryText *string `json:"query_text,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + RunAsUserName *string `json:"run_as_user_name,omitempty"` + Evaluation *alertEvaluationWire `json:"evaluation,omitempty"` + Schedule *cronScheduleWire `json:"schedule,omitempty"` + LifecycleState AlertLifecycleState `json:"lifecycle_state,omitempty"` + CustomSummary *string `json:"custom_summary,omitempty"` + CustomDescription *string `json:"custom_description,omitempty"` + RunAs *alertRunAsWire `json:"run_as,omitempty"` + EffectiveRunAs *alertRunAsWire `json:"effective_run_as,omitempty"` + Parameters []alertStatementParameterWire `json:"parameters,omitempty"` +} + +func alertToWire(v *Alert) (*alertWire, error) { + if v == nil { + return nil, nil + } + evaluationWireValue, err := alertEvaluationToWire(v.Evaluation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.Evaluation", err) + } + scheduleWireValue, err := cronScheduleToWire(v.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.Schedule", err) + } + runAsWireValue, err := alertRunAsToWire(v.RunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.RunAs", err) + } + effectiveRunAsWireValue, err := alertRunAsToWire(v.EffectiveRunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.EffectiveRunAs", err) + } + parametersWireValue, err := convertSlice(v.Parameters, alertStatementParameterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.Parameters", err) + } + return &alertWire{ + Id: v.Id, + DisplayName: v.DisplayName, + OwnerUserName: v.OwnerUserName, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + ParentPath: v.ParentPath, + QueryText: v.QueryText, + WarehouseId: v.WarehouseId, + RunAsUserName: v.RunAsUserName, + Evaluation: evaluationWireValue, + Schedule: scheduleWireValue, + LifecycleState: v.LifecycleState, + CustomSummary: v.CustomSummary, + CustomDescription: v.CustomDescription, + RunAs: runAsWireValue, + EffectiveRunAs: effectiveRunAsWireValue, + Parameters: parametersWireValue, + }, nil +} + +func alertFromWire(w *alertWire) (*Alert, error) { + if w == nil { + return nil, nil + } + evaluationPublicValue, err := alertEvaluationFromWire(w.Evaluation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.Evaluation", err) + } + schedulePublicValue, err := cronScheduleFromWire(w.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.Schedule", err) + } + runAsPublicValue, err := alertRunAsFromWire(w.RunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.RunAs", err) + } + effectiveRunAsPublicValue, err := alertRunAsFromWire(w.EffectiveRunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.EffectiveRunAs", err) + } + parametersPublicValue, err := convertSlice(w.Parameters, alertStatementParameterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Alert.Parameters", err) + } + return &Alert{ + Id: w.Id, + DisplayName: w.DisplayName, + OwnerUserName: w.OwnerUserName, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + ParentPath: w.ParentPath, + QueryText: w.QueryText, + WarehouseId: w.WarehouseId, + RunAsUserName: w.RunAsUserName, + Evaluation: evaluationPublicValue, + Schedule: schedulePublicValue, + LifecycleState: w.LifecycleState, + CustomSummary: w.CustomSummary, + CustomDescription: w.CustomDescription, + RunAs: runAsPublicValue, + EffectiveRunAs: effectiveRunAsPublicValue, + Parameters: parametersPublicValue, + }, nil +} + +type alertEvaluationWire struct { + Source *alertOperandColumnWire `json:"source,omitempty"` + ComparisonOperator ComparisonOperator `json:"comparison_operator,omitempty"` + Threshold *alertOperandWire `json:"threshold,omitempty"` + Notification *alertNotificationWire `json:"notification,omitempty"` + State AlertEvaluationState `json:"state,omitempty"` + LastEvaluatedAt *types.Time `json:"last_evaluated_at,omitempty"` + EmptyResultState AlertEvaluationState `json:"empty_result_state,omitempty"` +} + +func alertEvaluationToWire(v *AlertEvaluation) (*alertEvaluationWire, error) { + if v == nil { + return nil, nil + } + sourceWireValue, err := alertOperandColumnToWire(v.Source) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertEvaluation.Source", err) + } + thresholdWireValue, err := alertOperandToWire(v.Threshold) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertEvaluation.Threshold", err) + } + notificationWireValue, err := alertNotificationToWire(v.Notification) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertEvaluation.Notification", err) + } + return &alertEvaluationWire{ + Source: sourceWireValue, + ComparisonOperator: v.ComparisonOperator, + Threshold: thresholdWireValue, + Notification: notificationWireValue, + State: v.State, + LastEvaluatedAt: v.LastEvaluatedAt, + EmptyResultState: v.EmptyResultState, + }, nil +} + +func alertEvaluationFromWire(w *alertEvaluationWire) (*AlertEvaluation, error) { + if w == nil { + return nil, nil + } + sourcePublicValue, err := alertOperandColumnFromWire(w.Source) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertEvaluation.Source", err) + } + thresholdPublicValue, err := alertOperandFromWire(w.Threshold) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertEvaluation.Threshold", err) + } + notificationPublicValue, err := alertNotificationFromWire(w.Notification) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertEvaluation.Notification", err) + } + return &AlertEvaluation{ + Source: sourcePublicValue, + ComparisonOperator: w.ComparisonOperator, + Threshold: thresholdPublicValue, + Notification: notificationPublicValue, + State: w.State, + LastEvaluatedAt: w.LastEvaluatedAt, + EmptyResultState: w.EmptyResultState, + }, nil +} + +type alertNotificationWire struct { + Subscriptions []alertSubscriptionWire `json:"subscriptions,omitempty"` + RetriggerSeconds *int `json:"retrigger_seconds,omitempty"` + NotifyOnOk *bool `json:"notify_on_ok,omitempty"` +} + +func alertNotificationToWire(v *AlertNotification) (*alertNotificationWire, error) { + if v == nil { + return nil, nil + } + subscriptionsWireValue, err := convertSlice(v.Subscriptions, alertSubscriptionToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertNotification.Subscriptions", err) + } + return &alertNotificationWire{ + Subscriptions: subscriptionsWireValue, + RetriggerSeconds: v.RetriggerSeconds, + NotifyOnOk: v.NotifyOnOk, + }, nil +} + +func alertNotificationFromWire(w *alertNotificationWire) (*AlertNotification, error) { + if w == nil { + return nil, nil + } + subscriptionsPublicValue, err := convertSlice(w.Subscriptions, alertSubscriptionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertNotification.Subscriptions", err) + } + return &AlertNotification{ + Subscriptions: subscriptionsPublicValue, + RetriggerSeconds: w.RetriggerSeconds, + NotifyOnOk: w.NotifyOnOk, + }, nil +} + +type alertOperandWire struct { + Column *alertOperandColumnWire `json:"column,omitempty"` + Value *alertOperandValueWire `json:"value,omitempty"` +} + +func alertOperandToWire(v *AlertOperand) (*alertOperandWire, error) { + if v == nil { + return nil, nil + } + var operandColumnWire *alertOperandColumnWire + var operandValueWire *alertOperandValueWire + switch value := v.Operand.(type) { + case nil: + case *AlertOperand_Operand_Column: + if value != nil { + operandColumnConverted, err := alertOperandColumnToWire(&value.Column) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertOperand.Operand.Column", err) + } + operandColumnWire = operandColumnConverted + } + case *AlertOperand_Operand_Value: + if value != nil { + operandValueConverted, err := alertOperandValueToWire(&value.Value) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertOperand.Operand.Value", err) + } + operandValueWire = operandValueConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AlertOperand.Operand", value) + } + return &alertOperandWire{ + Column: operandColumnWire, + Value: operandValueWire, + }, nil +} + +func alertOperandFromWire(w *alertOperandWire) (*AlertOperand, error) { + if w == nil { + return nil, nil + } + operandMembers := 0 + if w.Column != nil { + operandMembers++ + } + if w.Value != nil { + operandMembers++ + } + if operandMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AlertOperand.Operand") + } + var operandSelection isAlertOperand_Operand + switch { + case w.Column != nil: + operandColumnConverted, err := alertOperandColumnFromWire(w.Column) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertOperand.Operand.Column", err) + } + operandSelection = &AlertOperand_Operand_Column{Column: *operandColumnConverted} + case w.Value != nil: + operandValueConverted, err := alertOperandValueFromWire(w.Value) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertOperand.Operand.Value", err) + } + operandSelection = &AlertOperand_Operand_Value{Value: *operandValueConverted} + } + return &AlertOperand{ + Operand: operandSelection, + }, nil +} + +type alertOperandColumnWire struct { + Name *string `json:"name,omitempty"` + Display *string `json:"display,omitempty"` + Aggregation Aggregation `json:"aggregation,omitempty"` +} + +func alertOperandColumnToWire(v *AlertOperandColumn) (*alertOperandColumnWire, error) { + if v == nil { + return nil, nil + } + return &alertOperandColumnWire{ + Name: v.Name, + Display: v.Display, + Aggregation: v.Aggregation, + }, nil +} + +func alertOperandColumnFromWire(w *alertOperandColumnWire) (*AlertOperandColumn, error) { + if w == nil { + return nil, nil + } + return &AlertOperandColumn{ + Name: w.Name, + Display: w.Display, + Aggregation: w.Aggregation, + }, nil +} + +type alertOperandValueWire struct { + StringValue *string `json:"string_value,omitempty"` + DoubleValue *float64 `json:"double_value,omitempty"` + BoolValue *bool `json:"bool_value,omitempty"` +} + +func alertOperandValueToWire(v *AlertOperandValue) (*alertOperandValueWire, error) { + if v == nil { + return nil, nil + } + var valueStringValueWire *string + var valueDoubleValueWire *float64 + var valueBoolValueWire *bool + switch value := v.Value.(type) { + case nil: + case *AlertOperandValue_Value_StringValue: + if value != nil { + valueStringValueWire = new(value.StringValue) + } + case *AlertOperandValue_Value_DoubleValue: + if value != nil { + valueDoubleValueWire = new(value.DoubleValue) + } + case *AlertOperandValue_Value_BoolValue: + if value != nil { + valueBoolValueWire = new(value.BoolValue) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AlertOperandValue.Value", value) + } + return &alertOperandValueWire{ + StringValue: valueStringValueWire, + DoubleValue: valueDoubleValueWire, + BoolValue: valueBoolValueWire, + }, nil +} + +func alertOperandValueFromWire(w *alertOperandValueWire) (*AlertOperandValue, error) { + if w == nil { + return nil, nil + } + valueMembers := 0 + if w.StringValue != nil { + valueMembers++ + } + if w.DoubleValue != nil { + valueMembers++ + } + if w.BoolValue != nil { + valueMembers++ + } + if valueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AlertOperandValue.Value") + } + var valueSelection isAlertOperandValue_Value + switch { + case w.StringValue != nil: + valueSelection = &AlertOperandValue_Value_StringValue{StringValue: *w.StringValue} + case w.DoubleValue != nil: + valueSelection = &AlertOperandValue_Value_DoubleValue{DoubleValue: *w.DoubleValue} + case w.BoolValue != nil: + valueSelection = &AlertOperandValue_Value_BoolValue{BoolValue: *w.BoolValue} + } + return &AlertOperandValue{ + Value: valueSelection, + }, nil +} + +type alertRunAsWire struct { + UserName *string `json:"user_name,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` +} + +func alertRunAsToWire(v *AlertRunAs) (*alertRunAsWire, error) { + if v == nil { + return nil, nil + } + var identityUserNameWire *string + var identityServicePrincipalNameWire *string + switch value := v.Identity.(type) { + case nil: + case *AlertRunAs_Identity_UserName: + if value != nil { + identityUserNameWire = new(value.UserName) + } + case *AlertRunAs_Identity_ServicePrincipalName: + if value != nil { + identityServicePrincipalNameWire = new(value.ServicePrincipalName) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AlertRunAs.Identity", value) + } + return &alertRunAsWire{ + UserName: identityUserNameWire, + ServicePrincipalName: identityServicePrincipalNameWire, + }, nil +} + +func alertRunAsFromWire(w *alertRunAsWire) (*AlertRunAs, error) { + if w == nil { + return nil, nil + } + identityMembers := 0 + if w.UserName != nil { + identityMembers++ + } + if w.ServicePrincipalName != nil { + identityMembers++ + } + if identityMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AlertRunAs.Identity") + } + var identitySelection isAlertRunAs_Identity + switch { + case w.UserName != nil: + identitySelection = &AlertRunAs_Identity_UserName{UserName: *w.UserName} + case w.ServicePrincipalName != nil: + identitySelection = &AlertRunAs_Identity_ServicePrincipalName{ServicePrincipalName: *w.ServicePrincipalName} + } + return &AlertRunAs{ + Identity: identitySelection, + }, nil +} + +type alertStatementParameterWire struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` + Type *string `json:"type,omitempty"` +} + +func alertStatementParameterToWire(v *AlertStatementParameter) (*alertStatementParameterWire, error) { + if v == nil { + return nil, nil + } + return &alertStatementParameterWire{ + Name: v.Name, + Value: v.Value, + Type: v.Type, + }, nil +} + +func alertStatementParameterFromWire(w *alertStatementParameterWire) (*AlertStatementParameter, error) { + if w == nil { + return nil, nil + } + return &AlertStatementParameter{ + Name: w.Name, + Value: w.Value, + Type: w.Type, + }, nil +} + +type alertSubscriptionWire struct { + UserEmail *string `json:"user_email,omitempty"` + DestinationId *string `json:"destination_id,omitempty"` +} + +func alertSubscriptionToWire(v *AlertSubscription) (*alertSubscriptionWire, error) { + if v == nil { + return nil, nil + } + var subscriptionTypeUserEmailWire *string + var subscriptionTypeDestinationIdWire *string + switch value := v.SubscriptionType.(type) { + case nil: + case *AlertSubscription_SubscriptionType_UserEmail: + if value != nil { + subscriptionTypeUserEmailWire = new(value.UserEmail) + } + case *AlertSubscription_SubscriptionType_DestinationId: + if value != nil { + subscriptionTypeDestinationIdWire = new(value.DestinationId) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AlertSubscription.SubscriptionType", value) + } + return &alertSubscriptionWire{ + UserEmail: subscriptionTypeUserEmailWire, + DestinationId: subscriptionTypeDestinationIdWire, + }, nil +} + +func alertSubscriptionFromWire(w *alertSubscriptionWire) (*AlertSubscription, error) { + if w == nil { + return nil, nil + } + subscriptionTypeMembers := 0 + if w.UserEmail != nil { + subscriptionTypeMembers++ + } + if w.DestinationId != nil { + subscriptionTypeMembers++ + } + if subscriptionTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AlertSubscription.SubscriptionType") + } + var subscriptionTypeSelection isAlertSubscription_SubscriptionType + switch { + case w.UserEmail != nil: + subscriptionTypeSelection = &AlertSubscription_SubscriptionType_UserEmail{UserEmail: *w.UserEmail} + case w.DestinationId != nil: + subscriptionTypeSelection = &AlertSubscription_SubscriptionType_DestinationId{DestinationId: *w.DestinationId} + } + return &AlertSubscription{ + SubscriptionType: subscriptionTypeSelection, + }, nil +} + +type createAlertRequestWire struct { + Alert *alertWire `json:"alert,omitempty"` +} + +func createAlertRequestToWire(v *CreateAlertRequest) (*createAlertRequestWire, error) { + if v == nil { + return nil, nil + } + alertWireValue, err := alertToWire(v.Alert) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAlertRequest.Alert", err) + } + return &createAlertRequestWire{ + Alert: alertWireValue, + }, nil +} + +type cronScheduleWire struct { + QuartzCronSchedule *string `json:"quartz_cron_schedule,omitempty"` + TimezoneId *string `json:"timezone_id,omitempty"` + PauseStatus SchedulePauseStatus `json:"pause_status,omitempty"` +} + +func cronScheduleToWire(v *CronSchedule) (*cronScheduleWire, error) { + if v == nil { + return nil, nil + } + return &cronScheduleWire{ + QuartzCronSchedule: v.QuartzCronSchedule, + TimezoneId: v.TimezoneId, + PauseStatus: v.PauseStatus, + }, nil +} + +func cronScheduleFromWire(w *cronScheduleWire) (*CronSchedule, error) { + if w == nil { + return nil, nil + } + return &CronSchedule{ + QuartzCronSchedule: w.QuartzCronSchedule, + TimezoneId: w.TimezoneId, + PauseStatus: w.PauseStatus, + }, nil +} + +type listAlertsRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listAlertsRequestToWire(v *ListAlertsRequest) (*listAlertsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAlertsRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listAlertsResponseWire struct { + Alerts []alertWire `json:"alerts,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listAlertsResponseFromWire(w *listAlertsResponseWire) (*ListAlertsResponse, error) { + if w == nil { + return nil, nil + } + alertsPublicValue, err := convertSlice(w.Alerts, alertFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAlertsResponse.Alerts", err) + } + return &ListAlertsResponse{ + Alerts: alertsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type trashAlertRequestWire struct { + Id *string `json:"id,omitempty"` + Purge *bool `json:"purge,omitempty"` +} + +func trashAlertRequestToWire(v *TrashAlertRequest) (*trashAlertRequestWire, error) { + if v == nil { + return nil, nil + } + return &trashAlertRequestWire{ + Id: v.Id, + Purge: v.Purge, + }, nil +} + +type updateAlertRequestWire struct { + Alert *alertWire `json:"alert,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateAlertRequestToWire(v *UpdateAlertRequest) (*updateAlertRequestWire, error) { + if v == nil { + return nil, nil + } + alertWireValue, err := alertToWire(v.Alert) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAlertRequest.Alert", err) + } + return &updateAlertRequestWire{ + Alert: alertWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/apps/.package.json b/apps/.package.json new file mode 100644 index 0000000..ab7e449 --- /dev/null +++ b/apps/.package.json @@ -0,0 +1,3 @@ +{ + "package": "apps" +} diff --git a/apps/CHANGELOG.md b/apps/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/apps/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/apps/README.md b/apps/README.md new file mode 100644 index 0000000..ca243c8 --- /dev/null +++ b/apps/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/apps + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/apps@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/apps/v1" + +client, err := apps.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/apps/go.mod b/apps/go.mod new file mode 100644 index 0000000..bef3476 --- /dev/null +++ b/apps/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/apps + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/apps/internal/version.go b/apps/internal/version.go new file mode 100644 index 0000000..743ccf9 --- /dev/null +++ b/apps/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-apps" + +const Version = "0.0.1-dev.1" diff --git a/apps/v1/client.go b/apps/v1/client.go new file mode 100755 index 0000000..b4b124b --- /dev/null +++ b/apps/v1/client.go @@ -0,0 +1,2627 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package apps + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/apps/internal" + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates an app update and starts the update process. The update process is +// asynchronous and the status of the update can be checked with the +// GetAppUpdate method. +func (c *internalClient) asyncUpdateAppBase(ctx context.Context, req *AsyncUpdateAppRequest, opts ...call.Option) (*AppUpdate, error) { + wireReq, err := asyncUpdateAppRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.AppName) + pb.literal("/update") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AppUpdate + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appUpdateWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appUpdateFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates an app update and starts the update process. The update process is +// asynchronous and the status of the update can be checked with the +// GetAppUpdate method. +func (c *internalClient) AsyncUpdateApp(ctx context.Context, req *AsyncUpdateAppRequest, opts ...call.Option) (*AsyncUpdateAppWaiter, error) { + if req.AppName == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "AppName") + } + capturedAppName := *req.AppName + _, err := c.asyncUpdateAppBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &AsyncUpdateAppWaiter{ + poll: c.GetAppUpdate, + appName: capturedAppName, + }, nil +} + +// AsyncUpdateAppWaiter tracks the state of the operation started by AsyncUpdateApp. +type AsyncUpdateAppWaiter struct { + poll func(context.Context, *GetAppUpdateRequest, ...call.Option) (*AppUpdate, error) + appName string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *AsyncUpdateAppWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetAppUpdateRequest{ + AppName: &w.appName, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.Status == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "Status") + } + status := pollResp.Status.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case AppUpdate_UpdateStatus_UpdateState_Succeeded, AppUpdate_UpdateStatus_UpdateState_Failed: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *AsyncUpdateAppWaiter) Wait(ctx context.Context, opts ...lro.Option) (*AppUpdate, error) { + var result *AppUpdate + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetAppUpdateRequest{ + AppName: &w.appName, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.Status == nil { + return fmt.Errorf("response field %q required for polling is missing", "Status") + } + status := pollResp.Status.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case AppUpdate_UpdateStatus_UpdateState_Succeeded: + result = pollResp + return nil + case AppUpdate_UpdateStatus_UpdateState_Failed: + message := "(no message)" + if pollResp.Status != nil && pollResp.Status.Message != nil { + message = fmt.Sprintf("%v", *pollResp.Status.Message) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Creates a new app. +func (c *internalClient) createAppBase(ctx context.Context, req *CreateAppRequest, opts ...call.Option) (*App, error) { + wireReq, err := createAppRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.App) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/apps" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "no_compute", wireReq.NoCompute); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *App + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new app. +func (c *internalClient) CreateApp(ctx context.Context, req *CreateAppRequest, opts ...call.Option) (*CreateAppWaiter, error) { + resp, err := c.createAppBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.Name == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "Name") + } + return &CreateAppWaiter{ + poll: c.GetApp, + name: *resp.Name, + }, nil +} + +// CreateAppWaiter tracks the state of the operation started by CreateApp. +type CreateAppWaiter struct { + poll func(context.Context, *GetAppRequest, ...call.Option) (*App, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateAppWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetAppRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.ComputeStatus == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "ComputeStatus") + } + status := pollResp.ComputeStatus.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ComputeStatus_ComputeState_Active, ComputeStatus_ComputeState_Error, ComputeStatus_ComputeState_Stopped: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateAppWaiter) Wait(ctx context.Context, opts ...lro.Option) (*App, error) { + var result *App + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetAppRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.ComputeStatus == nil { + return fmt.Errorf("response field %q required for polling is missing", "ComputeStatus") + } + status := pollResp.ComputeStatus.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ComputeStatus_ComputeState_Active: + result = pollResp + return nil + case ComputeStatus_ComputeState_Error, ComputeStatus_ComputeState_Stopped: + message := "(no message)" + if pollResp.ComputeStatus != nil && pollResp.ComputeStatus.Message != nil { + message = fmt.Sprintf("%v", *pollResp.ComputeStatus.Message) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Creates an app deployment for the app with the supplied name. +func (c *internalClient) createAppDeploymentBase(ctx context.Context, req *CreateAppDeploymentRequest, opts ...call.Option) (*AppDeployment, error) { + wireReq, err := createAppDeploymentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.AppDeployment) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.AppName) + pb.literal("/deployments") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AppDeployment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appDeploymentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appDeploymentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates an app deployment for the app with the supplied name. +func (c *internalClient) CreateAppDeployment(ctx context.Context, req *CreateAppDeploymentRequest, opts ...call.Option) (*CreateAppDeploymentWaiter, error) { + if req.AppName == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "AppName") + } + capturedAppName := *req.AppName + resp, err := c.createAppDeploymentBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.DeploymentId == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "DeploymentId") + } + return &CreateAppDeploymentWaiter{ + poll: c.GetAppDeployment, + deploymentId: *resp.DeploymentId, + appName: capturedAppName, + }, nil +} + +// CreateAppDeploymentWaiter tracks the state of the operation started by CreateAppDeployment. +type CreateAppDeploymentWaiter struct { + poll func(context.Context, *GetAppDeploymentRequest, ...call.Option) (*AppDeployment, error) + deploymentId string + appName string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateAppDeploymentWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetAppDeploymentRequest{ + DeploymentId: &w.deploymentId, + AppName: &w.appName, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.Status == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "Status") + } + status := pollResp.Status.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case AppDeployment_State_Succeeded, AppDeployment_State_Failed: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateAppDeploymentWaiter) Wait(ctx context.Context, opts ...lro.Option) (*AppDeployment, error) { + var result *AppDeployment + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetAppDeploymentRequest{ + DeploymentId: &w.deploymentId, + AppName: &w.appName, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.Status == nil { + return fmt.Errorf("response field %q required for polling is missing", "Status") + } + status := pollResp.Status.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case AppDeployment_State_Succeeded: + result = pollResp + return nil + case AppDeployment_State_Failed: + message := "(no message)" + if pollResp.Status != nil && pollResp.Status.Message != nil { + message = fmt.Sprintf("%v", *pollResp.Status.Message) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Creates a custom template. +func (c *internalClient) CreateCustomTemplate(ctx context.Context, req *CreateCustomTemplateRequest, opts ...call.Option) (*CustomTemplate, error) { + wireReq, err := createCustomTemplateRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Template) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/apps-settings/templates" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomTemplate + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customTemplateWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customTemplateFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new app space. +func (c *internalClient) createSpaceBase(ctx context.Context, req *CreateSpaceRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createSpaceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Space) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/app-spaces" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new app space. +func (c *internalClient) CreateSpace(ctx context.Context, req *CreateSpaceRequest, opts ...call.Option) (*CreateSpaceOperation, error) { + operation, err := c.createSpaceBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateSpaceOperation{ + operation: operation, + getOperation: c.getSpaceOperation, + }, nil +} + +// CreateSpaceOperation tracks the state of the long-running operation started by CreateSpace. +type CreateSpaceOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateSpaceOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateSpaceOperation) Metadata() (*Space, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata spaceWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := spaceFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateSpaceOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateSpaceOperation) Wait(ctx context.Context, opts ...lro.Option) (*Space, error) { + var result *Space + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response spaceWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = spaceFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Deletes an app. +func (c *internalClient) DeleteApp(ctx context.Context, req *DeleteAppRequest, opts ...call.Option) (*App, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *App + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the thumbnail for an app. +func (c *internalClient) DeleteAppThumbnail(ctx context.Context, req *DeleteAppThumbnailRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.Name) + pb.literal("/thumbnail") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Deletes the custom template with the specified name. +func (c *internalClient) DeleteCustomTemplate(ctx context.Context, req *DeleteCustomTemplateRequest, opts ...call.Option) (*CustomTemplate, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps-settings/templates/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomTemplate + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customTemplateWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customTemplateFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes an app space. +func (c *internalClient) deleteSpaceBase(ctx context.Context, req *DeleteSpaceRequest, opts ...call.Option) (*Operation, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/app-spaces/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes an app space. +func (c *internalClient) DeleteSpace(ctx context.Context, req *DeleteSpaceRequest, opts ...call.Option) (*DeleteSpaceOperation, error) { + operation, err := c.deleteSpaceBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &DeleteSpaceOperation{ + operation: operation, + getOperation: c.getSpaceOperation, + }, nil +} + +// DeleteSpaceOperation tracks the state of the long-running operation started by DeleteSpace. +type DeleteSpaceOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *DeleteSpaceOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *DeleteSpaceOperation) Metadata() (*Space, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata spaceWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := spaceFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *DeleteSpaceOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *DeleteSpaceOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Retrieves information for the app with the supplied name. +func (c *internalClient) GetApp(ctx context.Context, req *GetAppRequest, opts ...call.Option) (*App, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *App + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves information for the app deployment with the supplied name and +// deployment id. +func (c *internalClient) GetAppDeployment(ctx context.Context, req *GetAppDeploymentRequest, opts ...call.Option) (*AppDeployment, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.AppName) + pb.literal("/deployments/") + pb.singleSegment(*req.DeploymentId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AppDeployment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appDeploymentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appDeploymentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the status of an app update. +func (c *internalClient) GetAppUpdate(ctx context.Context, req *GetAppUpdateRequest, opts ...call.Option) (*AppUpdate, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.AppName) + pb.literal("/update") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AppUpdate + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appUpdateWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appUpdateFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the custom template with the specified name. +func (c *internalClient) GetCustomTemplate(ctx context.Context, req *GetCustomTemplateRequest, opts ...call.Option) (*CustomTemplate, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps-settings/templates/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomTemplate + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customTemplateWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customTemplateFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves information for the app space with the supplied name. +func (c *internalClient) GetSpace(ctx context.Context, req *GetSpaceRequest, opts ...call.Option) (*Space, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/app-spaces/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Space + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp spaceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = spaceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the status of an app space update operation. +func (c *internalClient) getSpaceOperation(ctx context.Context, req *GetOperationRequest, opts ...call.Option) (*Operation, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/app-spaces/") + pb.singleSegment(*req.Name) + pb.literal("/operation") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists all app deployments for the app with the supplied name. +func (c *internalClient) ListAppDeployments(ctx context.Context, req *ListAppDeploymentsRequest, opts ...call.Option) (*ListAppDeploymentsResponse, error) { + wireReq, err := listAppDeploymentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.AppName) + pb.literal("/deployments") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAppDeploymentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAppDeploymentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAppDeploymentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListAppDeploymentsIter returns an iterator that iterates +// over the results of ListAppDeployments. +// +// For example: +// +// for item, err := range c.ListAppDeploymentsIter(ctx, &ListAppDeploymentsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListAppDeployments call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListAppDeployments directly. +func (c *internalClient) ListAppDeploymentsIter(ctx context.Context, req *ListAppDeploymentsRequest, opts ...call.Option) iter.Seq2[*AppDeployment, error] { + return func(yield func(*AppDeployment, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListAppDeploymentsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListAppDeployments(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.AppDeployments { + if !yield(&resp.AppDeployments[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Lists all apps in the workspace. +func (c *internalClient) ListApps(ctx context.Context, req *ListAppsRequest, opts ...call.Option) (*ListAppsResponse, error) { + wireReq, err := listAppsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/apps" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "space", wireReq.Space); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAppsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAppsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAppsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListAppsIter returns an iterator that iterates +// over the results of ListApps. +// +// For example: +// +// for item, err := range c.ListAppsIter(ctx, &ListAppsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListApps call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListApps directly. +func (c *internalClient) ListAppsIter(ctx context.Context, req *ListAppsRequest, opts ...call.Option) iter.Seq2[*App, error] { + return func(yield func(*App, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListAppsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListApps(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Apps { + if !yield(&resp.Apps[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Lists all custom templates in the workspace. +func (c *internalClient) ListCustomTemplates(ctx context.Context, req *ListCustomTemplatesRequest, opts ...call.Option) (*ListCustomTemplatesResponse, error) { + wireReq, err := listCustomTemplatesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/apps-settings/templates" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCustomTemplatesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCustomTemplatesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCustomTemplatesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCustomTemplatesIter returns an iterator that iterates +// over the results of ListCustomTemplates. +// +// For example: +// +// for item, err := range c.ListCustomTemplatesIter(ctx, &ListCustomTemplatesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCustomTemplates call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCustomTemplates directly. +func (c *internalClient) ListCustomTemplatesIter(ctx context.Context, req *ListCustomTemplatesRequest, opts ...call.Option) iter.Seq2[*CustomTemplate, error] { + return func(yield func(*CustomTemplate, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCustomTemplatesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCustomTemplates(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Templates { + if !yield(&resp.Templates[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Lists all app spaces in the workspace. +func (c *internalClient) ListSpaces(ctx context.Context, req *ListSpacesRequest, opts ...call.Option) (*ListSpacesResponse, error) { + wireReq, err := listSpacesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/app-spaces" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListSpacesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listSpacesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listSpacesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListSpacesIter returns an iterator that iterates +// over the results of ListSpaces. +// +// For example: +// +// for item, err := range c.ListSpacesIter(ctx, &ListSpacesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListSpaces call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListSpaces directly. +func (c *internalClient) ListSpacesIter(ctx context.Context, req *ListSpacesRequest, opts ...call.Option) iter.Seq2[*Space, error] { + return func(yield func(*Space, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListSpacesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListSpaces(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Spaces { + if !yield(&resp.Spaces[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Start the last active deployment of the app in the workspace. +func (c *internalClient) startAppBase(ctx context.Context, req *StartAppRequest, opts ...call.Option) (*App, error) { + wireReq, err := startAppRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.Name) + pb.literal("/start") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *App + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Start the last active deployment of the app in the workspace. +func (c *internalClient) StartApp(ctx context.Context, req *StartAppRequest, opts ...call.Option) (*StartAppWaiter, error) { + if req.Name == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "Name") + } + capturedName := *req.Name + _, err := c.startAppBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &StartAppWaiter{ + poll: c.GetApp, + name: capturedName, + }, nil +} + +// StartAppWaiter tracks the state of the operation started by StartApp. +type StartAppWaiter struct { + poll func(context.Context, *GetAppRequest, ...call.Option) (*App, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *StartAppWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetAppRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.ComputeStatus == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "ComputeStatus") + } + status := pollResp.ComputeStatus.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ComputeStatus_ComputeState_Active, ComputeStatus_ComputeState_Error, ComputeStatus_ComputeState_Stopped: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *StartAppWaiter) Wait(ctx context.Context, opts ...lro.Option) (*App, error) { + var result *App + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetAppRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.ComputeStatus == nil { + return fmt.Errorf("response field %q required for polling is missing", "ComputeStatus") + } + status := pollResp.ComputeStatus.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ComputeStatus_ComputeState_Active: + result = pollResp + return nil + case ComputeStatus_ComputeState_Error, ComputeStatus_ComputeState_Stopped: + message := "(no message)" + if pollResp.ComputeStatus != nil && pollResp.ComputeStatus.Message != nil { + message = fmt.Sprintf("%v", *pollResp.ComputeStatus.Message) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Stops the active deployment of the app in the workspace. +func (c *internalClient) stopAppBase(ctx context.Context, req *StopAppRequest, opts ...call.Option) (*App, error) { + wireReq, err := stopAppRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.Name) + pb.literal("/stop") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *App + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Stops the active deployment of the app in the workspace. +func (c *internalClient) StopApp(ctx context.Context, req *StopAppRequest, opts ...call.Option) (*StopAppWaiter, error) { + if req.Name == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "Name") + } + capturedName := *req.Name + _, err := c.stopAppBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &StopAppWaiter{ + poll: c.GetApp, + name: capturedName, + }, nil +} + +// StopAppWaiter tracks the state of the operation started by StopApp. +type StopAppWaiter struct { + poll func(context.Context, *GetAppRequest, ...call.Option) (*App, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *StopAppWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetAppRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.ComputeStatus == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "ComputeStatus") + } + status := pollResp.ComputeStatus.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ComputeStatus_ComputeState_Stopped, ComputeStatus_ComputeState_Error: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *StopAppWaiter) Wait(ctx context.Context, opts ...lro.Option) (*App, error) { + var result *App + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetAppRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.ComputeStatus == nil { + return fmt.Errorf("response field %q required for polling is missing", "ComputeStatus") + } + status := pollResp.ComputeStatus.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ComputeStatus_ComputeState_Stopped: + result = pollResp + return nil + case ComputeStatus_ComputeState_Error: + message := "(no message)" + if pollResp.ComputeStatus != nil && pollResp.ComputeStatus.Message != nil { + message = fmt.Sprintf("%v", *pollResp.ComputeStatus.Message) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Updates the app with the supplied name. +func (c *internalClient) UpdateApp(ctx context.Context, req *UpdateAppRequest, opts ...call.Option) (*App, error) { + wireReq, err := updateAppRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.App) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.App.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *App + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the thumbnail for an app. +func (c *internalClient) UpdateAppThumbnail(ctx context.Context, req *UpdateAppThumbnailRequest, opts ...call.Option) (*AppThumbnail, error) { + wireReq, err := updateAppThumbnailRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps/") + pb.singleSegment(*req.Name) + pb.literal("/thumbnail") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AppThumbnail + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp appThumbnailWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = appThumbnailFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the custom template with the specified name. Note that the template +// name cannot be updated. +func (c *internalClient) UpdateCustomTemplate(ctx context.Context, req *UpdateCustomTemplateRequest, opts ...call.Option) (*CustomTemplate, error) { + wireReq, err := updateCustomTemplateRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Template) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/apps-settings/templates/") + pb.singleSegment(*req.Template.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomTemplate + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customTemplateWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customTemplateFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an app space. The update process is asynchronous and the status of +// the update can be checked with the GetSpaceOperation method. +func (c *internalClient) updateSpaceBase(ctx context.Context, req *UpdateSpaceRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := updateSpaceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Space) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/app-spaces/") + pb.singleSegment(*req.Space.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an app space. The update process is asynchronous and the status of +// the update can be checked with the GetSpaceOperation method. +func (c *internalClient) UpdateSpace(ctx context.Context, req *UpdateSpaceRequest, opts ...call.Option) (*UpdateSpaceOperation, error) { + operation, err := c.updateSpaceBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &UpdateSpaceOperation{ + operation: operation, + getOperation: c.getSpaceOperation, + }, nil +} + +// UpdateSpaceOperation tracks the state of the long-running operation started by UpdateSpace. +type UpdateSpaceOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *UpdateSpaceOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *UpdateSpaceOperation) Metadata() (*SpaceUpdate, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata spaceUpdateWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := spaceUpdateFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *UpdateSpaceOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *UpdateSpaceOperation) Wait(ctx context.Context, opts ...lro.Option) (*Space, error) { + var result *Space + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response spaceWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = spaceFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} diff --git a/apps/v1/genhelper.go b/apps/v1/genhelper.go new file mode 100755 index 0000000..088db1d --- /dev/null +++ b/apps/v1/genhelper.go @@ -0,0 +1,250 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package apps + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func validateOperationName(operationName *string) error { + if operationName == nil || *operationName == "" { + return errors.New("invalid operation response: missing operation name") + } + return nil +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/apps/v1/model.go b/apps/v1/model.go new file mode 100755 index 0000000..414a3e2 --- /dev/null +++ b/apps/v1/model.go @@ -0,0 +1,1548 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package apps + +import ( + "encoding/json" + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +type ComputeSize string + +const ( + ComputeSize_Unspecified ComputeSize = "" + ComputeSize_Medium ComputeSize = "MEDIUM" + ComputeSize_Large ComputeSize = "LARGE" + ComputeSize_Xlarge ComputeSize = "XLARGE" +) + +// Error codes returned by Databricks APIs to indicate specific failure +// conditions. +type ErrorCode string + +const ( + ErrorCode_Unspecified ErrorCode = "" + // Internal error. This means that some invariants expected by the underlying + // system have been broken. This error code is reserved for serious errors, + // which generally cannot be resolved by the user. + // + // Prefer this over all kinds of detailed error messages (e.g IO_ERROR), unless + // there's some automation that relies on the custom error code. + // + // Maps to: - google.rpc.Code: INTERNAL = 13; - HTTP code: 500 Internal Server + // Error + ErrorCode_InternalError ErrorCode = "INTERNAL_ERROR" + // The service is currently unavailable. This is most likely a transient + // condition, which can be corrected by retrying with a backoff. Note that it is + // not always safe to retry non-idempotent operations. + // + // Prefer this over SERVICE_UNDER_MAINTENANCE, + // WORKSPACE_TEMPORARILY_UNAVAILABLE. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on how to pick this vs RESOURCE_EXHAUSTED. + // + // Maps to: - google.rpc.Code: UNAVAILABLE = 14; - HTTP code: 503 Service + // Unavailable + ErrorCode_TemporarilyUnavailable ErrorCode = "TEMPORARILY_UNAVAILABLE" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Indicates that an IOException has been internally + // thrown. + ErrorCode_IoError ErrorCode = "IO_ERROR" + // The request is invalid. Prefer more specific error code whenever possible. + // Also see similar recommendation for the google.rpc.Code.FAILED_PRECONDITION. + // + // Prefer this error code over MALFORMED_REQUEST, INVALID_STATE, + // UNPARSEABLE_HTTP_ERROR. + // + // Maps to: - google.rpc.Code: FAILED_PRECONDITION = 9; - HTTP code: 400 Bad + // Request + ErrorCode_BadRequest ErrorCode = "BAD_REQUEST" + // An external service is unavailable temporarily as it is being + // updated/re-deployed. Indicates gateway proxy to safely retry the request. + ErrorCode_ServiceUnderMaintenance ErrorCode = "SERVICE_UNDER_MAINTENANCE" + // A workspace is temporarily unavailable as the workspace is being re-assigned. + ErrorCode_WorkspaceTemporarilyUnavailable ErrorCode = "WORKSPACE_TEMPORARILY_UNAVAILABLE" + // The deadline expired before the operation could complete. For operations that + // change the state of the system, this error may be returned even if the + // operation has completed successfully. For example, a successful response from + // a server could have been delayed long enough for the deadline to expire. When + // possible - implementations should make sure further processing of the request + // is aborted, e.g. by throwing an exception instead of making the RPC request, + // making the database query, etc. + // + // Maps to: - google.rpc.Code: DEADLINE_EXCEEDED = 4; - HTTP code: 504 Gateway + // Timeout + ErrorCode_DeadlineExceeded ErrorCode = "DEADLINE_EXCEEDED" + // The operation was canceled by the caller. An example - client closed the + // connection without waiting for a response. + // + // Maps to: - google.rpc.Code: CANCELLED = 1; - HTTP code: 499 Client Closed + // Request + ErrorCode_Cancelled ErrorCode = "CANCELLED" + // The operation is rejected because of either rate limiting or resource quota, + // such as the client has sent too many requests recently or the client has + // allocated too many resources. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on how to pick this vs TEMPORARILY_UNAVAILABLE. + // + // Maps to: - google.rpc.Code: RESOURCE_EXHAUSTED = 8; - HTTP code: 429 Too Many + // Requests + ErrorCode_ResourceExhausted ErrorCode = "RESOURCE_EXHAUSTED" + // The operation was aborted, typically due to a concurrency issue such as a + // sequencer check failure, transaction abort, or transaction conflict. + // + // Maps to: - google.rpc.Code: ABORTED = 10; - HTTP code: 409 Conflict + ErrorCode_Aborted ErrorCode = "ABORTED" + // Operation was performed on a resource that does not exist, e.g. file or + // directory was not found. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_NotFound ErrorCode = "NOT_FOUND" + // Operation was rejected due a conflict with an existing resource, e.g. + // attempted to create file or directory that already exists. + // + // Prefer this over RESOURCE_CONFLICT. + // + // Maps to: - google.rpc.Code: ALREADY_EXISTS = 6; - HTTP code: 409 Conflict + ErrorCode_AlreadyExists ErrorCode = "ALREADY_EXISTS" + // The request does not have valid authentication (AuthN) credentials for the + // operation. + // + // Prefer this over CUSTOMER_UNAUTHORIZED, unless you need to keep consistent + // behavior with legacy code. For authorization (AuthZ) errors use + // PERMISSION_DENIED. Maps to: - google.rpc.Code: UNAUTHENTICATED = 16; - HTTP + // code: 401 Unauthorized + ErrorCode_Unauthenticated ErrorCode = "UNAUTHENTICATED" + // The service is currently unavailable. Please note that the unavailability may + // or may not be transient. That means if this is a non-transient condition, + // retrying it does not work. If the unavailability is certainly a transient + // condition, pleases use `TEMPORARILY_UNAVAILABLE` which signals its transient + // nature explicitly. An example of this error code’s use case is that when + // DNS resolution fails, the DNS resolver does not know whether it is because + // the domain name is completely wrong (non-transient situation) or the domain + // name is valid but the DNS server does not have an entry for this domain name + // yet (transient situation). Hence, `UNAVAILABLE` is suitable for this case. + // + // Maps to: - google.rpc.Code: UNAVAILABLE = 14; - HTTP code: 503 Service + // Unavailable + ErrorCode_Unavailable ErrorCode = "UNAVAILABLE" + // Supplied value for a parameter was invalid (e.g., giving a number for a + // string parameter). + // + // Maps to: - google.rpc.Code: INVALID_ARGUMENT = 3; - HTTP code: 400 Bad + // Request + ErrorCode_InvalidParameterValue ErrorCode = "INVALID_PARAMETER_VALUE" + // Indicates that the given API endpoint does not exist. Legacy, when possible - + // NOT_IMPLEMENTED should be used instead to indicate that API doesn't exist. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_EndpointNotFound ErrorCode = "ENDPOINT_NOT_FOUND" + // Indicates that the given API request was malformed. + ErrorCode_MalformedRequest ErrorCode = "MALFORMED_REQUEST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. If one or more of the inputs to a given RPC are not in + // a valid state for the action. + ErrorCode_InvalidState ErrorCode = "INVALID_STATE" + // The caller does not have permission to execute the specified operation. + // PERMISSION_DENIED must not be used for rejections caused by exhausting some + // resource, use RESOURCE_EXHAUSTED instead for those errors. PERMISSION_DENIED + // must not be used if the caller can not be identified, use + // CUSTOMER_UNAUTHORIZED instead for those errors. This error code does not + // imply the request is valid or the requested entity exists or satisfies other + // pre-conditions. + // + // Maps to: - google.rpc.Code: PERMISSION_DENIED = 7; - HTTP code: 403 Forbidden + ErrorCode_PermissionDenied ErrorCode = "PERMISSION_DENIED" + // NOTE: Deprecated due to inconsistent mapping in legacy code, see + // https://docs.google.com/document/d/17TZIKX_Y39cJMBr333lc-d5dTvvBLSu3DPUyGU5eMJg/edit?disco=AAAAzVGt6FA. + // Prefer using NOT_FOUND or PERMISSION_DENIED. + // + // If a given user/entity is trying to use a feature which has been disabled. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_FeatureDisabled ErrorCode = "FEATURE_DISABLED" + // The request does not have valid authentication (AuthN) credentials for the + // operation. + // + // For authentication (AuthN) errors prefer using UNAUTHENTICATED, unless you + // need to keep consistent behavior with legacy code. For authorization (AuthZ) + // errors use PERMISSION_DENIED. + // + // Important: name is confusing, this error code is for authentication (AuthN) + // errors, not authorization (AuthZ) errors. It maps to 401 Unauthorized and + // suffers from the same confusing naming. See + // https://datatracker.ietf.org/doc/html/rfc7235#section-3.1 - "[...] status + // code indicates that the request has not been applied because it lacks valid + // authentication credentials for the target resource. [...] If the request + // included authentication credentials, then the 401 response indicates that + // authorization has been refused for those credentials." + // + // Also, see https://stackoverflow.com/a/6937030/16352922, it covers it pretty + // well. + // + // Maps to: - google.rpc.Code: UNAUTHENTICATED = 16; - HTTP code: 401 + // Unauthorized + ErrorCode_CustomerUnauthorized ErrorCode = "CUSTOMER_UNAUTHORIZED" + // The operation is rejected because of request rate limit, for example rate + // limiting applied to users, workspaces, IP addresses, etc. + // + // Prefer a more generic RESOURCE_EXHAUSTED for the new use cases. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on the rate limiting vs throttling. + // + // Maps to: - google.rpc.Code: RESOURCE_EXHAUSTED = 8; - HTTP code: 429 Too Many + // Requests + ErrorCode_RequestLimitExceeded ErrorCode = "REQUEST_LIMIT_EXCEEDED" + // Indicates API request was rejected due a conflict with an existing resource. + ErrorCode_ResourceConflict ErrorCode = "RESOURCE_CONFLICT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Indicates that the HTTP response cannot be correctly + // deserialized. This currently is only used in DUST test clients, and not by + // any real service code. + ErrorCode_UnparseableHttpError ErrorCode = "UNPARSEABLE_HTTP_ERROR" + // The operation is not implemented or is not supported/enabled in this service. + // + // Maps to: - google.rpc.Code: UNIMPLEMENTED = 12; - HTTP code: 501 Not + // Implemented + ErrorCode_NotImplemented ErrorCode = "NOT_IMPLEMENTED" + // Unrecoverable data loss or corruption. + // + // One of the major use cases is to indicate that server failed to validate the + // integrity of the request. This error can occur when the checksum specified in + // the `X-Databricks-Checksum` request header (or trailer) doesn't match the + // actual request content checksum. + // + // Note, in case of the severe corruption that results in a malformed request, + // the server may send a generic `400 Bad Request` response rather than sending + // this error code. + // + // Maps to: - google.rpc.Code: DATA_LOSS = 15; - HTTP code: 500 Internal Server + // Error + ErrorCode_DataLoss ErrorCode = "DATA_LOSS" + // If the user attempts to perform an invalid state transition on a shard. + ErrorCode_InvalidStateTransition ErrorCode = "INVALID_STATE_TRANSITION" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Unable to perform the operation because the shard was + // locked by some other operation. + ErrorCode_CouldNotAcquireLock ErrorCode = "COULD_NOT_ACQUIRE_LOCK" + // NOTE: Deprecated, prefer using ALREADY_EXISTS. Unlike ALREADY_EXISTS - this + // maps to HTTP code 400 Bad Request due to legacy reasons, remapping will be a + // backwards incompatible change. + // + // Operation was performed on a resource that already exists. + ErrorCode_ResourceAlreadyExists ErrorCode = "RESOURCE_ALREADY_EXISTS" + // NOTE: Deprecated, prefer using NOT_FOUND - see the note for the + // RESOURCE_ALREADY_EXISTS, because this pair of codes is related and + // RESOURCE_ALREADY_EXISTS has bad mapping to the HTTP codes we added new error + // codes NOT_FOUND and ALREADY_EXISTS, and recommend to use them instead. + // + // Operation was performed on a resource that does not exist. + ErrorCode_ResourceDoesNotExist ErrorCode = "RESOURCE_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_QuotaExceeded ErrorCode = "QUOTA_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxBlockSizeExceeded ErrorCode = "MAX_BLOCK_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxReadSizeExceeded ErrorCode = "MAX_READ_SIZE_EXCEEDED" + ErrorCode_PartialDelete ErrorCode = "PARTIAL_DELETE" + ErrorCode_MaxListSizeExceeded ErrorCode = "MAX_LIST_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DryRunFailed ErrorCode = "DRY_RUN_FAILED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Cluster request was rejected because it would exceed a + // resource limit. + ErrorCode_ResourceLimitExceeded ErrorCode = "RESOURCE_LIMIT_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DirectoryNotEmpty ErrorCode = "DIRECTORY_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DirectoryProtected ErrorCode = "DIRECTORY_PROTECTED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxNotebookSizeExceeded ErrorCode = "MAX_NOTEBOOK_SIZE_EXCEEDED" + ErrorCode_MaxChildNodeSizeExceeded ErrorCode = "MAX_CHILD_NODE_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SearchQueryTooLong ErrorCode = "SEARCH_QUERY_TOO_LONG" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SearchQueryTooShort ErrorCode = "SEARCH_QUERY_TOO_SHORT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ManagedResourceGroupDoesNotExist ErrorCode = "MANAGED_RESOURCE_GROUP_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_PermissionNotPropagated ErrorCode = "PERMISSION_NOT_PROPAGATED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DeploymentTimeout ErrorCode = "DEPLOYMENT_TIMEOUT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitConflict ErrorCode = "GIT_CONFLICT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitUnknownRef ErrorCode = "GIT_UNKNOWN_REF" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitSensitiveTokenDetected ErrorCode = "GIT_SENSITIVE_TOKEN_DETECTED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitUrlNotOnAllowList ErrorCode = "GIT_URL_NOT_ON_ALLOW_LIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitRemoteError ErrorCode = "GIT_REMOTE_ERROR" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProjectsOperationTimeout ErrorCode = "PROJECTS_OPERATION_TIMEOUT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_IpynbFileInRepo ErrorCode = "IPYNB_FILE_IN_REPO" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_InsecurePartnerResponse ErrorCode = "INSECURE_PARTNER_RESPONSE" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MalformedPartnerResponse ErrorCode = "MALFORMED_PARTNER_RESPONSE" + ErrorCode_MetastoreDoesNotExist ErrorCode = "METASTORE_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DacDoesNotExist ErrorCode = "DAC_DOES_NOT_EXIST" + ErrorCode_CatalogDoesNotExist ErrorCode = "CATALOG_DOES_NOT_EXIST" + ErrorCode_SchemaDoesNotExist ErrorCode = "SCHEMA_DOES_NOT_EXIST" + ErrorCode_TableDoesNotExist ErrorCode = "TABLE_DOES_NOT_EXIST" + ErrorCode_ShareDoesNotExist ErrorCode = "SHARE_DOES_NOT_EXIST" + ErrorCode_RecipientDoesNotExist ErrorCode = "RECIPIENT_DOES_NOT_EXIST" + ErrorCode_StorageCredentialDoesNotExist ErrorCode = "STORAGE_CREDENTIAL_DOES_NOT_EXIST" + ErrorCode_ExternalLocationDoesNotExist ErrorCode = "EXTERNAL_LOCATION_DOES_NOT_EXIST" + ErrorCode_PrincipalDoesNotExist ErrorCode = "PRINCIPAL_DOES_NOT_EXIST" + ErrorCode_ProviderDoesNotExist ErrorCode = "PROVIDER_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MetastoreAlreadyExists ErrorCode = "METASTORE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DacAlreadyExists ErrorCode = "DAC_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_CatalogAlreadyExists ErrorCode = "CATALOG_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SchemaAlreadyExists ErrorCode = "SCHEMA_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_TableAlreadyExists ErrorCode = "TABLE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ShareAlreadyExists ErrorCode = "SHARE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_RecipientAlreadyExists ErrorCode = "RECIPIENT_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_StorageCredentialAlreadyExists ErrorCode = "STORAGE_CREDENTIAL_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ExternalLocationAlreadyExists ErrorCode = "EXTERNAL_LOCATION_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProviderAlreadyExists ErrorCode = "PROVIDER_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_CatalogNotEmpty ErrorCode = "CATALOG_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SchemaNotEmpty ErrorCode = "SCHEMA_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MetastoreNotEmpty ErrorCode = "METASTORE_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProviderShareNotAccessible ErrorCode = "PROVIDER_SHARE_NOT_ACCESSIBLE" +) + +type SpaceUpdateState string + +const ( + SpaceUpdateState_Unspecified SpaceUpdateState = "" + SpaceUpdateState_NotUpdated SpaceUpdateState = "NOT_UPDATED" + SpaceUpdateState_InProgress SpaceUpdateState = "IN_PROGRESS" + SpaceUpdateState_Succeeded SpaceUpdateState = "SUCCEEDED" + SpaceUpdateState_Failed SpaceUpdateState = "FAILED" +) + +type AppDeployment_Mode string + +const ( + AppDeployment_Mode_Unspecified AppDeployment_Mode = "" + AppDeployment_Mode_Snapshot AppDeployment_Mode = "SNAPSHOT" + AppDeployment_Mode_AutoSync AppDeployment_Mode = "AUTO_SYNC" +) + +type AppDeployment_State string + +const ( + AppDeployment_State_Unspecified AppDeployment_State = "" + AppDeployment_State_Succeeded AppDeployment_State = "SUCCEEDED" + AppDeployment_State_Failed AppDeployment_State = "FAILED" + AppDeployment_State_InProgress AppDeployment_State = "IN_PROGRESS" + AppDeployment_State_Cancelled AppDeployment_State = "CANCELLED" +) + +type AppManifest_AppResourceExperimentSpec_ExperimentPermission string + +const ( + AppManifest_AppResourceExperimentSpec_ExperimentPermission_Unspecified AppManifest_AppResourceExperimentSpec_ExperimentPermission = "" + AppManifest_AppResourceExperimentSpec_ExperimentPermission_CanManage AppManifest_AppResourceExperimentSpec_ExperimentPermission = "CAN_MANAGE" + AppManifest_AppResourceExperimentSpec_ExperimentPermission_CanEdit AppManifest_AppResourceExperimentSpec_ExperimentPermission = "CAN_EDIT" + AppManifest_AppResourceExperimentSpec_ExperimentPermission_CanRead AppManifest_AppResourceExperimentSpec_ExperimentPermission = "CAN_READ" +) + +type AppManifest_AppResourceJobSpec_JobPermission string + +const ( + AppManifest_AppResourceJobSpec_JobPermission_Unspecified AppManifest_AppResourceJobSpec_JobPermission = "" + AppManifest_AppResourceJobSpec_JobPermission_CanManage AppManifest_AppResourceJobSpec_JobPermission = "CAN_MANAGE" + AppManifest_AppResourceJobSpec_JobPermission_IsOwner AppManifest_AppResourceJobSpec_JobPermission = "IS_OWNER" + AppManifest_AppResourceJobSpec_JobPermission_CanManageRun AppManifest_AppResourceJobSpec_JobPermission = "CAN_MANAGE_RUN" + AppManifest_AppResourceJobSpec_JobPermission_CanView AppManifest_AppResourceJobSpec_JobPermission = "CAN_VIEW" +) + +// Permission to grant on the secret scope. Supported permissions are: "READ", +// "WRITE", "MANAGE". +type AppManifest_AppResourceSecretSpec_SecretPermission string + +const ( + AppManifest_AppResourceSecretSpec_SecretPermission_Unspecified AppManifest_AppResourceSecretSpec_SecretPermission = "" + AppManifest_AppResourceSecretSpec_SecretPermission_Read AppManifest_AppResourceSecretSpec_SecretPermission = "READ" + AppManifest_AppResourceSecretSpec_SecretPermission_Write AppManifest_AppResourceSecretSpec_SecretPermission = "WRITE" + AppManifest_AppResourceSecretSpec_SecretPermission_Manage AppManifest_AppResourceSecretSpec_SecretPermission = "MANAGE" +) + +type AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission string + +const ( + AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission_Unspecified AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission = "" + AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission_CanManage AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission = "CAN_MANAGE" + AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission_CanQuery AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission = "CAN_QUERY" + AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission_CanView AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission = "CAN_VIEW" +) + +type AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission string + +const ( + AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission_Unspecified AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission = "" + AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission_CanManage AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission = "CAN_MANAGE" + AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission_CanUse AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission = "CAN_USE" + AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission_IsOwner AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission = "IS_OWNER" +) + +type AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission string + +const ( + AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission_Unspecified AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission = "" + AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission_ReadVolume AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission = "READ_VOLUME" + AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission_WriteVolume AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission = "WRITE_VOLUME" + AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission_Manage AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission = "MANAGE" + AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission_Select AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission = "SELECT" + AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission_Execute AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission = "EXECUTE" + AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission_UseConnection AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission = "USE_CONNECTION" +) + +type AppManifest_AppResourceUcSecurableSpec_UcSecurableType string + +const ( + AppManifest_AppResourceUcSecurableSpec_UcSecurableType_Unspecified AppManifest_AppResourceUcSecurableSpec_UcSecurableType = "" + AppManifest_AppResourceUcSecurableSpec_UcSecurableType_Volume AppManifest_AppResourceUcSecurableSpec_UcSecurableType = "VOLUME" + AppManifest_AppResourceUcSecurableSpec_UcSecurableType_Table AppManifest_AppResourceUcSecurableSpec_UcSecurableType = "TABLE" + AppManifest_AppResourceUcSecurableSpec_UcSecurableType_Function AppManifest_AppResourceUcSecurableSpec_UcSecurableType = "FUNCTION" + AppManifest_AppResourceUcSecurableSpec_UcSecurableType_Connection AppManifest_AppResourceUcSecurableSpec_UcSecurableType = "CONNECTION" +) + +type AppResourceApp_AppPermission string + +const ( + AppResourceApp_AppPermission_Unspecified AppResourceApp_AppPermission = "" + AppResourceApp_AppPermission_CanUse AppResourceApp_AppPermission = "CAN_USE" +) + +type AppResourceDatabase_DatabasePermission string + +const ( + AppResourceDatabase_DatabasePermission_Unspecified AppResourceDatabase_DatabasePermission = "" + AppResourceDatabase_DatabasePermission_CanConnectAndCreate AppResourceDatabase_DatabasePermission = "CAN_CONNECT_AND_CREATE" +) + +type AppResourceExperiment_ExperimentPermission string + +const ( + AppResourceExperiment_ExperimentPermission_Unspecified AppResourceExperiment_ExperimentPermission = "" + AppResourceExperiment_ExperimentPermission_CanManage AppResourceExperiment_ExperimentPermission = "CAN_MANAGE" + AppResourceExperiment_ExperimentPermission_CanEdit AppResourceExperiment_ExperimentPermission = "CAN_EDIT" + AppResourceExperiment_ExperimentPermission_CanRead AppResourceExperiment_ExperimentPermission = "CAN_READ" +) + +type AppResourceGenieSpace_GenieSpacePermission string + +const ( + AppResourceGenieSpace_GenieSpacePermission_Unspecified AppResourceGenieSpace_GenieSpacePermission = "" + AppResourceGenieSpace_GenieSpacePermission_CanManage AppResourceGenieSpace_GenieSpacePermission = "CAN_MANAGE" + AppResourceGenieSpace_GenieSpacePermission_CanEdit AppResourceGenieSpace_GenieSpacePermission = "CAN_EDIT" + AppResourceGenieSpace_GenieSpacePermission_CanRun AppResourceGenieSpace_GenieSpacePermission = "CAN_RUN" + AppResourceGenieSpace_GenieSpacePermission_CanView AppResourceGenieSpace_GenieSpacePermission = "CAN_VIEW" +) + +type AppResourceJob_JobPermission string + +const ( + AppResourceJob_JobPermission_Unspecified AppResourceJob_JobPermission = "" + AppResourceJob_JobPermission_CanManage AppResourceJob_JobPermission = "CAN_MANAGE" + AppResourceJob_JobPermission_IsOwner AppResourceJob_JobPermission = "IS_OWNER" + AppResourceJob_JobPermission_CanManageRun AppResourceJob_JobPermission = "CAN_MANAGE_RUN" + AppResourceJob_JobPermission_CanView AppResourceJob_JobPermission = "CAN_VIEW" +) + +type AppResourcePostgres_PostgresPermission string + +const ( + AppResourcePostgres_PostgresPermission_Unspecified AppResourcePostgres_PostgresPermission = "" + AppResourcePostgres_PostgresPermission_CanConnectAndCreate AppResourcePostgres_PostgresPermission = "CAN_CONNECT_AND_CREATE" +) + +// Permission to grant on the secret scope. Supported permissions are: "READ", +// "WRITE", "MANAGE". +type AppResourceSecret_SecretPermission string + +const ( + AppResourceSecret_SecretPermission_Unspecified AppResourceSecret_SecretPermission = "" + AppResourceSecret_SecretPermission_Read AppResourceSecret_SecretPermission = "READ" + AppResourceSecret_SecretPermission_Write AppResourceSecret_SecretPermission = "WRITE" + AppResourceSecret_SecretPermission_Manage AppResourceSecret_SecretPermission = "MANAGE" +) + +type AppResourceServingEndpoint_ServingEndpointPermission string + +const ( + AppResourceServingEndpoint_ServingEndpointPermission_Unspecified AppResourceServingEndpoint_ServingEndpointPermission = "" + AppResourceServingEndpoint_ServingEndpointPermission_CanManage AppResourceServingEndpoint_ServingEndpointPermission = "CAN_MANAGE" + AppResourceServingEndpoint_ServingEndpointPermission_CanQuery AppResourceServingEndpoint_ServingEndpointPermission = "CAN_QUERY" + AppResourceServingEndpoint_ServingEndpointPermission_CanView AppResourceServingEndpoint_ServingEndpointPermission = "CAN_VIEW" +) + +type AppResourceSqlWarehouse_SqlWarehousePermission string + +const ( + AppResourceSqlWarehouse_SqlWarehousePermission_Unspecified AppResourceSqlWarehouse_SqlWarehousePermission = "" + AppResourceSqlWarehouse_SqlWarehousePermission_CanManage AppResourceSqlWarehouse_SqlWarehousePermission = "CAN_MANAGE" + AppResourceSqlWarehouse_SqlWarehousePermission_CanUse AppResourceSqlWarehouse_SqlWarehousePermission = "CAN_USE" + AppResourceSqlWarehouse_SqlWarehousePermission_IsOwner AppResourceSqlWarehouse_SqlWarehousePermission = "IS_OWNER" +) + +type AppResourceUcSecurable_UcSecurablePermission string + +const ( + AppResourceUcSecurable_UcSecurablePermission_Unspecified AppResourceUcSecurable_UcSecurablePermission = "" + AppResourceUcSecurable_UcSecurablePermission_ReadVolume AppResourceUcSecurable_UcSecurablePermission = "READ_VOLUME" + AppResourceUcSecurable_UcSecurablePermission_WriteVolume AppResourceUcSecurable_UcSecurablePermission = "WRITE_VOLUME" + AppResourceUcSecurable_UcSecurablePermission_Select AppResourceUcSecurable_UcSecurablePermission = "SELECT" + AppResourceUcSecurable_UcSecurablePermission_Execute AppResourceUcSecurable_UcSecurablePermission = "EXECUTE" + AppResourceUcSecurable_UcSecurablePermission_UseConnection AppResourceUcSecurable_UcSecurablePermission = "USE_CONNECTION" + AppResourceUcSecurable_UcSecurablePermission_Modify AppResourceUcSecurable_UcSecurablePermission = "MODIFY" +) + +type AppResourceUcSecurable_UcSecurableType string + +const ( + AppResourceUcSecurable_UcSecurableType_Unspecified AppResourceUcSecurable_UcSecurableType = "" + AppResourceUcSecurable_UcSecurableType_Volume AppResourceUcSecurable_UcSecurableType = "VOLUME" + AppResourceUcSecurable_UcSecurableType_Table AppResourceUcSecurable_UcSecurableType = "TABLE" + AppResourceUcSecurable_UcSecurableType_Function AppResourceUcSecurable_UcSecurableType = "FUNCTION" + AppResourceUcSecurable_UcSecurableType_Connection AppResourceUcSecurable_UcSecurableType = "CONNECTION" +) + +type AppUpdate_UpdateStatus_UpdateState string + +const ( + AppUpdate_UpdateStatus_UpdateState_Unspecified AppUpdate_UpdateStatus_UpdateState = "" + AppUpdate_UpdateStatus_UpdateState_NotUpdated AppUpdate_UpdateStatus_UpdateState = "NOT_UPDATED" + AppUpdate_UpdateStatus_UpdateState_InProgress AppUpdate_UpdateStatus_UpdateState = "IN_PROGRESS" + AppUpdate_UpdateStatus_UpdateState_Succeeded AppUpdate_UpdateStatus_UpdateState = "SUCCEEDED" + AppUpdate_UpdateStatus_UpdateState_Failed AppUpdate_UpdateStatus_UpdateState = "FAILED" +) + +type ApplicationStatus_ApplicationState string + +const ( + ApplicationStatus_ApplicationState_Unspecified ApplicationStatus_ApplicationState = "" + ApplicationStatus_ApplicationState_Deploying ApplicationStatus_ApplicationState = "DEPLOYING" + ApplicationStatus_ApplicationState_Running ApplicationStatus_ApplicationState = "RUNNING" + ApplicationStatus_ApplicationState_Crashed ApplicationStatus_ApplicationState = "CRASHED" + ApplicationStatus_ApplicationState_Unavailable ApplicationStatus_ApplicationState = "UNAVAILABLE" +) + +type ComputeStatus_ComputeState string + +const ( + ComputeStatus_ComputeState_Unspecified ComputeStatus_ComputeState = "" + ComputeStatus_ComputeState_Error ComputeStatus_ComputeState = "ERROR" + ComputeStatus_ComputeState_Deleting ComputeStatus_ComputeState = "DELETING" + ComputeStatus_ComputeState_Starting ComputeStatus_ComputeState = "STARTING" + ComputeStatus_ComputeState_Stopping ComputeStatus_ComputeState = "STOPPING" + ComputeStatus_ComputeState_Updating ComputeStatus_ComputeState = "UPDATING" + ComputeStatus_ComputeState_Stopped ComputeStatus_ComputeState = "STOPPED" + ComputeStatus_ComputeState_Active ComputeStatus_ComputeState = "ACTIVE" +) + +type SpaceStatus_SpaceState string + +const ( + SpaceStatus_SpaceState_Unspecified SpaceStatus_SpaceState = "" + SpaceStatus_SpaceState_SpaceCreating SpaceStatus_SpaceState = "SPACE_CREATING" + SpaceStatus_SpaceState_SpaceActive SpaceStatus_SpaceState = "SPACE_ACTIVE" + SpaceStatus_SpaceState_SpaceError SpaceStatus_SpaceState = "SPACE_ERROR" + SpaceStatus_SpaceState_SpaceDeleting SpaceStatus_SpaceState = "SPACE_DELETING" + SpaceStatus_SpaceState_SpaceDeleted SpaceStatus_SpaceState = "SPACE_DELETED" + SpaceStatus_SpaceState_SpaceUpdating SpaceStatus_SpaceState = "SPACE_UPDATING" +) + +// Databricks Error that is returned by all Databricks APIs.. +type ApiError struct { + ErrorCode ErrorCode + Message *string + StackTrace *string + Details []json.RawMessage +} + +type App struct { + // The name of the app. The name must contain only lowercase alphanumeric + // characters and hyphens. It must be unique within the workspace. + Name *string `fieldmask:"name"` + // The description of the app. + Description *string `fieldmask:"description"` + ComputeStatus *ComputeStatus `fieldmask:"compute_status"` + AppStatus *ApplicationStatus `fieldmask:"app_status"` + // The URL of the app once it is deployed. + Url *string `fieldmask:"url"` + // The active deployment of the app. A deployment is considered active when it + // has been deployed to the app compute. + ActiveDeployment *AppDeployment `fieldmask:"active_deployment"` + // The creation time of the app. Formatted timestamp in ISO 6801. + CreateTime *types.Time `fieldmask:"create_time"` + // The email of the user that created the app. + Creator *string `fieldmask:"creator"` + // The update time of the app. Formatted timestamp in ISO 6801. + UpdateTime *types.Time `fieldmask:"update_time"` + // The email of the user that last updated the app. + Updater *string `fieldmask:"updater"` + // The pending deployment of the app. A deployment is considered pending when it + // is being prepared for deployment to the app compute. + PendingDeployment *AppDeployment `fieldmask:"pending_deployment"` + // Resources for the app. + Resources []AppResource `fieldmask:"resources"` + ServicePrincipalId *int64 `fieldmask:"service_principal_id"` + ServicePrincipalName *string `fieldmask:"service_principal_name"` + // The default workspace file system path of the source code from which app + // deployment are created. This field tracks the workspace source code path of + // the last active deployment. + DefaultSourceCodePath *string `fieldmask:"default_source_code_path"` + // The Git source of the app's most recent active deployment, including the + // repository configuration and the resolved reference. Populated by the system + // after a Git-based deployment and used as the default reference when automatic + // deployments are enabled. + DefaultGitSource *GitSource `fieldmask:"default_git_source"` + BudgetPolicyId *string `fieldmask:"budget_policy_id"` + EffectiveBudgetPolicyId *string `fieldmask:"effective_budget_policy_id"` + ServicePrincipalClientId *string `fieldmask:"service_principal_client_id"` + UserApiScopes []string `fieldmask:"user_api_scopes"` + // The unique identifier of the app. + Id *string `fieldmask:"id"` + // The effective api scopes granted to the user access token. + EffectiveUserApiScopes []string `fieldmask:"effective_user_api_scopes"` + Oauth2AppIntegrationId *string `fieldmask:"oauth2_app_integration_id"` + Oauth2AppClientId *string `fieldmask:"oauth2_app_client_id"` + ComputeSize ComputeSize `fieldmask:"compute_size"` + UsagePolicyId *string `fieldmask:"usage_policy_id"` + EffectiveUsagePolicyId *string `fieldmask:"effective_usage_policy_id"` + // Minimum number of app instances. Must be set together with + // `compute_max_instances`. + ComputeMinInstances *int `fieldmask:"compute_min_instances"` + // Maximum number of app instances. Must be set together with + // `compute_min_instances`. + ComputeMaxInstances *int `fieldmask:"compute_max_instances"` + // Git repository configuration for app deployments. When specified, deployments + // can reference code from this repository by providing only the git reference + // (branch, tag, or commit). + GitRepository *GitRepository `fieldmask:"git_repository"` + TelemetryExportDestinations []TelemetryExportDestination `fieldmask:"telemetry_export_destinations"` + // The URL of the thumbnail image for the app. + ThumbnailUrl *string `fieldmask:"thumbnail_url"` + // Name of the space this app belongs to. + Space *string `fieldmask:"space"` + DeploymentSource isApp_DeploymentSource + // Forward the user's access token to the app. Requires stopping and starting + // app compute to take effect. + ForwardUserAccessToken *bool `fieldmask:"forward_user_access_token"` + _ [0]appDeploymentSourceFieldMaskMetadata `fieldmask_oneof:"DeploymentSource"` +} + +type isApp_DeploymentSource interface { + isApp_DeploymentSource() +} + +// App_DeploymentSource_SourceCodePath selects SourceCodePath for App.DeploymentSource. +type App_DeploymentSource_SourceCodePath struct { + SourceCodePath string `fieldmask:"source_code_path"` +} + +func (*App_DeploymentSource_SourceCodePath) isApp_DeploymentSource() {} + +// App_DeploymentSource_GitSource selects GitSource for App.DeploymentSource. +// The Git source to deploy from, specifying the reference to check out (branch, +// tag, or commit) and an optional path to the app source code within the +// repository configured in git_repository. +type App_DeploymentSource_GitSource struct { + GitSource GitSource `fieldmask:"git_source"` +} + +func (*App_DeploymentSource_GitSource) isApp_DeploymentSource() {} + +type appDeploymentSourceFieldMaskMetadata struct { + *App_DeploymentSource_SourceCodePath + *App_DeploymentSource_GitSource +} + +type AppDeployment struct { + // The unique id of the deployment. + DeploymentId *string `fieldmask:"deployment_id"` + // The workspace file system path of the source code used to create the app + // deployment. This is different from `deployment_artifacts.source_code_path`, + // which is the path used by the deployed app. The former refers to the original + // source code location of the app in the workspace during deployment creation, + // whereas the latter provides a system generated stable snapshotted source code + // path used by the deployment. + SourceCodePath *string `fieldmask:"source_code_path"` + // Git repository to use as the source for the app deployment. + GitSource *GitSource `fieldmask:"git_source"` + // The mode of which the deployment will manage the source code. + Mode AppDeployment_Mode `fieldmask:"mode"` + // The deployment artifacts for an app. + DeploymentArtifacts *AppDeploymentArtifacts `fieldmask:"deployment_artifacts"` + // Status and status message of the deployment + Status *AppDeploymentStatus `fieldmask:"status"` + // The creation time of the deployment. Formatted timestamp in ISO 6801. + CreateTime *types.Time `fieldmask:"create_time"` + // The email of the user creates the deployment. + Creator *string `fieldmask:"creator"` + // The update time of the deployment. Formatted timestamp in ISO 6801. + UpdateTime *types.Time `fieldmask:"update_time"` + // The command with which to run the app. This will override the command + // specified in the app.yaml file. + Command []string `fieldmask:"command"` + // The environment variables to set in the app runtime environment. This will + // override the environment variables specified in the app.yaml file. + EnvVars []EnvVar `fieldmask:"env_vars"` +} + +type AppDeploymentArtifacts struct { + // The snapshotted workspace file system path of the source code loaded by the + // deployed app. + SourceCodePath *string `fieldmask:"source_code_path"` +} + +type AppDeploymentStatus struct { + // State of the deployment. + State AppDeployment_State `fieldmask:"state"` + // Message corresponding with the deployment state. + Message *string `fieldmask:"message"` +} + +// App manifest definition. +type AppManifest struct { + // The manifest schema version, for now only 1 is allowed + Version *int + // Name of the app defined by manifest author / publisher + Name *string + // Description of the app defined by manifest author / publisher + Description *string + ResourceSpecs []AppManifest_AppResourceSpec +} + +type AppManifest_AppResourceExperimentSpec struct { + Permission AppManifest_AppResourceExperimentSpec_ExperimentPermission +} + +type AppManifest_AppResourceJobSpec struct { + // Permissions to grant on the Job. Supported permissions are: "CAN_MANAGE", + // "IS_OWNER", "CAN_MANAGE_RUN", "CAN_VIEW". + Permission AppManifest_AppResourceJobSpec_JobPermission +} + +type AppManifest_AppResourceSecretSpec struct { + // Permission to grant on the secret scope. For secrets, only one permission is + // allowed. Permission must be one of: "READ", "WRITE", "MANAGE". + Permission AppManifest_AppResourceSecretSpec_SecretPermission +} + +type AppManifest_AppResourceServingEndpointSpec struct { + // Permission to grant on the serving endpoint. Supported permissions are: + // "CAN_MANAGE", "CAN_QUERY", "CAN_VIEW". + Permission AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission +} + +// AppResource related fields are copied from app.proto but excludes resource +// identifiers (e.g. name, id, key, scope, etc.). +type AppManifest_AppResourceSpec struct { + // Name of the App Resource. + Name *string + // Description of the App Resource. + Description *string + Resource isAppManifest_AppResourceSpec_Resource +} + +type isAppManifest_AppResourceSpec_Resource interface { + isAppManifest_AppResourceSpec_Resource() +} + +// AppManifest_AppResourceSpec_Resource_SecretSpec selects SecretSpec for AppManifest_AppResourceSpec.Resource. +type AppManifest_AppResourceSpec_Resource_SecretSpec struct { + SecretSpec AppManifest_AppResourceSecretSpec +} + +func (*AppManifest_AppResourceSpec_Resource_SecretSpec) isAppManifest_AppResourceSpec_Resource() {} + +// AppManifest_AppResourceSpec_Resource_SqlWarehouseSpec selects SqlWarehouseSpec for AppManifest_AppResourceSpec.Resource. +type AppManifest_AppResourceSpec_Resource_SqlWarehouseSpec struct { + SqlWarehouseSpec AppManifest_AppResourceSqlWarehouseSpec +} + +func (*AppManifest_AppResourceSpec_Resource_SqlWarehouseSpec) isAppManifest_AppResourceSpec_Resource() { +} + +// AppManifest_AppResourceSpec_Resource_ServingEndpointSpec selects ServingEndpointSpec for AppManifest_AppResourceSpec.Resource. +type AppManifest_AppResourceSpec_Resource_ServingEndpointSpec struct { + ServingEndpointSpec AppManifest_AppResourceServingEndpointSpec +} + +func (*AppManifest_AppResourceSpec_Resource_ServingEndpointSpec) isAppManifest_AppResourceSpec_Resource() { +} + +// AppManifest_AppResourceSpec_Resource_JobSpec selects JobSpec for AppManifest_AppResourceSpec.Resource. +type AppManifest_AppResourceSpec_Resource_JobSpec struct { + JobSpec AppManifest_AppResourceJobSpec +} + +func (*AppManifest_AppResourceSpec_Resource_JobSpec) isAppManifest_AppResourceSpec_Resource() {} + +// AppManifest_AppResourceSpec_Resource_UcSecurableSpec selects UcSecurableSpec for AppManifest_AppResourceSpec.Resource. +type AppManifest_AppResourceSpec_Resource_UcSecurableSpec struct { + UcSecurableSpec AppManifest_AppResourceUcSecurableSpec +} + +func (*AppManifest_AppResourceSpec_Resource_UcSecurableSpec) isAppManifest_AppResourceSpec_Resource() { +} + +// AppManifest_AppResourceSpec_Resource_ExperimentSpec selects ExperimentSpec for AppManifest_AppResourceSpec.Resource. +type AppManifest_AppResourceSpec_Resource_ExperimentSpec struct { + ExperimentSpec AppManifest_AppResourceExperimentSpec +} + +func (*AppManifest_AppResourceSpec_Resource_ExperimentSpec) isAppManifest_AppResourceSpec_Resource() { +} + +type AppManifest_AppResourceSqlWarehouseSpec struct { + // Permission to grant on the SQL warehouse. Supported permissions are: + // "CAN_MANAGE", "CAN_USE", "IS_OWNER". + Permission AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission +} + +type AppManifest_AppResourceUcSecurableSpec struct { + SecurableType AppManifest_AppResourceUcSecurableSpec_UcSecurableType + Permission AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission +} + +type AppResource struct { + // Name of the App Resource. + Name *string + // Description of the App Resource. + Description *string + Resource isAppResource_Resource +} + +type isAppResource_Resource interface { + isAppResource_Resource() +} + +// AppResource_Resource_Secret selects Secret for AppResource.Resource. +type AppResource_Resource_Secret struct { + Secret AppResourceSecret +} + +func (*AppResource_Resource_Secret) isAppResource_Resource() {} + +// AppResource_Resource_SqlWarehouse selects SqlWarehouse for AppResource.Resource. +type AppResource_Resource_SqlWarehouse struct { + SqlWarehouse AppResourceSqlWarehouse +} + +func (*AppResource_Resource_SqlWarehouse) isAppResource_Resource() {} + +// AppResource_Resource_ServingEndpoint selects ServingEndpoint for AppResource.Resource. +type AppResource_Resource_ServingEndpoint struct { + ServingEndpoint AppResourceServingEndpoint +} + +func (*AppResource_Resource_ServingEndpoint) isAppResource_Resource() {} + +// AppResource_Resource_Job selects Job for AppResource.Resource. +type AppResource_Resource_Job struct { + Job AppResourceJob +} + +func (*AppResource_Resource_Job) isAppResource_Resource() {} + +// AppResource_Resource_UcSecurable selects UcSecurable for AppResource.Resource. +type AppResource_Resource_UcSecurable struct { + UcSecurable AppResourceUcSecurable +} + +func (*AppResource_Resource_UcSecurable) isAppResource_Resource() {} + +// AppResource_Resource_Database selects Database for AppResource.Resource. +type AppResource_Resource_Database struct { + Database AppResourceDatabase +} + +func (*AppResource_Resource_Database) isAppResource_Resource() {} + +// AppResource_Resource_GenieSpace selects GenieSpace for AppResource.Resource. +type AppResource_Resource_GenieSpace struct { + GenieSpace AppResourceGenieSpace +} + +func (*AppResource_Resource_GenieSpace) isAppResource_Resource() {} + +// AppResource_Resource_Experiment selects Experiment for AppResource.Resource. +type AppResource_Resource_Experiment struct { + Experiment AppResourceExperiment +} + +func (*AppResource_Resource_Experiment) isAppResource_Resource() {} + +// AppResource_Resource_App selects App for AppResource.Resource. +type AppResource_Resource_App struct { + App AppResourceApp +} + +func (*AppResource_Resource_App) isAppResource_Resource() {} + +// AppResource_Resource_Postgres selects Postgres for AppResource.Resource. +type AppResource_Resource_Postgres struct { + Postgres AppResourcePostgres +} + +func (*AppResource_Resource_Postgres) isAppResource_Resource() {} + +type AppResourceApp struct { + Name *string + Permission AppResourceApp_AppPermission +} + +type AppResourceDatabase struct { + InstanceName *string + DatabaseName *string + Permission AppResourceDatabase_DatabasePermission +} + +type AppResourceExperiment struct { + ExperimentId *string + Permission AppResourceExperiment_ExperimentPermission +} + +type AppResourceGenieSpace struct { + Name *string + SpaceId *string + Permission AppResourceGenieSpace_GenieSpacePermission +} + +type AppResourceJob struct { + // Id of the job to grant permission on. + Id *string + // Permissions to grant on the Job. Supported permissions are: "CAN_MANAGE", + // "IS_OWNER", "CAN_MANAGE_RUN", "CAN_VIEW". + Permission AppResourceJob_JobPermission +} + +type AppResourcePostgres struct { + Branch *string + Database *string + Permission AppResourcePostgres_PostgresPermission +} + +type AppResourceSecret struct { + // Scope of the secret to grant permission on. + Scope *string + // Key of the secret to grant permission on. + Key *string + // Permission to grant on the secret scope. For secrets, only one permission is + // allowed. Permission must be one of: "READ", "WRITE", "MANAGE". + Permission AppResourceSecret_SecretPermission +} + +type AppResourceServingEndpoint struct { + // Name of the serving endpoint to grant permission on. + Name *string + // Permission to grant on the serving endpoint. Supported permissions are: + // "CAN_MANAGE", "CAN_QUERY", "CAN_VIEW". + Permission AppResourceServingEndpoint_ServingEndpointPermission +} + +type AppResourceSqlWarehouse struct { + // Id of the SQL warehouse to grant permission on. + Id *string + // Permission to grant on the SQL warehouse. Supported permissions are: + // "CAN_MANAGE", "CAN_USE", "IS_OWNER". + Permission AppResourceSqlWarehouse_SqlWarehousePermission +} + +type AppResourceUcSecurable struct { + SecurableFullName *string + SecurableType AppResourceUcSecurable_UcSecurableType + Permission AppResourceUcSecurable_UcSecurablePermission + // The securable kind from Unity Catalog. See + // https://docs.databricks.com/api/workspace/tables/get#securable_kind_manifest-securable_kind. + SecurableKind *string +} + +// The thumbnail for an app.. +type AppThumbnail struct { + // The thumbnail image bytes. + Thumbnail []byte +} + +type AppUpdate struct { + Status *AppUpdate_UpdateStatus + Description *string + BudgetPolicyId *string + Resources []AppResource + UserApiScopes []string + ComputeSize ComputeSize + UsagePolicyId *string + // Minimum number of app instances. Must be set together with + // `compute_max_instances`. + ComputeMinInstances *int + // Maximum number of app instances. Must be set together with + // `compute_min_instances`. + ComputeMaxInstances *int + GitRepository *GitRepository + // Forward the user's access token to the app. Requires stopping and starting + // app compute to take effect. + ForwardUserAccessToken *bool +} + +type AppUpdate_UpdateStatus struct { + State AppUpdate_UpdateStatus_UpdateState + Message *string +} + +type ApplicationStatus struct { + // State of the application. + State ApplicationStatus_ApplicationState `fieldmask:"state"` + // Application status message + Message *string `fieldmask:"message"` + // The number of running instances of this application. + RunningInstances *int `fieldmask:"running_instances"` +} + +type AsyncUpdateAppRequest struct { + App *App + UpdateMask *types.FieldMask[App] + AppName *string +} + +type ComputeStatus struct { + // State of the app compute. + State ComputeStatus_ComputeState `fieldmask:"state"` + // Compute status message + Message *string `fieldmask:"message"` + // The number of compute instances currently serving requests for this + // application. An instance is considered active if it is reachable and ready to + // handle requests. + ActiveInstances *int `fieldmask:"active_instances"` +} + +type CreateAppDeploymentRequest struct { + // The name of the app. + AppName *string + // The app deployment configuration. + AppDeployment *AppDeployment +} + +type CreateAppRequest struct { + App *App + // If true, the app will not be started after creation. + NoCompute *bool +} + +type CreateCustomTemplateRequest struct { + Template *CustomTemplate +} + +type CreateSpaceRequest struct { + Space *Space +} + +type CustomTemplate struct { + // The name of the template. It must contain only alphanumeric characters, + // hyphens, underscores, and whitespaces. It must be unique within the + // workspace. + Name *string + // The description of the template. + Description *string + // The Git repository URL that the template resides in. + GitRepo *string + // The path to the template within the Git repository. + Path *string + // The manifest of the template. It defines fields and default values when + // installing the template. + Manifest *AppManifest + // The Git provider of the template. + GitProvider *string + Creator *string +} + +type DeleteAppRequest struct { + // The name of the app. + Name *string +} + +type DeleteAppThumbnailRequest struct { + // The name of the app. + Name *string +} + +type DeleteCustomTemplateRequest struct { + // The name of the custom template. + Name *string +} + +type DeleteSpaceRequest struct { + // The name of the app space. + Name *string +} + +type EnvVar struct { + // The name of the environment variable. + Name *string + Source isEnvVar_Source +} + +type isEnvVar_Source interface { + isEnvVar_Source() +} + +// EnvVar_Source_Value selects Value for EnvVar.Source. +// The value for the environment variable. +type EnvVar_Source_Value struct { + Value string +} + +func (*EnvVar_Source_Value) isEnvVar_Source() {} + +// EnvVar_Source_ValueFrom selects ValueFrom for EnvVar.Source. +// The name of an external resource that contains the value, such +// as a secret or a database table. +type EnvVar_Source_ValueFrom struct { + ValueFrom string +} + +func (*EnvVar_Source_ValueFrom) isEnvVar_Source() {} + +type GetAppDeploymentRequest struct { + // The name of the app. + AppName *string + // The unique id of the deployment. + DeploymentId *string +} + +type GetAppRequest struct { + // The name of the app. + Name *string +} + +type GetAppUpdateRequest struct { + // The name of the app. + AppName *string +} + +type GetCustomTemplateRequest struct { + // The name of the custom template. + Name *string +} + +// The request message for `GetOperation` method.. +type GetOperationRequest struct { + // The name of the operation resource. + Name *string +} + +type GetSpaceRequest struct { + // The name of the app space. + Name *string +} + +// Git repository configuration specifying the location of the repository.. +type GitRepository struct { + // URL of the Git repository. + Url *string `fieldmask:"url"` + // Git provider. Case insensitive. Supported values: gitHub, gitHubEnterprise, + // bitbucketCloud, bitbucketServer, azureDevOpsServices, gitLab, + // gitLabEnterpriseEdition, awsCodeCommit. + Provider *string `fieldmask:"provider"` + // When true, automatically deploys the app on push events to the branch + // configured in the app's deployment_source.git_source. + AutoDeploy *bool `fieldmask:"auto_deploy"` + // ID of a personal access token Git credential owned by the caller, used to + // grant the app's service principal access to this repository. + CallerCredentialId *int64 `fieldmask:"caller_credential_id"` +} + +// Complete git source specification including repository location and +// reference.. +type GitSource struct { + // Git repository configuration. Populated from the app's git_repository + // configuration. + GitRepository *GitRepository `fieldmask:"git_repository"` + // Git reference to checkout. Mutually exclusive: branch, tag, or commit. + Reference isGitSource_Reference + // Relative path to the app source code within the Git repository. If not + // specified, the root of the repository is used. + SourceCodePath *string `fieldmask:"source_code_path"` + // The resolved commit SHA that was actually used for the deployment. This is + // populated by the system after resolving the reference (branch, tag, or + // commit). If commit is specified directly, this will match commit. If a branch + // or tag is specified, this contains the commit SHA that the branch or tag + // pointed to at deployment time. + ResolvedCommit *string `fieldmask:"resolved_commit"` + _ [0]gitSourceReferenceFieldMaskMetadata `fieldmask_oneof:"Reference"` +} + +type isGitSource_Reference interface { + isGitSource_Reference() +} + +// GitSource_Reference_Branch selects Branch for GitSource.Reference. +// Git branch to checkout. +type GitSource_Reference_Branch struct { + Branch string `fieldmask:"branch"` +} + +func (*GitSource_Reference_Branch) isGitSource_Reference() {} + +// GitSource_Reference_Tag selects Tag for GitSource.Reference. +// Git tag to checkout. +type GitSource_Reference_Tag struct { + Tag string `fieldmask:"tag"` +} + +func (*GitSource_Reference_Tag) isGitSource_Reference() {} + +// GitSource_Reference_Commit selects Commit for GitSource.Reference. +// Git commit SHA to checkout. +type GitSource_Reference_Commit struct { + Commit string `fieldmask:"commit"` +} + +func (*GitSource_Reference_Commit) isGitSource_Reference() {} + +type gitSourceReferenceFieldMaskMetadata struct { + *GitSource_Reference_Branch + *GitSource_Reference_Tag + *GitSource_Reference_Commit +} + +type ListAppDeploymentsRequest struct { + // The name of the app. + AppName *string + // Pagination token to go to the next page of apps. Requests first page if + // absent. + PageToken *string + // Upper bound for items returned. + PageSize *int +} + +type ListAppDeploymentsResponse struct { + // Deployment history of the app. + AppDeployments []AppDeployment + // Pagination token to request the next page of apps. + NextPageToken *string +} + +// Request to list all apps deployed in the workspace. +type ListAppsRequest struct { + // Pagination token to go to the next page of apps. Requests first page if + // absent. + PageToken *string + // Upper bound for items returned. + PageSize *int + // Filter apps by app space name. When specified, only apps belonging to this + // space are returned. + Space *string +} + +type ListAppsResponse struct { + Apps []App + // Pagination token to request the next page of apps. + NextPageToken *string +} + +type ListCustomTemplatesRequest struct { + // Pagination token to go to the next page of custom templates. Requests first + // page if absent. + PageToken *string + // Upper bound for items returned. + PageSize *int +} + +type ListCustomTemplatesResponse struct { + Templates []CustomTemplate + // Pagination token to request the next page of custom templates. + NextPageToken *string +} + +type ListSpacesRequest struct { + // Pagination token to go to the next page of app spaces. Requests first page if + // absent. + PageToken *string + // Upper bound for items returned. + PageSize *int +} + +type ListSpacesResponse struct { + Spaces []Space + // Pagination token to request the next page of app spaces. + NextPageToken *string +} + +// This resource represents a long-running operation that is the result of a +// network API call.. +type Operation struct { + // The server-assigned name, which is only unique within the same service that + // originally returns it. If you use the default HTTP mapping, the `name` should + // be a resource name ending with `operations/{unique_id}`. + Name *string + // Service-specific metadata associated with the operation. It typically + // contains progress information and common metadata such as create time. Some + // services might not provide such metadata. + Metadata json.RawMessage + // If the value is `false`, it means the operation is still in progress. If + // `true`, the operation is completed, and either `error` or `response` is + // available. + Done *bool + // The operation result, which can be either an `error` or a valid `response`. + // If `done` == `false`, neither `error` nor `response` is set. If `done` == + // `true`, exactly one of `error` or `response` can be set. Some services might + // not provide the result. + Result isOperation_Result +} + +type isOperation_Result interface { + isOperation_Result() +} + +// Operation_Result_Error selects Error for Operation.Result. +// The error result of the operation in case of failure or cancellation. +type Operation_Result_Error struct { + Error ApiError +} + +func (*Operation_Result_Error) isOperation_Result() {} + +// Operation_Result_Response selects Response for Operation.Result. +// The normal, successful response of the operation. +type Operation_Result_Response struct { + Response json.RawMessage +} + +func (*Operation_Result_Response) isOperation_Result() {} + +type Space struct { + // The name of the app space. The name must contain only lowercase alphanumeric + // characters and hyphens. It must be unique within the workspace. + Name *string `fieldmask:"name"` + // The description of the app space. + Description *string `fieldmask:"description"` + // The status of the app space. + Status *SpaceStatus `fieldmask:"status"` + // The unique identifier of the app space. + Id *string `fieldmask:"id"` + // The creation time of the app space. Formatted timestamp in ISO 6801. + CreateTime *types.Time `fieldmask:"create_time"` + // The email of the user that created the app space. + Creator *string `fieldmask:"creator"` + // The update time of the app space. Formatted timestamp in ISO 6801. + UpdateTime *types.Time `fieldmask:"update_time"` + // The email of the user that last updated the app space. + Updater *string `fieldmask:"updater"` + // Resources for the app space. Resources configured at the space level are + // available to all apps in the space. + Resources []AppResource `fieldmask:"resources"` + // OAuth scopes for apps in the space. + UserApiScopes []string `fieldmask:"user_api_scopes"` + // The effective api scopes granted to the user access token. + EffectiveUserApiScopes []string `fieldmask:"effective_user_api_scopes"` + // The service principal ID for the app space. + ServicePrincipalId *int64 `fieldmask:"service_principal_id"` + // The service principal name for the app space. + ServicePrincipalName *string `fieldmask:"service_principal_name"` + // The service principal client ID for the app space. + ServicePrincipalClientId *string `fieldmask:"service_principal_client_id"` + // The usage policy ID for managing cost at the space level. + UsagePolicyId *string `fieldmask:"usage_policy_id"` + // The effective usage policy ID used by apps in the space. + EffectiveUsagePolicyId *string `fieldmask:"effective_usage_policy_id"` +} + +type SpaceStatus struct { + // The state of the app space. + State SpaceStatus_SpaceState `fieldmask:"state"` + // Message providing context about the current state. + Message *string `fieldmask:"message"` +} + +// Tracks app space update information.. +type SpaceUpdate struct { + Status *SpaceUpdateStatus + Description *string + Resources []AppResource + UserApiScopes []string + UsagePolicyId *string +} + +// Status of an app space update operation. +type SpaceUpdateStatus struct { + State SpaceUpdateState + Message *string +} + +type StartAppRequest struct { + // The name of the app. + Name *string +} + +type StopAppRequest struct { + // The name of the app. + Name *string +} + +// A single telemetry export destination with its configuration and status.. +type TelemetryExportDestination struct { + // Destination type and configuration (writable). + Destination isTelemetryExportDestination_Destination +} + +type isTelemetryExportDestination_Destination interface { + isTelemetryExportDestination_Destination() +} + +// TelemetryExportDestination_Destination_UnityCatalog selects UnityCatalog for TelemetryExportDestination.Destination. +type TelemetryExportDestination_Destination_UnityCatalog struct { + UnityCatalog UnityCatalog +} + +func (*TelemetryExportDestination_Destination_UnityCatalog) isTelemetryExportDestination_Destination() { +} + +// Unity Catalog Destinations for OTEL telemetry export.. +type UnityCatalog struct { + // Unity Catalog table for OTEL logs. + LogsTable *string + // Unity Catalog table for OTEL metrics. + MetricsTable *string + // Unity Catalog table for OTEL traces (spans). + TracesTable *string +} + +type UpdateAppRequest struct { + App *App +} + +type UpdateAppThumbnailRequest struct { + // The name of the app. + Name *string + // The app thumbnail to set. + AppThumbnail *AppThumbnail +} + +type UpdateCustomTemplateRequest struct { + Template *CustomTemplate +} + +type UpdateSpaceRequest struct { + Space *Space + UpdateMask *types.FieldMask[Space] +} + +// Error returns the LRO error code and message. +func (e *ApiError) Error() string { + message := "unknown error" + if e.Message != nil && *e.Message != "" { + message = *e.Message + } + if e.ErrorCode != "" { + return fmt.Sprintf("[%v] %s", e.ErrorCode, message) + } + return message +} diff --git a/apps/v1/wire.go b/apps/v1/wire.go new file mode 100755 index 0000000..fc31765 --- /dev/null +++ b/apps/v1/wire.go @@ -0,0 +1,2216 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package apps + +import ( + "encoding/json" + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type apiErrorWire struct { + ErrorCode ErrorCode `json:"error_code,omitempty"` + Message *string `json:"message,omitempty"` + StackTrace *string `json:"stack_trace,omitempty"` + Details []json.RawMessage `json:"details,omitempty"` +} + +func apiErrorFromWire(w *apiErrorWire) (*ApiError, error) { + if w == nil { + return nil, nil + } + return &ApiError{ + ErrorCode: w.ErrorCode, + Message: w.Message, + StackTrace: w.StackTrace, + Details: w.Details, + }, nil +} + +type appWire struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + ComputeStatus *computeStatusWire `json:"compute_status,omitempty"` + AppStatus *applicationStatusWire `json:"app_status,omitempty"` + Url *string `json:"url,omitempty"` + ActiveDeployment *appDeploymentWire `json:"active_deployment,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + Creator *string `json:"creator,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Updater *string `json:"updater,omitempty"` + PendingDeployment *appDeploymentWire `json:"pending_deployment,omitempty"` + Resources []appResourceWire `json:"resources,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` + DefaultSourceCodePath *string `json:"default_source_code_path,omitempty"` + DefaultGitSource *gitSourceWire `json:"default_git_source,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + EffectiveBudgetPolicyId *string `json:"effective_budget_policy_id,omitempty"` + ServicePrincipalClientId *string `json:"service_principal_client_id,omitempty"` + UserApiScopes []string `json:"user_api_scopes,omitempty"` + Id *string `json:"id,omitempty"` + EffectiveUserApiScopes []string `json:"effective_user_api_scopes,omitempty"` + Oauth2AppIntegrationId *string `json:"oauth2_app_integration_id,omitempty"` + Oauth2AppClientId *string `json:"oauth2_app_client_id,omitempty"` + ComputeSize ComputeSize `json:"compute_size,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + EffectiveUsagePolicyId *string `json:"effective_usage_policy_id,omitempty"` + ComputeMinInstances *int `json:"compute_min_instances,omitempty"` + ComputeMaxInstances *int `json:"compute_max_instances,omitempty"` + GitRepository *gitRepositoryWire `json:"git_repository,omitempty"` + TelemetryExportDestinations []telemetryExportDestinationWire `json:"telemetry_export_destinations,omitempty"` + ThumbnailUrl *string `json:"thumbnail_url,omitempty"` + Space *string `json:"space,omitempty"` + SourceCodePath *string `json:"source_code_path,omitempty"` + GitSource *gitSourceWire `json:"git_source,omitempty"` + ForwardUserAccessToken *bool `json:"forward_user_access_token,omitempty"` +} + +func appToWire(v *App) (*appWire, error) { + if v == nil { + return nil, nil + } + computeStatusWireValue, err := computeStatusToWire(v.ComputeStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.ComputeStatus", err) + } + appStatusWireValue, err := applicationStatusToWire(v.AppStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.AppStatus", err) + } + activeDeploymentWireValue, err := appDeploymentToWire(v.ActiveDeployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.ActiveDeployment", err) + } + pendingDeploymentWireValue, err := appDeploymentToWire(v.PendingDeployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.PendingDeployment", err) + } + resourcesWireValue, err := convertSlice(v.Resources, appResourceToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.Resources", err) + } + defaultGitSourceWireValue, err := gitSourceToWire(v.DefaultGitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.DefaultGitSource", err) + } + gitRepositoryWireValue, err := gitRepositoryToWire(v.GitRepository) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.GitRepository", err) + } + telemetryExportDestinationsWireValue, err := convertSlice(v.TelemetryExportDestinations, telemetryExportDestinationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.TelemetryExportDestinations", err) + } + var deploymentSourceSourceCodePathWire *string + var deploymentSourceGitSourceWire *gitSourceWire + switch value := v.DeploymentSource.(type) { + case nil: + case *App_DeploymentSource_SourceCodePath: + if value != nil { + deploymentSourceSourceCodePathWire = new(value.SourceCodePath) + } + case *App_DeploymentSource_GitSource: + if value != nil { + deploymentSourceGitSourceConverted, err := gitSourceToWire(&value.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.DeploymentSource.GitSource", err) + } + deploymentSourceGitSourceWire = deploymentSourceGitSourceConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "App.DeploymentSource", value) + } + return &appWire{ + Name: v.Name, + Description: v.Description, + ComputeStatus: computeStatusWireValue, + AppStatus: appStatusWireValue, + Url: v.Url, + ActiveDeployment: activeDeploymentWireValue, + CreateTime: v.CreateTime, + Creator: v.Creator, + UpdateTime: v.UpdateTime, + Updater: v.Updater, + PendingDeployment: pendingDeploymentWireValue, + Resources: resourcesWireValue, + ServicePrincipalId: v.ServicePrincipalId, + ServicePrincipalName: v.ServicePrincipalName, + DefaultSourceCodePath: v.DefaultSourceCodePath, + DefaultGitSource: defaultGitSourceWireValue, + BudgetPolicyId: v.BudgetPolicyId, + EffectiveBudgetPolicyId: v.EffectiveBudgetPolicyId, + ServicePrincipalClientId: v.ServicePrincipalClientId, + UserApiScopes: v.UserApiScopes, + Id: v.Id, + EffectiveUserApiScopes: v.EffectiveUserApiScopes, + Oauth2AppIntegrationId: v.Oauth2AppIntegrationId, + Oauth2AppClientId: v.Oauth2AppClientId, + ComputeSize: v.ComputeSize, + UsagePolicyId: v.UsagePolicyId, + EffectiveUsagePolicyId: v.EffectiveUsagePolicyId, + ComputeMinInstances: v.ComputeMinInstances, + ComputeMaxInstances: v.ComputeMaxInstances, + GitRepository: gitRepositoryWireValue, + TelemetryExportDestinations: telemetryExportDestinationsWireValue, + ThumbnailUrl: v.ThumbnailUrl, + Space: v.Space, + SourceCodePath: deploymentSourceSourceCodePathWire, + GitSource: deploymentSourceGitSourceWire, + ForwardUserAccessToken: v.ForwardUserAccessToken, + }, nil +} + +func appFromWire(w *appWire) (*App, error) { + if w == nil { + return nil, nil + } + deploymentSourceMembers := 0 + if w.SourceCodePath != nil { + deploymentSourceMembers++ + } + if w.GitSource != nil { + deploymentSourceMembers++ + } + if deploymentSourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "App.DeploymentSource") + } + computeStatusPublicValue, err := computeStatusFromWire(w.ComputeStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.ComputeStatus", err) + } + appStatusPublicValue, err := applicationStatusFromWire(w.AppStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.AppStatus", err) + } + activeDeploymentPublicValue, err := appDeploymentFromWire(w.ActiveDeployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.ActiveDeployment", err) + } + pendingDeploymentPublicValue, err := appDeploymentFromWire(w.PendingDeployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.PendingDeployment", err) + } + resourcesPublicValue, err := convertSlice(w.Resources, appResourceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.Resources", err) + } + defaultGitSourcePublicValue, err := gitSourceFromWire(w.DefaultGitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.DefaultGitSource", err) + } + gitRepositoryPublicValue, err := gitRepositoryFromWire(w.GitRepository) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.GitRepository", err) + } + telemetryExportDestinationsPublicValue, err := convertSlice(w.TelemetryExportDestinations, telemetryExportDestinationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.TelemetryExportDestinations", err) + } + var deploymentSourceSelection isApp_DeploymentSource + switch { + case w.SourceCodePath != nil: + deploymentSourceSelection = &App_DeploymentSource_SourceCodePath{SourceCodePath: *w.SourceCodePath} + case w.GitSource != nil: + deploymentSourceGitSourceConverted, err := gitSourceFromWire(w.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "App.DeploymentSource.GitSource", err) + } + deploymentSourceSelection = &App_DeploymentSource_GitSource{GitSource: *deploymentSourceGitSourceConverted} + } + return &App{ + Name: w.Name, + Description: w.Description, + ComputeStatus: computeStatusPublicValue, + AppStatus: appStatusPublicValue, + Url: w.Url, + ActiveDeployment: activeDeploymentPublicValue, + CreateTime: w.CreateTime, + Creator: w.Creator, + UpdateTime: w.UpdateTime, + Updater: w.Updater, + PendingDeployment: pendingDeploymentPublicValue, + Resources: resourcesPublicValue, + ServicePrincipalId: w.ServicePrincipalId, + ServicePrincipalName: w.ServicePrincipalName, + DefaultSourceCodePath: w.DefaultSourceCodePath, + DefaultGitSource: defaultGitSourcePublicValue, + BudgetPolicyId: w.BudgetPolicyId, + EffectiveBudgetPolicyId: w.EffectiveBudgetPolicyId, + ServicePrincipalClientId: w.ServicePrincipalClientId, + UserApiScopes: w.UserApiScopes, + Id: w.Id, + EffectiveUserApiScopes: w.EffectiveUserApiScopes, + Oauth2AppIntegrationId: w.Oauth2AppIntegrationId, + Oauth2AppClientId: w.Oauth2AppClientId, + ComputeSize: w.ComputeSize, + UsagePolicyId: w.UsagePolicyId, + EffectiveUsagePolicyId: w.EffectiveUsagePolicyId, + ComputeMinInstances: w.ComputeMinInstances, + ComputeMaxInstances: w.ComputeMaxInstances, + GitRepository: gitRepositoryPublicValue, + TelemetryExportDestinations: telemetryExportDestinationsPublicValue, + ThumbnailUrl: w.ThumbnailUrl, + Space: w.Space, + ForwardUserAccessToken: w.ForwardUserAccessToken, + DeploymentSource: deploymentSourceSelection, + }, nil +} + +type appDeploymentWire struct { + DeploymentId *string `json:"deployment_id,omitempty"` + SourceCodePath *string `json:"source_code_path,omitempty"` + GitSource *gitSourceWire `json:"git_source,omitempty"` + Mode AppDeployment_Mode `json:"mode,omitempty"` + DeploymentArtifacts *appDeploymentArtifactsWire `json:"deployment_artifacts,omitempty"` + Status *appDeploymentStatusWire `json:"status,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + Creator *string `json:"creator,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Command []string `json:"command,omitempty"` + EnvVars []envVarWire `json:"env_vars,omitempty"` +} + +func appDeploymentToWire(v *AppDeployment) (*appDeploymentWire, error) { + if v == nil { + return nil, nil + } + gitSourceWireValue, err := gitSourceToWire(v.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppDeployment.GitSource", err) + } + deploymentArtifactsWireValue, err := appDeploymentArtifactsToWire(v.DeploymentArtifacts) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppDeployment.DeploymentArtifacts", err) + } + statusWireValue, err := appDeploymentStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppDeployment.Status", err) + } + envVarsWireValue, err := convertSlice(v.EnvVars, envVarToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppDeployment.EnvVars", err) + } + return &appDeploymentWire{ + DeploymentId: v.DeploymentId, + SourceCodePath: v.SourceCodePath, + GitSource: gitSourceWireValue, + Mode: v.Mode, + DeploymentArtifacts: deploymentArtifactsWireValue, + Status: statusWireValue, + CreateTime: v.CreateTime, + Creator: v.Creator, + UpdateTime: v.UpdateTime, + Command: v.Command, + EnvVars: envVarsWireValue, + }, nil +} + +func appDeploymentFromWire(w *appDeploymentWire) (*AppDeployment, error) { + if w == nil { + return nil, nil + } + gitSourcePublicValue, err := gitSourceFromWire(w.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppDeployment.GitSource", err) + } + deploymentArtifactsPublicValue, err := appDeploymentArtifactsFromWire(w.DeploymentArtifacts) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppDeployment.DeploymentArtifacts", err) + } + statusPublicValue, err := appDeploymentStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppDeployment.Status", err) + } + envVarsPublicValue, err := convertSlice(w.EnvVars, envVarFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppDeployment.EnvVars", err) + } + return &AppDeployment{ + DeploymentId: w.DeploymentId, + SourceCodePath: w.SourceCodePath, + GitSource: gitSourcePublicValue, + Mode: w.Mode, + DeploymentArtifacts: deploymentArtifactsPublicValue, + Status: statusPublicValue, + CreateTime: w.CreateTime, + Creator: w.Creator, + UpdateTime: w.UpdateTime, + Command: w.Command, + EnvVars: envVarsPublicValue, + }, nil +} + +type appDeploymentArtifactsWire struct { + SourceCodePath *string `json:"source_code_path,omitempty"` +} + +func appDeploymentArtifactsToWire(v *AppDeploymentArtifacts) (*appDeploymentArtifactsWire, error) { + if v == nil { + return nil, nil + } + return &appDeploymentArtifactsWire{ + SourceCodePath: v.SourceCodePath, + }, nil +} + +func appDeploymentArtifactsFromWire(w *appDeploymentArtifactsWire) (*AppDeploymentArtifacts, error) { + if w == nil { + return nil, nil + } + return &AppDeploymentArtifacts{ + SourceCodePath: w.SourceCodePath, + }, nil +} + +type appDeploymentStatusWire struct { + State AppDeployment_State `json:"state,omitempty"` + Message *string `json:"message,omitempty"` +} + +func appDeploymentStatusToWire(v *AppDeploymentStatus) (*appDeploymentStatusWire, error) { + if v == nil { + return nil, nil + } + return &appDeploymentStatusWire{ + State: v.State, + Message: v.Message, + }, nil +} + +func appDeploymentStatusFromWire(w *appDeploymentStatusWire) (*AppDeploymentStatus, error) { + if w == nil { + return nil, nil + } + return &AppDeploymentStatus{ + State: w.State, + Message: w.Message, + }, nil +} + +type appManifestWire struct { + Version *int `json:"version,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + ResourceSpecs []appManifest_AppResourceSpecWire `json:"resource_specs,omitempty"` +} + +func appManifestToWire(v *AppManifest) (*appManifestWire, error) { + if v == nil { + return nil, nil + } + resourceSpecsWireValue, err := convertSlice(v.ResourceSpecs, appManifest_AppResourceSpecToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest.ResourceSpecs", err) + } + return &appManifestWire{ + Version: v.Version, + Name: v.Name, + Description: v.Description, + ResourceSpecs: resourceSpecsWireValue, + }, nil +} + +func appManifestFromWire(w *appManifestWire) (*AppManifest, error) { + if w == nil { + return nil, nil + } + resourceSpecsPublicValue, err := convertSlice(w.ResourceSpecs, appManifest_AppResourceSpecFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest.ResourceSpecs", err) + } + return &AppManifest{ + Version: w.Version, + Name: w.Name, + Description: w.Description, + ResourceSpecs: resourceSpecsPublicValue, + }, nil +} + +type appManifest_AppResourceExperimentSpecWire struct { + Permission AppManifest_AppResourceExperimentSpec_ExperimentPermission `json:"permission,omitempty"` +} + +func appManifest_AppResourceExperimentSpecToWire(v *AppManifest_AppResourceExperimentSpec) (*appManifest_AppResourceExperimentSpecWire, error) { + if v == nil { + return nil, nil + } + return &appManifest_AppResourceExperimentSpecWire{ + Permission: v.Permission, + }, nil +} + +func appManifest_AppResourceExperimentSpecFromWire(w *appManifest_AppResourceExperimentSpecWire) (*AppManifest_AppResourceExperimentSpec, error) { + if w == nil { + return nil, nil + } + return &AppManifest_AppResourceExperimentSpec{ + Permission: w.Permission, + }, nil +} + +type appManifest_AppResourceJobSpecWire struct { + Permission AppManifest_AppResourceJobSpec_JobPermission `json:"permission,omitempty"` +} + +func appManifest_AppResourceJobSpecToWire(v *AppManifest_AppResourceJobSpec) (*appManifest_AppResourceJobSpecWire, error) { + if v == nil { + return nil, nil + } + return &appManifest_AppResourceJobSpecWire{ + Permission: v.Permission, + }, nil +} + +func appManifest_AppResourceJobSpecFromWire(w *appManifest_AppResourceJobSpecWire) (*AppManifest_AppResourceJobSpec, error) { + if w == nil { + return nil, nil + } + return &AppManifest_AppResourceJobSpec{ + Permission: w.Permission, + }, nil +} + +type appManifest_AppResourceSecretSpecWire struct { + Permission AppManifest_AppResourceSecretSpec_SecretPermission `json:"permission,omitempty"` +} + +func appManifest_AppResourceSecretSpecToWire(v *AppManifest_AppResourceSecretSpec) (*appManifest_AppResourceSecretSpecWire, error) { + if v == nil { + return nil, nil + } + return &appManifest_AppResourceSecretSpecWire{ + Permission: v.Permission, + }, nil +} + +func appManifest_AppResourceSecretSpecFromWire(w *appManifest_AppResourceSecretSpecWire) (*AppManifest_AppResourceSecretSpec, error) { + if w == nil { + return nil, nil + } + return &AppManifest_AppResourceSecretSpec{ + Permission: w.Permission, + }, nil +} + +type appManifest_AppResourceServingEndpointSpecWire struct { + Permission AppManifest_AppResourceServingEndpointSpec_ServingEndpointPermission `json:"permission,omitempty"` +} + +func appManifest_AppResourceServingEndpointSpecToWire(v *AppManifest_AppResourceServingEndpointSpec) (*appManifest_AppResourceServingEndpointSpecWire, error) { + if v == nil { + return nil, nil + } + return &appManifest_AppResourceServingEndpointSpecWire{ + Permission: v.Permission, + }, nil +} + +func appManifest_AppResourceServingEndpointSpecFromWire(w *appManifest_AppResourceServingEndpointSpecWire) (*AppManifest_AppResourceServingEndpointSpec, error) { + if w == nil { + return nil, nil + } + return &AppManifest_AppResourceServingEndpointSpec{ + Permission: w.Permission, + }, nil +} + +type appManifest_AppResourceSpecWire struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + SecretSpec *appManifest_AppResourceSecretSpecWire `json:"secret_spec,omitempty"` + SqlWarehouseSpec *appManifest_AppResourceSqlWarehouseSpecWire `json:"sql_warehouse_spec,omitempty"` + ServingEndpointSpec *appManifest_AppResourceServingEndpointSpecWire `json:"serving_endpoint_spec,omitempty"` + JobSpec *appManifest_AppResourceJobSpecWire `json:"job_spec,omitempty"` + UcSecurableSpec *appManifest_AppResourceUcSecurableSpecWire `json:"uc_securable_spec,omitempty"` + ExperimentSpec *appManifest_AppResourceExperimentSpecWire `json:"experiment_spec,omitempty"` +} + +func appManifest_AppResourceSpecToWire(v *AppManifest_AppResourceSpec) (*appManifest_AppResourceSpecWire, error) { + if v == nil { + return nil, nil + } + var resourceSecretSpecWire *appManifest_AppResourceSecretSpecWire + var resourceSqlWarehouseSpecWire *appManifest_AppResourceSqlWarehouseSpecWire + var resourceServingEndpointSpecWire *appManifest_AppResourceServingEndpointSpecWire + var resourceJobSpecWire *appManifest_AppResourceJobSpecWire + var resourceUcSecurableSpecWire *appManifest_AppResourceUcSecurableSpecWire + var resourceExperimentSpecWire *appManifest_AppResourceExperimentSpecWire + switch value := v.Resource.(type) { + case nil: + case *AppManifest_AppResourceSpec_Resource_SecretSpec: + if value != nil { + resourceSecretSpecConverted, err := appManifest_AppResourceSecretSpecToWire(&value.SecretSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.SecretSpec", err) + } + resourceSecretSpecWire = resourceSecretSpecConverted + } + case *AppManifest_AppResourceSpec_Resource_SqlWarehouseSpec: + if value != nil { + resourceSqlWarehouseSpecConverted, err := appManifest_AppResourceSqlWarehouseSpecToWire(&value.SqlWarehouseSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.SqlWarehouseSpec", err) + } + resourceSqlWarehouseSpecWire = resourceSqlWarehouseSpecConverted + } + case *AppManifest_AppResourceSpec_Resource_ServingEndpointSpec: + if value != nil { + resourceServingEndpointSpecConverted, err := appManifest_AppResourceServingEndpointSpecToWire(&value.ServingEndpointSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.ServingEndpointSpec", err) + } + resourceServingEndpointSpecWire = resourceServingEndpointSpecConverted + } + case *AppManifest_AppResourceSpec_Resource_JobSpec: + if value != nil { + resourceJobSpecConverted, err := appManifest_AppResourceJobSpecToWire(&value.JobSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.JobSpec", err) + } + resourceJobSpecWire = resourceJobSpecConverted + } + case *AppManifest_AppResourceSpec_Resource_UcSecurableSpec: + if value != nil { + resourceUcSecurableSpecConverted, err := appManifest_AppResourceUcSecurableSpecToWire(&value.UcSecurableSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.UcSecurableSpec", err) + } + resourceUcSecurableSpecWire = resourceUcSecurableSpecConverted + } + case *AppManifest_AppResourceSpec_Resource_ExperimentSpec: + if value != nil { + resourceExperimentSpecConverted, err := appManifest_AppResourceExperimentSpecToWire(&value.ExperimentSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.ExperimentSpec", err) + } + resourceExperimentSpecWire = resourceExperimentSpecConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AppManifest_AppResourceSpec.Resource", value) + } + return &appManifest_AppResourceSpecWire{ + Name: v.Name, + Description: v.Description, + SecretSpec: resourceSecretSpecWire, + SqlWarehouseSpec: resourceSqlWarehouseSpecWire, + ServingEndpointSpec: resourceServingEndpointSpecWire, + JobSpec: resourceJobSpecWire, + UcSecurableSpec: resourceUcSecurableSpecWire, + ExperimentSpec: resourceExperimentSpecWire, + }, nil +} + +func appManifest_AppResourceSpecFromWire(w *appManifest_AppResourceSpecWire) (*AppManifest_AppResourceSpec, error) { + if w == nil { + return nil, nil + } + resourceMembers := 0 + if w.SecretSpec != nil { + resourceMembers++ + } + if w.SqlWarehouseSpec != nil { + resourceMembers++ + } + if w.ServingEndpointSpec != nil { + resourceMembers++ + } + if w.JobSpec != nil { + resourceMembers++ + } + if w.UcSecurableSpec != nil { + resourceMembers++ + } + if w.ExperimentSpec != nil { + resourceMembers++ + } + if resourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AppManifest_AppResourceSpec.Resource") + } + var resourceSelection isAppManifest_AppResourceSpec_Resource + switch { + case w.SecretSpec != nil: + resourceSecretSpecConverted, err := appManifest_AppResourceSecretSpecFromWire(w.SecretSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.SecretSpec", err) + } + resourceSelection = &AppManifest_AppResourceSpec_Resource_SecretSpec{SecretSpec: *resourceSecretSpecConverted} + case w.SqlWarehouseSpec != nil: + resourceSqlWarehouseSpecConverted, err := appManifest_AppResourceSqlWarehouseSpecFromWire(w.SqlWarehouseSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.SqlWarehouseSpec", err) + } + resourceSelection = &AppManifest_AppResourceSpec_Resource_SqlWarehouseSpec{SqlWarehouseSpec: *resourceSqlWarehouseSpecConverted} + case w.ServingEndpointSpec != nil: + resourceServingEndpointSpecConverted, err := appManifest_AppResourceServingEndpointSpecFromWire(w.ServingEndpointSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.ServingEndpointSpec", err) + } + resourceSelection = &AppManifest_AppResourceSpec_Resource_ServingEndpointSpec{ServingEndpointSpec: *resourceServingEndpointSpecConverted} + case w.JobSpec != nil: + resourceJobSpecConverted, err := appManifest_AppResourceJobSpecFromWire(w.JobSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.JobSpec", err) + } + resourceSelection = &AppManifest_AppResourceSpec_Resource_JobSpec{JobSpec: *resourceJobSpecConverted} + case w.UcSecurableSpec != nil: + resourceUcSecurableSpecConverted, err := appManifest_AppResourceUcSecurableSpecFromWire(w.UcSecurableSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.UcSecurableSpec", err) + } + resourceSelection = &AppManifest_AppResourceSpec_Resource_UcSecurableSpec{UcSecurableSpec: *resourceUcSecurableSpecConverted} + case w.ExperimentSpec != nil: + resourceExperimentSpecConverted, err := appManifest_AppResourceExperimentSpecFromWire(w.ExperimentSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppManifest_AppResourceSpec.Resource.ExperimentSpec", err) + } + resourceSelection = &AppManifest_AppResourceSpec_Resource_ExperimentSpec{ExperimentSpec: *resourceExperimentSpecConverted} + } + return &AppManifest_AppResourceSpec{ + Name: w.Name, + Description: w.Description, + Resource: resourceSelection, + }, nil +} + +type appManifest_AppResourceSqlWarehouseSpecWire struct { + Permission AppManifest_AppResourceSqlWarehouseSpec_SqlWarehousePermission `json:"permission,omitempty"` +} + +func appManifest_AppResourceSqlWarehouseSpecToWire(v *AppManifest_AppResourceSqlWarehouseSpec) (*appManifest_AppResourceSqlWarehouseSpecWire, error) { + if v == nil { + return nil, nil + } + return &appManifest_AppResourceSqlWarehouseSpecWire{ + Permission: v.Permission, + }, nil +} + +func appManifest_AppResourceSqlWarehouseSpecFromWire(w *appManifest_AppResourceSqlWarehouseSpecWire) (*AppManifest_AppResourceSqlWarehouseSpec, error) { + if w == nil { + return nil, nil + } + return &AppManifest_AppResourceSqlWarehouseSpec{ + Permission: w.Permission, + }, nil +} + +type appManifest_AppResourceUcSecurableSpecWire struct { + SecurableType AppManifest_AppResourceUcSecurableSpec_UcSecurableType `json:"securable_type,omitempty"` + Permission AppManifest_AppResourceUcSecurableSpec_UcSecurablePermission `json:"permission,omitempty"` +} + +func appManifest_AppResourceUcSecurableSpecToWire(v *AppManifest_AppResourceUcSecurableSpec) (*appManifest_AppResourceUcSecurableSpecWire, error) { + if v == nil { + return nil, nil + } + return &appManifest_AppResourceUcSecurableSpecWire{ + SecurableType: v.SecurableType, + Permission: v.Permission, + }, nil +} + +func appManifest_AppResourceUcSecurableSpecFromWire(w *appManifest_AppResourceUcSecurableSpecWire) (*AppManifest_AppResourceUcSecurableSpec, error) { + if w == nil { + return nil, nil + } + return &AppManifest_AppResourceUcSecurableSpec{ + SecurableType: w.SecurableType, + Permission: w.Permission, + }, nil +} + +type appResourceWire struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + Secret *appResourceSecretWire `json:"secret,omitempty"` + SqlWarehouse *appResourceSqlWarehouseWire `json:"sql_warehouse,omitempty"` + ServingEndpoint *appResourceServingEndpointWire `json:"serving_endpoint,omitempty"` + Job *appResourceJobWire `json:"job,omitempty"` + UcSecurable *appResourceUcSecurableWire `json:"uc_securable,omitempty"` + Database *appResourceDatabaseWire `json:"database,omitempty"` + GenieSpace *appResourceGenieSpaceWire `json:"genie_space,omitempty"` + Experiment *appResourceExperimentWire `json:"experiment,omitempty"` + App *appResourceAppWire `json:"app,omitempty"` + Postgres *appResourcePostgresWire `json:"postgres,omitempty"` +} + +func appResourceToWire(v *AppResource) (*appResourceWire, error) { + if v == nil { + return nil, nil + } + var resourceSecretWire *appResourceSecretWire + var resourceSqlWarehouseWire *appResourceSqlWarehouseWire + var resourceServingEndpointWire *appResourceServingEndpointWire + var resourceJobWire *appResourceJobWire + var resourceUcSecurableWire *appResourceUcSecurableWire + var resourceDatabaseWire *appResourceDatabaseWire + var resourceGenieSpaceWire *appResourceGenieSpaceWire + var resourceExperimentWire *appResourceExperimentWire + var resourceAppWire *appResourceAppWire + var resourcePostgresWire *appResourcePostgresWire + switch value := v.Resource.(type) { + case nil: + case *AppResource_Resource_Secret: + if value != nil { + resourceSecretConverted, err := appResourceSecretToWire(&value.Secret) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.Secret", err) + } + resourceSecretWire = resourceSecretConverted + } + case *AppResource_Resource_SqlWarehouse: + if value != nil { + resourceSqlWarehouseConverted, err := appResourceSqlWarehouseToWire(&value.SqlWarehouse) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.SqlWarehouse", err) + } + resourceSqlWarehouseWire = resourceSqlWarehouseConverted + } + case *AppResource_Resource_ServingEndpoint: + if value != nil { + resourceServingEndpointConverted, err := appResourceServingEndpointToWire(&value.ServingEndpoint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.ServingEndpoint", err) + } + resourceServingEndpointWire = resourceServingEndpointConverted + } + case *AppResource_Resource_Job: + if value != nil { + resourceJobConverted, err := appResourceJobToWire(&value.Job) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.Job", err) + } + resourceJobWire = resourceJobConverted + } + case *AppResource_Resource_UcSecurable: + if value != nil { + resourceUcSecurableConverted, err := appResourceUcSecurableToWire(&value.UcSecurable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.UcSecurable", err) + } + resourceUcSecurableWire = resourceUcSecurableConverted + } + case *AppResource_Resource_Database: + if value != nil { + resourceDatabaseConverted, err := appResourceDatabaseToWire(&value.Database) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.Database", err) + } + resourceDatabaseWire = resourceDatabaseConverted + } + case *AppResource_Resource_GenieSpace: + if value != nil { + resourceGenieSpaceConverted, err := appResourceGenieSpaceToWire(&value.GenieSpace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.GenieSpace", err) + } + resourceGenieSpaceWire = resourceGenieSpaceConverted + } + case *AppResource_Resource_Experiment: + if value != nil { + resourceExperimentConverted, err := appResourceExperimentToWire(&value.Experiment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.Experiment", err) + } + resourceExperimentWire = resourceExperimentConverted + } + case *AppResource_Resource_App: + if value != nil { + resourceAppConverted, err := appResourceAppToWire(&value.App) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.App", err) + } + resourceAppWire = resourceAppConverted + } + case *AppResource_Resource_Postgres: + if value != nil { + resourcePostgresConverted, err := appResourcePostgresToWire(&value.Postgres) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.Postgres", err) + } + resourcePostgresWire = resourcePostgresConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AppResource.Resource", value) + } + return &appResourceWire{ + Name: v.Name, + Description: v.Description, + Secret: resourceSecretWire, + SqlWarehouse: resourceSqlWarehouseWire, + ServingEndpoint: resourceServingEndpointWire, + Job: resourceJobWire, + UcSecurable: resourceUcSecurableWire, + Database: resourceDatabaseWire, + GenieSpace: resourceGenieSpaceWire, + Experiment: resourceExperimentWire, + App: resourceAppWire, + Postgres: resourcePostgresWire, + }, nil +} + +func appResourceFromWire(w *appResourceWire) (*AppResource, error) { + if w == nil { + return nil, nil + } + resourceMembers := 0 + if w.Secret != nil { + resourceMembers++ + } + if w.SqlWarehouse != nil { + resourceMembers++ + } + if w.ServingEndpoint != nil { + resourceMembers++ + } + if w.Job != nil { + resourceMembers++ + } + if w.UcSecurable != nil { + resourceMembers++ + } + if w.Database != nil { + resourceMembers++ + } + if w.GenieSpace != nil { + resourceMembers++ + } + if w.Experiment != nil { + resourceMembers++ + } + if w.App != nil { + resourceMembers++ + } + if w.Postgres != nil { + resourceMembers++ + } + if resourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AppResource.Resource") + } + var resourceSelection isAppResource_Resource + switch { + case w.Secret != nil: + resourceSecretConverted, err := appResourceSecretFromWire(w.Secret) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.Secret", err) + } + resourceSelection = &AppResource_Resource_Secret{Secret: *resourceSecretConverted} + case w.SqlWarehouse != nil: + resourceSqlWarehouseConverted, err := appResourceSqlWarehouseFromWire(w.SqlWarehouse) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.SqlWarehouse", err) + } + resourceSelection = &AppResource_Resource_SqlWarehouse{SqlWarehouse: *resourceSqlWarehouseConverted} + case w.ServingEndpoint != nil: + resourceServingEndpointConverted, err := appResourceServingEndpointFromWire(w.ServingEndpoint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.ServingEndpoint", err) + } + resourceSelection = &AppResource_Resource_ServingEndpoint{ServingEndpoint: *resourceServingEndpointConverted} + case w.Job != nil: + resourceJobConverted, err := appResourceJobFromWire(w.Job) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.Job", err) + } + resourceSelection = &AppResource_Resource_Job{Job: *resourceJobConverted} + case w.UcSecurable != nil: + resourceUcSecurableConverted, err := appResourceUcSecurableFromWire(w.UcSecurable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.UcSecurable", err) + } + resourceSelection = &AppResource_Resource_UcSecurable{UcSecurable: *resourceUcSecurableConverted} + case w.Database != nil: + resourceDatabaseConverted, err := appResourceDatabaseFromWire(w.Database) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.Database", err) + } + resourceSelection = &AppResource_Resource_Database{Database: *resourceDatabaseConverted} + case w.GenieSpace != nil: + resourceGenieSpaceConverted, err := appResourceGenieSpaceFromWire(w.GenieSpace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.GenieSpace", err) + } + resourceSelection = &AppResource_Resource_GenieSpace{GenieSpace: *resourceGenieSpaceConverted} + case w.Experiment != nil: + resourceExperimentConverted, err := appResourceExperimentFromWire(w.Experiment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.Experiment", err) + } + resourceSelection = &AppResource_Resource_Experiment{Experiment: *resourceExperimentConverted} + case w.App != nil: + resourceAppConverted, err := appResourceAppFromWire(w.App) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.App", err) + } + resourceSelection = &AppResource_Resource_App{App: *resourceAppConverted} + case w.Postgres != nil: + resourcePostgresConverted, err := appResourcePostgresFromWire(w.Postgres) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppResource.Resource.Postgres", err) + } + resourceSelection = &AppResource_Resource_Postgres{Postgres: *resourcePostgresConverted} + } + return &AppResource{ + Name: w.Name, + Description: w.Description, + Resource: resourceSelection, + }, nil +} + +type appResourceAppWire struct { + Name *string `json:"name,omitempty"` + Permission AppResourceApp_AppPermission `json:"permission,omitempty"` +} + +func appResourceAppToWire(v *AppResourceApp) (*appResourceAppWire, error) { + if v == nil { + return nil, nil + } + return &appResourceAppWire{ + Name: v.Name, + Permission: v.Permission, + }, nil +} + +func appResourceAppFromWire(w *appResourceAppWire) (*AppResourceApp, error) { + if w == nil { + return nil, nil + } + return &AppResourceApp{ + Name: w.Name, + Permission: w.Permission, + }, nil +} + +type appResourceDatabaseWire struct { + InstanceName *string `json:"instance_name,omitempty"` + DatabaseName *string `json:"database_name,omitempty"` + Permission AppResourceDatabase_DatabasePermission `json:"permission,omitempty"` +} + +func appResourceDatabaseToWire(v *AppResourceDatabase) (*appResourceDatabaseWire, error) { + if v == nil { + return nil, nil + } + return &appResourceDatabaseWire{ + InstanceName: v.InstanceName, + DatabaseName: v.DatabaseName, + Permission: v.Permission, + }, nil +} + +func appResourceDatabaseFromWire(w *appResourceDatabaseWire) (*AppResourceDatabase, error) { + if w == nil { + return nil, nil + } + return &AppResourceDatabase{ + InstanceName: w.InstanceName, + DatabaseName: w.DatabaseName, + Permission: w.Permission, + }, nil +} + +type appResourceExperimentWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` + Permission AppResourceExperiment_ExperimentPermission `json:"permission,omitempty"` +} + +func appResourceExperimentToWire(v *AppResourceExperiment) (*appResourceExperimentWire, error) { + if v == nil { + return nil, nil + } + return &appResourceExperimentWire{ + ExperimentId: v.ExperimentId, + Permission: v.Permission, + }, nil +} + +func appResourceExperimentFromWire(w *appResourceExperimentWire) (*AppResourceExperiment, error) { + if w == nil { + return nil, nil + } + return &AppResourceExperiment{ + ExperimentId: w.ExperimentId, + Permission: w.Permission, + }, nil +} + +type appResourceGenieSpaceWire struct { + Name *string `json:"name,omitempty"` + SpaceId *string `json:"space_id,omitempty"` + Permission AppResourceGenieSpace_GenieSpacePermission `json:"permission,omitempty"` +} + +func appResourceGenieSpaceToWire(v *AppResourceGenieSpace) (*appResourceGenieSpaceWire, error) { + if v == nil { + return nil, nil + } + return &appResourceGenieSpaceWire{ + Name: v.Name, + SpaceId: v.SpaceId, + Permission: v.Permission, + }, nil +} + +func appResourceGenieSpaceFromWire(w *appResourceGenieSpaceWire) (*AppResourceGenieSpace, error) { + if w == nil { + return nil, nil + } + return &AppResourceGenieSpace{ + Name: w.Name, + SpaceId: w.SpaceId, + Permission: w.Permission, + }, nil +} + +type appResourceJobWire struct { + Id *string `json:"id,omitempty"` + Permission AppResourceJob_JobPermission `json:"permission,omitempty"` +} + +func appResourceJobToWire(v *AppResourceJob) (*appResourceJobWire, error) { + if v == nil { + return nil, nil + } + return &appResourceJobWire{ + Id: v.Id, + Permission: v.Permission, + }, nil +} + +func appResourceJobFromWire(w *appResourceJobWire) (*AppResourceJob, error) { + if w == nil { + return nil, nil + } + return &AppResourceJob{ + Id: w.Id, + Permission: w.Permission, + }, nil +} + +type appResourcePostgresWire struct { + Branch *string `json:"branch,omitempty"` + Database *string `json:"database,omitempty"` + Permission AppResourcePostgres_PostgresPermission `json:"permission,omitempty"` +} + +func appResourcePostgresToWire(v *AppResourcePostgres) (*appResourcePostgresWire, error) { + if v == nil { + return nil, nil + } + return &appResourcePostgresWire{ + Branch: v.Branch, + Database: v.Database, + Permission: v.Permission, + }, nil +} + +func appResourcePostgresFromWire(w *appResourcePostgresWire) (*AppResourcePostgres, error) { + if w == nil { + return nil, nil + } + return &AppResourcePostgres{ + Branch: w.Branch, + Database: w.Database, + Permission: w.Permission, + }, nil +} + +type appResourceSecretWire struct { + Scope *string `json:"scope,omitempty"` + Key *string `json:"key,omitempty"` + Permission AppResourceSecret_SecretPermission `json:"permission,omitempty"` +} + +func appResourceSecretToWire(v *AppResourceSecret) (*appResourceSecretWire, error) { + if v == nil { + return nil, nil + } + return &appResourceSecretWire{ + Scope: v.Scope, + Key: v.Key, + Permission: v.Permission, + }, nil +} + +func appResourceSecretFromWire(w *appResourceSecretWire) (*AppResourceSecret, error) { + if w == nil { + return nil, nil + } + return &AppResourceSecret{ + Scope: w.Scope, + Key: w.Key, + Permission: w.Permission, + }, nil +} + +type appResourceServingEndpointWire struct { + Name *string `json:"name,omitempty"` + Permission AppResourceServingEndpoint_ServingEndpointPermission `json:"permission,omitempty"` +} + +func appResourceServingEndpointToWire(v *AppResourceServingEndpoint) (*appResourceServingEndpointWire, error) { + if v == nil { + return nil, nil + } + return &appResourceServingEndpointWire{ + Name: v.Name, + Permission: v.Permission, + }, nil +} + +func appResourceServingEndpointFromWire(w *appResourceServingEndpointWire) (*AppResourceServingEndpoint, error) { + if w == nil { + return nil, nil + } + return &AppResourceServingEndpoint{ + Name: w.Name, + Permission: w.Permission, + }, nil +} + +type appResourceSqlWarehouseWire struct { + Id *string `json:"id,omitempty"` + Permission AppResourceSqlWarehouse_SqlWarehousePermission `json:"permission,omitempty"` +} + +func appResourceSqlWarehouseToWire(v *AppResourceSqlWarehouse) (*appResourceSqlWarehouseWire, error) { + if v == nil { + return nil, nil + } + return &appResourceSqlWarehouseWire{ + Id: v.Id, + Permission: v.Permission, + }, nil +} + +func appResourceSqlWarehouseFromWire(w *appResourceSqlWarehouseWire) (*AppResourceSqlWarehouse, error) { + if w == nil { + return nil, nil + } + return &AppResourceSqlWarehouse{ + Id: w.Id, + Permission: w.Permission, + }, nil +} + +type appResourceUcSecurableWire struct { + SecurableFullName *string `json:"securable_full_name,omitempty"` + SecurableType AppResourceUcSecurable_UcSecurableType `json:"securable_type,omitempty"` + Permission AppResourceUcSecurable_UcSecurablePermission `json:"permission,omitempty"` + SecurableKind *string `json:"securable_kind,omitempty"` +} + +func appResourceUcSecurableToWire(v *AppResourceUcSecurable) (*appResourceUcSecurableWire, error) { + if v == nil { + return nil, nil + } + return &appResourceUcSecurableWire{ + SecurableFullName: v.SecurableFullName, + SecurableType: v.SecurableType, + Permission: v.Permission, + SecurableKind: v.SecurableKind, + }, nil +} + +func appResourceUcSecurableFromWire(w *appResourceUcSecurableWire) (*AppResourceUcSecurable, error) { + if w == nil { + return nil, nil + } + return &AppResourceUcSecurable{ + SecurableFullName: w.SecurableFullName, + SecurableType: w.SecurableType, + Permission: w.Permission, + SecurableKind: w.SecurableKind, + }, nil +} + +type appThumbnailWire struct { + Thumbnail []byte `json:"thumbnail,omitempty"` +} + +func appThumbnailToWire(v *AppThumbnail) (*appThumbnailWire, error) { + if v == nil { + return nil, nil + } + return &appThumbnailWire{ + Thumbnail: v.Thumbnail, + }, nil +} + +func appThumbnailFromWire(w *appThumbnailWire) (*AppThumbnail, error) { + if w == nil { + return nil, nil + } + return &AppThumbnail{ + Thumbnail: w.Thumbnail, + }, nil +} + +type appUpdateWire struct { + Status *appUpdate_UpdateStatusWire `json:"status,omitempty"` + Description *string `json:"description,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + Resources []appResourceWire `json:"resources,omitempty"` + UserApiScopes []string `json:"user_api_scopes,omitempty"` + ComputeSize ComputeSize `json:"compute_size,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + ComputeMinInstances *int `json:"compute_min_instances,omitempty"` + ComputeMaxInstances *int `json:"compute_max_instances,omitempty"` + GitRepository *gitRepositoryWire `json:"git_repository,omitempty"` + ForwardUserAccessToken *bool `json:"forward_user_access_token,omitempty"` +} + +func appUpdateFromWire(w *appUpdateWire) (*AppUpdate, error) { + if w == nil { + return nil, nil + } + statusPublicValue, err := appUpdate_UpdateStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppUpdate.Status", err) + } + resourcesPublicValue, err := convertSlice(w.Resources, appResourceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppUpdate.Resources", err) + } + gitRepositoryPublicValue, err := gitRepositoryFromWire(w.GitRepository) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AppUpdate.GitRepository", err) + } + return &AppUpdate{ + Status: statusPublicValue, + Description: w.Description, + BudgetPolicyId: w.BudgetPolicyId, + Resources: resourcesPublicValue, + UserApiScopes: w.UserApiScopes, + ComputeSize: w.ComputeSize, + UsagePolicyId: w.UsagePolicyId, + ComputeMinInstances: w.ComputeMinInstances, + ComputeMaxInstances: w.ComputeMaxInstances, + GitRepository: gitRepositoryPublicValue, + ForwardUserAccessToken: w.ForwardUserAccessToken, + }, nil +} + +type appUpdate_UpdateStatusWire struct { + State AppUpdate_UpdateStatus_UpdateState `json:"state,omitempty"` + Message *string `json:"message,omitempty"` +} + +func appUpdate_UpdateStatusFromWire(w *appUpdate_UpdateStatusWire) (*AppUpdate_UpdateStatus, error) { + if w == nil { + return nil, nil + } + return &AppUpdate_UpdateStatus{ + State: w.State, + Message: w.Message, + }, nil +} + +type applicationStatusWire struct { + State ApplicationStatus_ApplicationState `json:"state,omitempty"` + Message *string `json:"message,omitempty"` + RunningInstances *int `json:"running_instances,omitempty"` +} + +func applicationStatusToWire(v *ApplicationStatus) (*applicationStatusWire, error) { + if v == nil { + return nil, nil + } + return &applicationStatusWire{ + State: v.State, + Message: v.Message, + RunningInstances: v.RunningInstances, + }, nil +} + +func applicationStatusFromWire(w *applicationStatusWire) (*ApplicationStatus, error) { + if w == nil { + return nil, nil + } + return &ApplicationStatus{ + State: w.State, + Message: w.Message, + RunningInstances: w.RunningInstances, + }, nil +} + +type asyncUpdateAppRequestWire struct { + App *appWire `json:"app,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` + AppName *string `json:"app_name,omitempty"` +} + +func asyncUpdateAppRequestToWire(v *AsyncUpdateAppRequest) (*asyncUpdateAppRequestWire, error) { + if v == nil { + return nil, nil + } + appWireValue, err := appToWire(v.App) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AsyncUpdateAppRequest.App", err) + } + return &asyncUpdateAppRequestWire{ + App: appWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + AppName: v.AppName, + }, nil +} + +type computeStatusWire struct { + State ComputeStatus_ComputeState `json:"state,omitempty"` + Message *string `json:"message,omitempty"` + ActiveInstances *int `json:"active_instances,omitempty"` +} + +func computeStatusToWire(v *ComputeStatus) (*computeStatusWire, error) { + if v == nil { + return nil, nil + } + return &computeStatusWire{ + State: v.State, + Message: v.Message, + ActiveInstances: v.ActiveInstances, + }, nil +} + +func computeStatusFromWire(w *computeStatusWire) (*ComputeStatus, error) { + if w == nil { + return nil, nil + } + return &ComputeStatus{ + State: w.State, + Message: w.Message, + ActiveInstances: w.ActiveInstances, + }, nil +} + +type createAppDeploymentRequestWire struct { + AppName *string `json:"app_name,omitempty"` + AppDeployment *appDeploymentWire `json:"app_deployment,omitempty"` +} + +func createAppDeploymentRequestToWire(v *CreateAppDeploymentRequest) (*createAppDeploymentRequestWire, error) { + if v == nil { + return nil, nil + } + appDeploymentWireValue, err := appDeploymentToWire(v.AppDeployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAppDeploymentRequest.AppDeployment", err) + } + return &createAppDeploymentRequestWire{ + AppName: v.AppName, + AppDeployment: appDeploymentWireValue, + }, nil +} + +type createAppRequestWire struct { + App *appWire `json:"app,omitempty"` + NoCompute *bool `json:"no_compute,omitempty"` +} + +func createAppRequestToWire(v *CreateAppRequest) (*createAppRequestWire, error) { + if v == nil { + return nil, nil + } + appWireValue, err := appToWire(v.App) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAppRequest.App", err) + } + return &createAppRequestWire{ + App: appWireValue, + NoCompute: v.NoCompute, + }, nil +} + +type createCustomTemplateRequestWire struct { + Template *customTemplateWire `json:"template,omitempty"` +} + +func createCustomTemplateRequestToWire(v *CreateCustomTemplateRequest) (*createCustomTemplateRequestWire, error) { + if v == nil { + return nil, nil + } + templateWireValue, err := customTemplateToWire(v.Template) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCustomTemplateRequest.Template", err) + } + return &createCustomTemplateRequestWire{ + Template: templateWireValue, + }, nil +} + +type createSpaceRequestWire struct { + Space *spaceWire `json:"space,omitempty"` +} + +func createSpaceRequestToWire(v *CreateSpaceRequest) (*createSpaceRequestWire, error) { + if v == nil { + return nil, nil + } + spaceWireValue, err := spaceToWire(v.Space) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateSpaceRequest.Space", err) + } + return &createSpaceRequestWire{ + Space: spaceWireValue, + }, nil +} + +type customTemplateWire struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + GitRepo *string `json:"git_repo,omitempty"` + Path *string `json:"path,omitempty"` + Manifest *appManifestWire `json:"manifest,omitempty"` + GitProvider *string `json:"git_provider,omitempty"` + Creator *string `json:"creator,omitempty"` +} + +func customTemplateToWire(v *CustomTemplate) (*customTemplateWire, error) { + if v == nil { + return nil, nil + } + manifestWireValue, err := appManifestToWire(v.Manifest) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomTemplate.Manifest", err) + } + return &customTemplateWire{ + Name: v.Name, + Description: v.Description, + GitRepo: v.GitRepo, + Path: v.Path, + Manifest: manifestWireValue, + GitProvider: v.GitProvider, + Creator: v.Creator, + }, nil +} + +func customTemplateFromWire(w *customTemplateWire) (*CustomTemplate, error) { + if w == nil { + return nil, nil + } + manifestPublicValue, err := appManifestFromWire(w.Manifest) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomTemplate.Manifest", err) + } + return &CustomTemplate{ + Name: w.Name, + Description: w.Description, + GitRepo: w.GitRepo, + Path: w.Path, + Manifest: manifestPublicValue, + GitProvider: w.GitProvider, + Creator: w.Creator, + }, nil +} + +type envVarWire struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` + ValueFrom *string `json:"value_from,omitempty"` +} + +func envVarToWire(v *EnvVar) (*envVarWire, error) { + if v == nil { + return nil, nil + } + var sourceValueWire *string + var sourceValueFromWire *string + switch value := v.Source.(type) { + case nil: + case *EnvVar_Source_Value: + if value != nil { + sourceValueWire = new(value.Value) + } + case *EnvVar_Source_ValueFrom: + if value != nil { + sourceValueFromWire = new(value.ValueFrom) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "EnvVar.Source", value) + } + return &envVarWire{ + Name: v.Name, + Value: sourceValueWire, + ValueFrom: sourceValueFromWire, + }, nil +} + +func envVarFromWire(w *envVarWire) (*EnvVar, error) { + if w == nil { + return nil, nil + } + sourceMembers := 0 + if w.Value != nil { + sourceMembers++ + } + if w.ValueFrom != nil { + sourceMembers++ + } + if sourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "EnvVar.Source") + } + var sourceSelection isEnvVar_Source + switch { + case w.Value != nil: + sourceSelection = &EnvVar_Source_Value{Value: *w.Value} + case w.ValueFrom != nil: + sourceSelection = &EnvVar_Source_ValueFrom{ValueFrom: *w.ValueFrom} + } + return &EnvVar{ + Name: w.Name, + Source: sourceSelection, + }, nil +} + +type gitRepositoryWire struct { + Url *string `json:"url,omitempty"` + Provider *string `json:"provider,omitempty"` + AutoDeploy *bool `json:"auto_deploy,omitempty"` + CallerCredentialId *int64 `json:"caller_credential_id,omitempty"` +} + +func gitRepositoryToWire(v *GitRepository) (*gitRepositoryWire, error) { + if v == nil { + return nil, nil + } + return &gitRepositoryWire{ + Url: v.Url, + Provider: v.Provider, + AutoDeploy: v.AutoDeploy, + CallerCredentialId: v.CallerCredentialId, + }, nil +} + +func gitRepositoryFromWire(w *gitRepositoryWire) (*GitRepository, error) { + if w == nil { + return nil, nil + } + return &GitRepository{ + Url: w.Url, + Provider: w.Provider, + AutoDeploy: w.AutoDeploy, + CallerCredentialId: w.CallerCredentialId, + }, nil +} + +type gitSourceWire struct { + GitRepository *gitRepositoryWire `json:"git_repository,omitempty"` + Branch *string `json:"branch,omitempty"` + Tag *string `json:"tag,omitempty"` + Commit *string `json:"commit,omitempty"` + SourceCodePath *string `json:"source_code_path,omitempty"` + ResolvedCommit *string `json:"resolved_commit,omitempty"` +} + +func gitSourceToWire(v *GitSource) (*gitSourceWire, error) { + if v == nil { + return nil, nil + } + gitRepositoryWireValue, err := gitRepositoryToWire(v.GitRepository) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GitSource.GitRepository", err) + } + var referenceBranchWire *string + var referenceTagWire *string + var referenceCommitWire *string + switch value := v.Reference.(type) { + case nil: + case *GitSource_Reference_Branch: + if value != nil { + referenceBranchWire = new(value.Branch) + } + case *GitSource_Reference_Tag: + if value != nil { + referenceTagWire = new(value.Tag) + } + case *GitSource_Reference_Commit: + if value != nil { + referenceCommitWire = new(value.Commit) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "GitSource.Reference", value) + } + return &gitSourceWire{ + GitRepository: gitRepositoryWireValue, + Branch: referenceBranchWire, + Tag: referenceTagWire, + Commit: referenceCommitWire, + SourceCodePath: v.SourceCodePath, + ResolvedCommit: v.ResolvedCommit, + }, nil +} + +func gitSourceFromWire(w *gitSourceWire) (*GitSource, error) { + if w == nil { + return nil, nil + } + referenceMembers := 0 + if w.Branch != nil { + referenceMembers++ + } + if w.Tag != nil { + referenceMembers++ + } + if w.Commit != nil { + referenceMembers++ + } + if referenceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "GitSource.Reference") + } + gitRepositoryPublicValue, err := gitRepositoryFromWire(w.GitRepository) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GitSource.GitRepository", err) + } + var referenceSelection isGitSource_Reference + switch { + case w.Branch != nil: + referenceSelection = &GitSource_Reference_Branch{Branch: *w.Branch} + case w.Tag != nil: + referenceSelection = &GitSource_Reference_Tag{Tag: *w.Tag} + case w.Commit != nil: + referenceSelection = &GitSource_Reference_Commit{Commit: *w.Commit} + } + return &GitSource{ + GitRepository: gitRepositoryPublicValue, + SourceCodePath: w.SourceCodePath, + ResolvedCommit: w.ResolvedCommit, + Reference: referenceSelection, + }, nil +} + +type listAppDeploymentsRequestWire struct { + AppName *string `json:"app_name,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listAppDeploymentsRequestToWire(v *ListAppDeploymentsRequest) (*listAppDeploymentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAppDeploymentsRequestWire{ + AppName: v.AppName, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listAppDeploymentsResponseWire struct { + AppDeployments []appDeploymentWire `json:"app_deployments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listAppDeploymentsResponseFromWire(w *listAppDeploymentsResponseWire) (*ListAppDeploymentsResponse, error) { + if w == nil { + return nil, nil + } + appDeploymentsPublicValue, err := convertSlice(w.AppDeployments, appDeploymentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAppDeploymentsResponse.AppDeployments", err) + } + return &ListAppDeploymentsResponse{ + AppDeployments: appDeploymentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listAppsRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` + Space *string `json:"space,omitempty"` +} + +func listAppsRequestToWire(v *ListAppsRequest) (*listAppsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAppsRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + Space: v.Space, + }, nil +} + +type listAppsResponseWire struct { + Apps []appWire `json:"apps,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listAppsResponseFromWire(w *listAppsResponseWire) (*ListAppsResponse, error) { + if w == nil { + return nil, nil + } + appsPublicValue, err := convertSlice(w.Apps, appFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAppsResponse.Apps", err) + } + return &ListAppsResponse{ + Apps: appsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listCustomTemplatesRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listCustomTemplatesRequestToWire(v *ListCustomTemplatesRequest) (*listCustomTemplatesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCustomTemplatesRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listCustomTemplatesResponseWire struct { + Templates []customTemplateWire `json:"templates,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCustomTemplatesResponseFromWire(w *listCustomTemplatesResponseWire) (*ListCustomTemplatesResponse, error) { + if w == nil { + return nil, nil + } + templatesPublicValue, err := convertSlice(w.Templates, customTemplateFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCustomTemplatesResponse.Templates", err) + } + return &ListCustomTemplatesResponse{ + Templates: templatesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listSpacesRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listSpacesRequestToWire(v *ListSpacesRequest) (*listSpacesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSpacesRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listSpacesResponseWire struct { + Spaces []spaceWire `json:"spaces,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listSpacesResponseFromWire(w *listSpacesResponseWire) (*ListSpacesResponse, error) { + if w == nil { + return nil, nil + } + spacesPublicValue, err := convertSlice(w.Spaces, spaceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListSpacesResponse.Spaces", err) + } + return &ListSpacesResponse{ + Spaces: spacesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type operationWire struct { + Name *string `json:"name,omitempty"` + Metadata json.RawMessage `json:"metadata,omitempty"` + Done *bool `json:"done,omitempty"` + Error *apiErrorWire `json:"error,omitempty"` + Response json.RawMessage `json:"response,omitempty"` +} + +func operationFromWire(w *operationWire) (*Operation, error) { + if w == nil { + return nil, nil + } + resultMembers := 0 + if w.Error != nil { + resultMembers++ + } + if w.Response != nil { + resultMembers++ + } + if resultMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Operation.Result") + } + var resultSelection isOperation_Result + switch { + case w.Error != nil: + resultErrorConverted, err := apiErrorFromWire(w.Error) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Operation.Result.Error", err) + } + resultSelection = &Operation_Result_Error{Error: *resultErrorConverted} + case w.Response != nil: + resultSelection = &Operation_Result_Response{Response: w.Response} + } + return &Operation{ + Name: w.Name, + Metadata: w.Metadata, + Done: w.Done, + Result: resultSelection, + }, nil +} + +type spaceWire struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + Status *spaceStatusWire `json:"status,omitempty"` + Id *string `json:"id,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + Creator *string `json:"creator,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Updater *string `json:"updater,omitempty"` + Resources []appResourceWire `json:"resources,omitempty"` + UserApiScopes []string `json:"user_api_scopes,omitempty"` + EffectiveUserApiScopes []string `json:"effective_user_api_scopes,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` + ServicePrincipalClientId *string `json:"service_principal_client_id,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + EffectiveUsagePolicyId *string `json:"effective_usage_policy_id,omitempty"` +} + +func spaceToWire(v *Space) (*spaceWire, error) { + if v == nil { + return nil, nil + } + statusWireValue, err := spaceStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Space.Status", err) + } + resourcesWireValue, err := convertSlice(v.Resources, appResourceToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Space.Resources", err) + } + return &spaceWire{ + Name: v.Name, + Description: v.Description, + Status: statusWireValue, + Id: v.Id, + CreateTime: v.CreateTime, + Creator: v.Creator, + UpdateTime: v.UpdateTime, + Updater: v.Updater, + Resources: resourcesWireValue, + UserApiScopes: v.UserApiScopes, + EffectiveUserApiScopes: v.EffectiveUserApiScopes, + ServicePrincipalId: v.ServicePrincipalId, + ServicePrincipalName: v.ServicePrincipalName, + ServicePrincipalClientId: v.ServicePrincipalClientId, + UsagePolicyId: v.UsagePolicyId, + EffectiveUsagePolicyId: v.EffectiveUsagePolicyId, + }, nil +} + +func spaceFromWire(w *spaceWire) (*Space, error) { + if w == nil { + return nil, nil + } + statusPublicValue, err := spaceStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Space.Status", err) + } + resourcesPublicValue, err := convertSlice(w.Resources, appResourceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Space.Resources", err) + } + return &Space{ + Name: w.Name, + Description: w.Description, + Status: statusPublicValue, + Id: w.Id, + CreateTime: w.CreateTime, + Creator: w.Creator, + UpdateTime: w.UpdateTime, + Updater: w.Updater, + Resources: resourcesPublicValue, + UserApiScopes: w.UserApiScopes, + EffectiveUserApiScopes: w.EffectiveUserApiScopes, + ServicePrincipalId: w.ServicePrincipalId, + ServicePrincipalName: w.ServicePrincipalName, + ServicePrincipalClientId: w.ServicePrincipalClientId, + UsagePolicyId: w.UsagePolicyId, + EffectiveUsagePolicyId: w.EffectiveUsagePolicyId, + }, nil +} + +type spaceStatusWire struct { + State SpaceStatus_SpaceState `json:"state,omitempty"` + Message *string `json:"message,omitempty"` +} + +func spaceStatusToWire(v *SpaceStatus) (*spaceStatusWire, error) { + if v == nil { + return nil, nil + } + return &spaceStatusWire{ + State: v.State, + Message: v.Message, + }, nil +} + +func spaceStatusFromWire(w *spaceStatusWire) (*SpaceStatus, error) { + if w == nil { + return nil, nil + } + return &SpaceStatus{ + State: w.State, + Message: w.Message, + }, nil +} + +type spaceUpdateWire struct { + Status *spaceUpdateStatusWire `json:"status,omitempty"` + Description *string `json:"description,omitempty"` + Resources []appResourceWire `json:"resources,omitempty"` + UserApiScopes []string `json:"user_api_scopes,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` +} + +func spaceUpdateFromWire(w *spaceUpdateWire) (*SpaceUpdate, error) { + if w == nil { + return nil, nil + } + statusPublicValue, err := spaceUpdateStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SpaceUpdate.Status", err) + } + resourcesPublicValue, err := convertSlice(w.Resources, appResourceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SpaceUpdate.Resources", err) + } + return &SpaceUpdate{ + Status: statusPublicValue, + Description: w.Description, + Resources: resourcesPublicValue, + UserApiScopes: w.UserApiScopes, + UsagePolicyId: w.UsagePolicyId, + }, nil +} + +type spaceUpdateStatusWire struct { + State SpaceUpdateState `json:"state,omitempty"` + Message *string `json:"message,omitempty"` +} + +func spaceUpdateStatusFromWire(w *spaceUpdateStatusWire) (*SpaceUpdateStatus, error) { + if w == nil { + return nil, nil + } + return &SpaceUpdateStatus{ + State: w.State, + Message: w.Message, + }, nil +} + +type startAppRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func startAppRequestToWire(v *StartAppRequest) (*startAppRequestWire, error) { + if v == nil { + return nil, nil + } + return &startAppRequestWire{ + Name: v.Name, + }, nil +} + +type stopAppRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func stopAppRequestToWire(v *StopAppRequest) (*stopAppRequestWire, error) { + if v == nil { + return nil, nil + } + return &stopAppRequestWire{ + Name: v.Name, + }, nil +} + +type telemetryExportDestinationWire struct { + UnityCatalog *unityCatalogWire `json:"unity_catalog,omitempty"` +} + +func telemetryExportDestinationToWire(v *TelemetryExportDestination) (*telemetryExportDestinationWire, error) { + if v == nil { + return nil, nil + } + var destinationUnityCatalogWire *unityCatalogWire + switch value := v.Destination.(type) { + case nil: + case *TelemetryExportDestination_Destination_UnityCatalog: + if value != nil { + destinationUnityCatalogConverted, err := unityCatalogToWire(&value.UnityCatalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TelemetryExportDestination.Destination.UnityCatalog", err) + } + destinationUnityCatalogWire = destinationUnityCatalogConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "TelemetryExportDestination.Destination", value) + } + return &telemetryExportDestinationWire{ + UnityCatalog: destinationUnityCatalogWire, + }, nil +} + +func telemetryExportDestinationFromWire(w *telemetryExportDestinationWire) (*TelemetryExportDestination, error) { + if w == nil { + return nil, nil + } + destinationMembers := 0 + if w.UnityCatalog != nil { + destinationMembers++ + } + if destinationMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "TelemetryExportDestination.Destination") + } + var destinationSelection isTelemetryExportDestination_Destination + switch { + case w.UnityCatalog != nil: + destinationUnityCatalogConverted, err := unityCatalogFromWire(w.UnityCatalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TelemetryExportDestination.Destination.UnityCatalog", err) + } + destinationSelection = &TelemetryExportDestination_Destination_UnityCatalog{UnityCatalog: *destinationUnityCatalogConverted} + } + return &TelemetryExportDestination{ + Destination: destinationSelection, + }, nil +} + +type unityCatalogWire struct { + LogsTable *string `json:"logs_table,omitempty"` + MetricsTable *string `json:"metrics_table,omitempty"` + TracesTable *string `json:"traces_table,omitempty"` +} + +func unityCatalogToWire(v *UnityCatalog) (*unityCatalogWire, error) { + if v == nil { + return nil, nil + } + return &unityCatalogWire{ + LogsTable: v.LogsTable, + MetricsTable: v.MetricsTable, + TracesTable: v.TracesTable, + }, nil +} + +func unityCatalogFromWire(w *unityCatalogWire) (*UnityCatalog, error) { + if w == nil { + return nil, nil + } + return &UnityCatalog{ + LogsTable: w.LogsTable, + MetricsTable: w.MetricsTable, + TracesTable: w.TracesTable, + }, nil +} + +type updateAppRequestWire struct { + App *appWire `json:"app,omitempty"` +} + +func updateAppRequestToWire(v *UpdateAppRequest) (*updateAppRequestWire, error) { + if v == nil { + return nil, nil + } + appWireValue, err := appToWire(v.App) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAppRequest.App", err) + } + return &updateAppRequestWire{ + App: appWireValue, + }, nil +} + +type updateAppThumbnailRequestWire struct { + Name *string `json:"name,omitempty"` + AppThumbnail *appThumbnailWire `json:"app_thumbnail,omitempty"` +} + +func updateAppThumbnailRequestToWire(v *UpdateAppThumbnailRequest) (*updateAppThumbnailRequestWire, error) { + if v == nil { + return nil, nil + } + appThumbnailWireValue, err := appThumbnailToWire(v.AppThumbnail) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAppThumbnailRequest.AppThumbnail", err) + } + return &updateAppThumbnailRequestWire{ + Name: v.Name, + AppThumbnail: appThumbnailWireValue, + }, nil +} + +type updateCustomTemplateRequestWire struct { + Template *customTemplateWire `json:"template,omitempty"` +} + +func updateCustomTemplateRequestToWire(v *UpdateCustomTemplateRequest) (*updateCustomTemplateRequestWire, error) { + if v == nil { + return nil, nil + } + templateWireValue, err := customTemplateToWire(v.Template) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCustomTemplateRequest.Template", err) + } + return &updateCustomTemplateRequestWire{ + Template: templateWireValue, + }, nil +} + +type updateSpaceRequestWire struct { + Space *spaceWire `json:"space,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateSpaceRequestToWire(v *UpdateSpaceRequest) (*updateSpaceRequestWire, error) { + if v == nil { + return nil, nil + } + spaceWireValue, err := spaceToWire(v.Space) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateSpaceRequest.Space", err) + } + return &updateSpaceRequestWire{ + Space: spaceWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/auth/.package.json b/auth/.package.json new file mode 100644 index 0000000..a73a2fc --- /dev/null +++ b/auth/.package.json @@ -0,0 +1,3 @@ +{ + "package": "auth" +} diff --git a/auth/CHANGELOG.md b/auth/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/auth/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/auth/credentials/default.go b/auth/credentials/default.go new file mode 100644 index 0000000..d5c6a17 --- /dev/null +++ b/auth/credentials/default.go @@ -0,0 +1,206 @@ +package credentials + +import ( + "context" + "errors" + "fmt" + "sync" + "sync/atomic" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/profiles" +) + +const authDocURL = "https://docs.databricks.com/aws/en/dev-tools/auth/index" + +var ( + // ErrNoAuthConfigured is returned when no strategy in the default chain + // could be configured from the resolved profile and environment. + ErrNoAuthConfigured = errors.New("cannot configure default credentials") + + // ErrAuthTypeNotFound is returned when the profile requests an auth_type + // that does not match any strategy in the default chain. + ErrAuthTypeNotFound = errors.New("auth type not found") +) + +// strategy is one entry in the default credential chain: a name plus a way to +// build credentials from a profile. Configure returns nil (without an error) +// when the strategy does not apply to the given profile, so the chain can move +// on to the next strategy. +type strategy struct { + name string + configure func(profiles.Profile) (auth.Credentials, error) +} + +// defaultStrategies returns the strategies tried by [NewDefaultCredentials], in +// priority order: PAT, then OAuth M2M, then the Databricks CLI (U2M). The order +// mirrors the other Databricks SDKs and must not change without consideration +// for environments compatible with more than one strategy. +func defaultStrategies() []strategy { + return []strategy{ + {name: "pat", configure: configurePAT}, + {name: "oauth-m2m", configure: configureM2M}, + {name: "databricks-cli", configure: configureU2M}, + } +} + +// DefaultCredentialsOptions configures [NewDefaultCredentials]. +type DefaultCredentialsOptions struct { + // Profile is a pre-resolved profile to use. When nil, the profile is + // resolved on first use from the default config file (~/.databrickscfg) + // and DATABRICKS_* environment variables. + Profile *profiles.Profile +} + +// NewDefaultCredentials returns [auth.Credentials] that resolve to the first +// configured authentication strategy on first use. +// +// Strategies are tried in this order: +// 1. PAT (pat). +// 2. OAuth M2M (oauth-m2m). +// 3. Databricks CLI (databricks-cli). +// +// If the profile sets auth_type, only the strategy with that name is tried. +// Resolution is deferred until the first [auth.Credentials.AuthHeaders] call +// and then memoized, so profile resolution and any network discovery happen +// lazily and at most once. +func NewDefaultCredentials(opts DefaultCredentialsOptions) auth.Credentials { + explicit := opts.Profile + loadProfile := func() (profiles.Profile, error) { + if explicit != nil { + return *explicit, nil + } + p, err := profiles.Resolve() + if err != nil { + return profiles.Profile{}, fmt.Errorf("resolving default profile: %w", err) + } + return *p, nil + } + return &defaultCredentials{ + loadProfile: loadProfile, + strategies: defaultStrategies(), + } +} + +// defaultCredentials lazily resolves a profile and selects a strategy the first +// time AuthHeaders is called. It is safe for concurrent use: resolution runs +// once under [sync.Once], and the selected credentials are published through an +// [atomic.Pointer] so Name can read them without blocking on AuthHeaders. +type defaultCredentials struct { + loadProfile func() (profiles.Profile, error) + strategies []strategy + + once sync.Once + resolved atomic.Pointer[auth.Credentials] + resolveErr error +} + +// Name returns "default" until a strategy has been selected, then the name of +// the selected strategy so callers (logging, telemetry) can tell which +// authentication method won. +func (c *defaultCredentials) Name() string { + if resolved := c.resolved.Load(); resolved != nil { + return (*resolved).Name() + } + return "default" +} + +func (c *defaultCredentials) AuthHeaders(ctx context.Context) ([]auth.Header, error) { + c.once.Do(func() { + creds, err := c.resolveChain() + if err != nil { + c.resolveErr = err + return + } + c.resolved.Store(&creds) + }) + if c.resolveErr != nil { + return nil, c.resolveErr + } + return (*c.resolved.Load()).AuthHeaders(ctx) +} + +func (c *defaultCredentials) resolveChain() (auth.Credentials, error) { + profile, err := c.loadProfile() + if err != nil { + return nil, err + } + + if profile.AuthType != "" { + return c.resolveByAuthType(profile, profile.AuthType) + } + + for _, s := range c.strategies { + creds, err := s.configure(profile) + if err != nil { + return nil, err + } + if creds != nil { + return creds, nil + } + } + return nil, fmt.Errorf("%w, please check %s to configure credentials for your preferred authentication method", ErrNoAuthConfigured, authDocURL) +} + +func (c *defaultCredentials) resolveByAuthType(profile profiles.Profile, authType string) (auth.Credentials, error) { + for _, s := range c.strategies { + if s.name != authType { + continue + } + creds, err := s.configure(profile) + if err != nil { + return nil, err + } + if creds == nil { + return nil, fmt.Errorf("%w, please check %s to configure credentials for your preferred authentication method", ErrNoAuthConfigured, authDocURL) + } + return creds, nil + } + return nil, fmt.Errorf("%w: %q, please check %s for a list of supported auth types", ErrAuthTypeNotFound, authType, authDocURL) +} + +// configurePAT selects PAT credentials when the profile has a host and a token. +func configurePAT(p profiles.Profile) (auth.Credentials, error) { + if p.Host == "" || p.Token == "" { + return nil, nil + } + return NewPATCredentials(string(p.Token)) +} + +// configureM2M selects OAuth M2M credentials when the profile has a host plus a +// client ID and client secret. The underlying token provider is wrapped in a +// cache so a token is reused until it nears expiry rather than re-minted on +// every request. +func configureM2M(p profiles.Profile) (auth.Credentials, error) { + if p.Host == "" || p.ClientID == "" || p.ClientSecret == "" { + return nil, nil + } + provider, err := NewM2MCredentials(M2MOptions{ + Host: p.Host, + ClientID: p.ClientID, + ClientSecret: string(p.ClientSecret), + }) + if err != nil { + return nil, err + } + return auth.NewTokenCredentials("oauth-m2m", auth.NewCachedTokenProvider(provider)), nil +} + +// configureU2M selects Databricks CLI (U2M) credentials when the profile was +// loaded from the config file (so its section name is known) and has a host. +// The CLI must have been logged in ahead of time via "databricks auth login". +// The underlying token provider is wrapped in a cache to avoid shelling out to +// the CLI on every request. +func configureU2M(p profiles.Profile) (auth.Credentials, error) { + if p.Host == "" || p.Name == "" { + return nil, nil + } + provider, err := NewU2MCredentials(U2MOptions{ + Profile: p.Name, + CLIPath: p.DatabricksCLIPath, + }) + if err != nil { + return nil, err + } + return auth.NewTokenCredentials("databricks-cli", auth.NewCachedTokenProvider(provider)), nil +} diff --git a/auth/credentials/default_test.go b/auth/credentials/default_test.go new file mode 100644 index 0000000..a9341c0 --- /dev/null +++ b/auth/credentials/default_test.go @@ -0,0 +1,246 @@ +package credentials + +import ( + "context" + "errors" + "sync" + "testing" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/profiles" + "github.com/google/go-cmp/cmp" +) + +const testHost = "https://workspace.example" + +// configuredStrategy returns a strategy that always builds credentials whose +// single auth header identifies the strategy by label. +func configuredStrategy(label string) strategy { + return strategy{ + name: label, + configure: func(profiles.Profile) (auth.Credentials, error) { + return auth.NewTokenCredentials(label, auth.TokenProviderFn( + func(context.Context) (*auth.Token, error) { + return &auth.Token{Value: label}, nil + }, + )), nil + }, + } +} + +// unconfiguredStrategy returns a strategy that never applies. +func unconfiguredStrategy(label string) strategy { + return strategy{ + name: label, + configure: func(profiles.Profile) (auth.Credentials, error) { return nil, nil }, + } +} + +func loaderFor(p profiles.Profile) func() (profiles.Profile, error) { + return func() (profiles.Profile, error) { return p, nil } +} + +func newTestChain(strategies []strategy, p profiles.Profile) *defaultCredentials { + return &defaultCredentials{loadProfile: loaderFor(p), strategies: strategies} +} + +func TestDefaultCredentials_Resolution(t *testing.T) { + testCases := []struct { + desc string + strategies []strategy + profile profiles.Profile + wantValue string // expected bearer token value in the Authorization header + }{ + { + desc: "returns the first configured strategy", + strategies: []strategy{{name: "pat", configure: configurePAT}, configuredStrategy("oauth-m2m")}, + profile: profiles.Profile{Host: testHost, Token: "dapi-abc"}, + wantValue: "dapi-abc", + }, + { + desc: "falls through to the next strategy when earlier ones are unconfigured", + strategies: []strategy{unconfiguredStrategy("pat"), configuredStrategy("oauth-m2m")}, + profile: profiles.Profile{Host: testHost}, + wantValue: "oauth-m2m", + }, + { + // PAT is configured and comes first, but auth_type pins oauth-m2m. + desc: "selects the strategy named by auth_type over an earlier configured strategy", + strategies: []strategy{{name: "pat", configure: configurePAT}, configuredStrategy("oauth-m2m")}, + profile: profiles.Profile{Host: testHost, Token: "dapi-abc", AuthType: "oauth-m2m"}, + wantValue: "oauth-m2m", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + creds := newTestChain(tc.strategies, tc.profile) + headers, err := creds.AuthHeaders(context.Background()) + if err != nil { + t.Fatalf("AuthHeaders() error = %v", err) + } + want := []auth.Header{{Key: "Authorization", Value: "Bearer " + tc.wantValue}} + if diff := cmp.Diff(want, headers); diff != "" { + t.Errorf("AuthHeaders() mismatch (-want +got):\n%s", diff) + } + }) + } +} + +func TestDefaultCredentials_CachesResolvedStrategy(t *testing.T) { + buildCount := 0 + counting := strategy{ + name: "counting", + configure: func(profiles.Profile) (auth.Credentials, error) { + buildCount++ + return auth.NewTokenCredentials("counting", auth.TokenProviderFn( + func(context.Context) (*auth.Token, error) { + return &auth.Token{Value: "x"}, nil + }, + )), nil + }, + } + creds := newTestChain([]strategy{counting}, profiles.Profile{}) + if _, err := creds.AuthHeaders(context.Background()); err != nil { + t.Fatalf("AuthHeaders() error = %v", err) + } + if _, err := creds.AuthHeaders(context.Background()); err != nil { + t.Fatalf("AuthHeaders() error = %v", err) + } + if buildCount != 1 { + t.Errorf("configure called %d times, want 1", buildCount) + } +} + +func TestDefaultCredentials_InvokesLoaderExactlyOnce(t *testing.T) { + loaderCalls := 0 + loader := func() (profiles.Profile, error) { + loaderCalls++ + return profiles.Profile{Host: testHost, Token: "dapi-abc"}, nil + } + creds := &defaultCredentials{ + loadProfile: loader, + strategies: []strategy{{name: "pat", configure: configurePAT}}, + } + if _, err := creds.AuthHeaders(context.Background()); err != nil { + t.Fatalf("AuthHeaders() error = %v", err) + } + if _, err := creds.AuthHeaders(context.Background()); err != nil { + t.Fatalf("AuthHeaders() error = %v", err) + } + if loaderCalls != 1 { + t.Errorf("loader called %d times, want 1", loaderCalls) + } +} + +func TestDefaultCredentials_Errors(t *testing.T) { + testCases := []struct { + desc string + strategies []strategy + profile profiles.Profile + wantErr error + }{ + { + desc: "no strategy is configured", + strategies: []strategy{{name: "pat", configure: configurePAT}}, + profile: profiles.Profile{Host: testHost}, + wantErr: ErrNoAuthConfigured, + }, + { + desc: "no strategy matches auth_type", + strategies: []strategy{{name: "pat", configure: configurePAT}, configuredStrategy("oauth-m2m")}, + profile: profiles.Profile{Host: testHost, Token: "dapi-abc", AuthType: "made-up"}, + wantErr: ErrAuthTypeNotFound, + }, + { + desc: "the strategy named by auth_type is not configured", + strategies: []strategy{{name: "pat", configure: configurePAT}, configuredStrategy("oauth-m2m")}, + profile: profiles.Profile{Host: testHost, AuthType: "pat"}, + wantErr: ErrNoAuthConfigured, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + creds := newTestChain(tc.strategies, tc.profile) + _, err := creds.AuthHeaders(context.Background()) + if !errors.Is(err, tc.wantErr) { + t.Errorf("AuthHeaders() err = %v, want %v", err, tc.wantErr) + } + }) + } +} + +func TestDefaultCredentials_Name(t *testing.T) { + testCases := []struct { + desc string + strategies []strategy + profile profiles.Profile + wantName string + }{ + { + desc: "reports the first configured strategy when auth_type is not set", + strategies: []strategy{{name: "pat", configure: configurePAT}}, + profile: profiles.Profile{Host: testHost, Token: "dapi-abc"}, + wantName: "pat", + }, + { + desc: "reports the strategy selected by auth_type", + strategies: []strategy{{name: "pat", configure: configurePAT}, configuredStrategy("oauth-m2m")}, + profile: profiles.Profile{Host: testHost, Token: "dapi-abc", AuthType: "oauth-m2m"}, + wantName: "oauth-m2m", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + creds := newTestChain(tc.strategies, tc.profile) + if got := creds.Name(); got != "default" { + t.Errorf("Name() before resolution = %q, want %q", got, "default") + } + if _, err := creds.AuthHeaders(context.Background()); err != nil { + t.Fatalf("AuthHeaders() error = %v", err) + } + if got := creds.Name(); got != tc.wantName { + t.Errorf("Name() after resolution = %q, want %q", got, tc.wantName) + } + }) + } +} + +// TestDefaultCredentials_NameConcurrentWithAuthHeaders calls Name concurrently +// with AuthHeaders to guard against a data race on the resolved credentials. +// Meaningful under `go test -race`, which this repo's CI runs. +func TestDefaultCredentials_NameConcurrentWithAuthHeaders(t *testing.T) { + creds := newTestChain( + []strategy{{name: "pat", configure: configurePAT}}, + profiles.Profile{Host: testHost, Token: "dapi-abc"}, + ) + var wg sync.WaitGroup + for range 50 { + wg.Add(2) + go func() { defer wg.Done(); _, _ = creds.AuthHeaders(context.Background()) }() + go func() { defer wg.Done(); _ = creds.Name() }() + } + wg.Wait() +} + +// TestNewDefaultCredentials_PATFromProfile exercises the public constructor +// end-to-end with a real strategy (PAT needs no network) via an explicit +// profile, confirming the default chain wires up correctly. +func TestNewDefaultCredentials_PATFromProfile(t *testing.T) { + creds := NewDefaultCredentials(DefaultCredentialsOptions{ + Profile: &profiles.Profile{Host: testHost, Token: "dapi-xyz"}, + }) + headers, err := creds.AuthHeaders(context.Background()) + if err != nil { + t.Fatalf("AuthHeaders() error = %v", err) + } + want := []auth.Header{{Key: "Authorization", Value: "Bearer dapi-xyz"}} + if diff := cmp.Diff(want, headers); diff != "" { + t.Errorf("AuthHeaders() mismatch (-want +got):\n%s", diff) + } + if got := creds.Name(); got != "pat" { + t.Errorf("Name() = %q, want %q", got, "pat") + } +} diff --git a/auth/go.mod b/auth/go.mod index b6dd23d..f9620b3 100644 --- a/auth/go.mod +++ b/auth/go.mod @@ -6,7 +6,7 @@ replace github.com/databricks/sdk-go/core => ../core require ( github.com/databricks/databricks-sdk-go v0.92.0 - github.com/databricks/sdk-go/core v0.0.1-dev + github.com/databricks/sdk-go/core v0.0.1-dev.1 github.com/google/go-cmp v0.7.0 golang.org/x/oauth2 v0.33.0 ) @@ -19,4 +19,5 @@ require ( golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/auth/go.sum b/auth/go.sum index 405bb06..3f1d82f 100644 --- a/auth/go.sum +++ b/auth/go.sum @@ -27,5 +27,7 @@ golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/auth/internal/version.go b/auth/internal/version.go index 61a90fb..0d97015 100644 --- a/auth/internal/version.go +++ b/auth/internal/version.go @@ -2,4 +2,4 @@ package internal const ModuleName = "sdk-go-auth" -const Version = "0.0.0-dev" +const Version = "0.0.1-dev.1" diff --git a/auth/transport/transport.go b/auth/transport/transport.go deleted file mode 100644 index a278506..0000000 --- a/auth/transport/transport.go +++ /dev/null @@ -1,50 +0,0 @@ -// Package transport provides a HTTP transport that automatically adds authentication -// headers to outgoing requests. It is meant to provide a convenient way to make -// authenticated requests against Databricks APIs that are not part of the SDKs. -package transport - -import ( - "net/http" - - "github.com/databricks/sdk-go/auth" -) - -// NewAuthTransport returns a new HTTP transport that wraps the base transport -// to automatically add authentication headers to outgoing requests. -// -// The returned transport is safe for concurrent use by multiple goroutines. -// If base is nil, the default transport is used. The function assumes that -// the given credentials are non-nil. -func NewAuthTransport(base http.RoundTripper, creds auth.Credentials) http.RoundTripper { - if base == nil { - base = http.DefaultTransport - } - return &authTransport{base: base, creds: creds} -} - -// authTransport is the implementation of the HTTP transport that adds -// authentication headers to outgoing requests. -type authTransport struct { - base http.RoundTripper // base transport to wrap - creds auth.Credentials // credentials to use for authentication -} - -func (t *authTransport) RoundTrip(req *http.Request) (*http.Response, error) { - headers, err := t.creds.AuthHeaders(req.Context()) - if err != nil { - // RoundTripper must always close the request, including on errors. - if req.Body != nil { - // Swallow the cleanup error; the credentials error is the primary - // failure and the one that is the most actionable for callers. - _ = req.Body.Close() - } - return nil, err - } - // RoundTripper must not modify the request, except for consuming and - // closing the Request's Body. - clone := req.Clone(req.Context()) - for _, header := range headers { - clone.Header.Add(header.Key, header.Value) - } - return t.base.RoundTrip(clone) -} diff --git a/auth/transport/transport_test.go b/auth/transport/transport_test.go deleted file mode 100644 index 6741ae1..0000000 --- a/auth/transport/transport_test.go +++ /dev/null @@ -1,227 +0,0 @@ -package transport - -import ( - "context" - "errors" - "io" - "net/http" - "testing" - - "github.com/databricks/sdk-go/auth" -) - -// Sentinel test errors for use with errors.Is. -var ( - errCredentials = errors.New("credentials error") - errTransport = errors.New("transport error") - errClose = errors.New("close error") -) - -// mockCredentials implements auth.Credentials for testing. -type mockCredentials struct { - headers []auth.Header - err error - capturedCtx context.Context -} - -func (m *mockCredentials) Name() string { return "mock" } - -func (m *mockCredentials) AuthHeaders(ctx context.Context) ([]auth.Header, error) { - m.capturedCtx = ctx - return m.headers, m.err -} - -// mockTransport implements http.RoundTripper for testing. -type mockTransport struct { - response *http.Response - err error - - // capturedReq stores the request passed to RoundTrip for inspection. - capturedReq *http.Request -} - -func (m *mockTransport) RoundTrip(req *http.Request) (*http.Response, error) { - if req.Body != nil { - defer req.Body.Close() - } - m.capturedReq = req - return m.response, m.err -} - -// mockBody implements io.ReadCloser for testing body close behavior. -type mockBody struct { - closed bool - closeErr error -} - -func (m *mockBody) Read(p []byte) (n int, err error) { - return 0, io.EOF -} - -func (m *mockBody) Close() error { - m.closed = true - return m.closeErr -} - -func TestAuthTransport_RoundTrip(t *testing.T) { - testCases := []struct { - desc string - credHeaders []auth.Header // headers returned by the credentials - credErr error // error returned by the credentials - transportResp *http.Response // response returned by the base transport - transportErr error // error returned by the base transport - bodycloseErr error // error returned by the body close - wantErr error // error returned by the transport - }{ - { - desc: "adds single auth header", - credHeaders: []auth.Header{ - {Key: "Authorization", Value: "Bearer token123"}, - }, - transportResp: &http.Response{StatusCode: 200}, - }, - { - desc: "adds multiple auth headers", - credHeaders: []auth.Header{ - {Key: "Authorization", Value: "Bearer token123"}, - {Key: "X-Custom-Auth", Value: "custom-value"}, - }, - transportResp: &http.Response{StatusCode: 200}, - }, - { - desc: "propagates transport error", - credHeaders: []auth.Header{ - {Key: "Authorization", Value: "Bearer token123"}, - }, - transportErr: errTransport, - wantErr: errTransport, - }, - { - desc: "credentials error with no close error", - credErr: errCredentials, - wantErr: errCredentials, - }, - { - desc: "credentials error with close error", - bodycloseErr: errClose, - credErr: errCredentials, - wantErr: errCredentials, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - creds := &mockCredentials{ - headers: tc.credHeaders, - err: tc.credErr, - } - base := &mockTransport{ - response: tc.transportResp, - err: tc.transportErr, - } - transport := &authTransport{ - base: base, - creds: creds, - } - - body := &mockBody{closeErr: tc.bodycloseErr} - req, err := http.NewRequest("GET", "https://example.com/api", body) - if err != nil { - t.Fatalf("failed to create request: %v", err) - } - - gotResp, gotErr := transport.RoundTrip(req) - - // The body should always be closed by the transport, even in case - // of errors. - if !body.closed { - t.Error("request body was not closed") - } - if !errors.Is(gotErr, tc.wantErr) { - t.Fatalf("got error %v, want %v", gotErr, tc.wantErr) - } - if gotResp != tc.transportResp { - t.Errorf("response: got %v, want %v", gotResp, tc.transportResp) - } - // Check that the auth headers were added to the request sent to - // the base transport. - for _, h := range tc.credHeaders { - if got := base.capturedReq.Header.Get(h.Key); got != h.Value { - t.Errorf("%s header: got %q, want %q", h.Key, got, h.Value) - } - } - }) - } -} - -func TestAuthTransport_RoundTrip_DoesNotModifyOriginalRequest(t *testing.T) { - creds := &mockCredentials{ - headers: []auth.Header{{Key: "Authorization", Value: "Bearer token123"}}, - } - base := &mockTransport{ - response: &http.Response{StatusCode: 200}, - } - transport := &authTransport{ - base: base, - creds: creds, - } - - req, err := http.NewRequest("GET", "https://example.com/api", nil) - if err != nil { - t.Fatalf("failed to create request: %v", err) - } - - // Keep track of the original header state to verify that is was not - // modified by the transport. - originalAuthHeader := req.Header.Get("Authorization") - - _, err = transport.RoundTrip(req) - if err != nil { - t.Fatalf("got error %v, want nil", err) - } - - if req == base.capturedReq { - t.Error("base transport received original request instead of clone") - } - if got := req.Header.Get("Authorization"); got != originalAuthHeader { - t.Errorf("Authorization header from original request was modified: got %q, want %q", got, originalAuthHeader) - } - if got := base.capturedReq.Header.Get("Authorization"); got != "Bearer token123" { - t.Errorf("cloned request missing auth header: got %q", got) - } -} - -func TestAuthTransport_RoundTrip_PassesContextToCredentials(t *testing.T) { - type ctxKey string - key := ctxKey("test-key") - wantValue := "test-value" - - creds := &mockCredentials{ - headers: []auth.Header{{Key: "Auth", Value: "token"}}, - } - base := &mockTransport{ - response: &http.Response{StatusCode: 200}, - } - transport := &authTransport{ - base: base, - creds: creds, - } - - ctx := context.WithValue(context.Background(), key, wantValue) - req, err := http.NewRequestWithContext(ctx, "GET", "https://example.com/api", nil) - if err != nil { - t.Fatalf("failed to create request: %v", err) - } - - _, err = transport.RoundTrip(req) - if err != nil { - t.Fatalf("got error %v, want nil", err) - } - - if creds.capturedCtx == nil { - t.Fatal("context was not passed to credentials") - } - if got := creds.capturedCtx.Value(key); got != wantValue { - t.Errorf("context value = %v, want %v", got, wantValue) - } -} diff --git a/authentication/.package.json b/authentication/.package.json new file mode 100644 index 0000000..d1cc5d5 --- /dev/null +++ b/authentication/.package.json @@ -0,0 +1,3 @@ +{ + "package": "authentication" +} diff --git a/authentication/CHANGELOG.md b/authentication/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/authentication/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/authentication/README.md b/authentication/README.md new file mode 100644 index 0000000..6f544a1 --- /dev/null +++ b/authentication/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/authentication + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/authentication@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/authentication/v1" + +client, err := authentication.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/authentication/go.mod b/authentication/go.mod new file mode 100644 index 0000000..2b58a4a --- /dev/null +++ b/authentication/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/authentication + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/authentication/internal/version.go b/authentication/internal/version.go new file mode 100644 index 0000000..2134368 --- /dev/null +++ b/authentication/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-authentication" + +const Version = "0.0.1-dev.1" diff --git a/authentication/v1/client.go b/authentication/v1/client.go new file mode 100755 index 0000000..385c621 --- /dev/null +++ b/authentication/v1/client.go @@ -0,0 +1,1390 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package authentication + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/authentication/internal" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create account federation policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateAccountFederationPolicy(ctx context.Context, req *CreateAccountFederationPolicyRequest, opts ...call.Option) (*FederationPolicy, error) { + wireReq, err := createAccountFederationPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Policy) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/federationPolicies") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "service_principal_id", wireReq.ServicePrincipalId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "policy_id", wireReq.PolicyId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FederationPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp federationPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = federationPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create account federation policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateServicePrincipalFederationPolicy(ctx context.Context, req *CreateServicePrincipalFederationPolicyRequest, opts ...call.Option) (*FederationPolicy, error) { + wireReq, err := createServicePrincipalFederationPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Policy) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipalId) + pb.literal("/federationPolicies") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "policy_id", wireReq.PolicyId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FederationPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp federationPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = federationPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete account federation policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteAccountFederationPolicy(ctx context.Context, req *DeleteAccountFederationPolicyRequest, opts ...call.Option) error { + wireReq, err := deleteAccountFederationPolicyRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/federationPolicies/") + pb.singleSegment(*req.PolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "service_principal_id", wireReq.ServicePrincipalId); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete account federation policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteServicePrincipalFederationPolicy(ctx context.Context, req *DeleteServicePrincipalFederationPolicyRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipalId) + pb.literal("/federationPolicies/") + pb.singleSegment(*req.PolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Get account federation policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetAccountFederationPolicy(ctx context.Context, req *GetAccountFederationPolicyRequest, opts ...call.Option) (*FederationPolicy, error) { + wireReq, err := getAccountFederationPolicyRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/federationPolicies/") + pb.singleSegment(*req.PolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "service_principal_id", wireReq.ServicePrincipalId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FederationPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp federationPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = federationPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get account federation policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetServicePrincipalFederationPolicy(ctx context.Context, req *GetServicePrincipalFederationPolicyRequest, opts ...call.Option) (*FederationPolicy, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipalId) + pb.literal("/federationPolicies/") + pb.singleSegment(*req.PolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FederationPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp federationPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = federationPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List account federation policies. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListAccountFederationPolicies(ctx context.Context, req *ListAccountFederationPoliciesRequest, opts ...call.Option) (*ListFederationPoliciesResponse, error) { + wireReq, err := listAccountFederationPoliciesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/federationPolicies") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "service_principal_id", wireReq.ServicePrincipalId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListFederationPoliciesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listFederationPoliciesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listFederationPoliciesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListAccountFederationPoliciesIter returns an iterator that iterates +// over the results of ListAccountFederationPolicies. +// +// For example: +// +// for item, err := range c.ListAccountFederationPoliciesIter(ctx, &ListAccountFederationPoliciesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListAccountFederationPolicies call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListAccountFederationPolicies directly. +func (c *internalClient) ListAccountFederationPoliciesIter(ctx context.Context, req *ListAccountFederationPoliciesRequest, opts ...call.Option) iter.Seq2[*FederationPolicy, error] { + return func(yield func(*FederationPolicy, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListAccountFederationPoliciesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListAccountFederationPolicies(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Policies { + if !yield(&resp.Policies[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List account federation policies. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListServicePrincipalFederationPolicies(ctx context.Context, req *ListServicePrincipalFederationPoliciesRequest, opts ...call.Option) (*ListFederationPoliciesResponse, error) { + wireReq, err := listServicePrincipalFederationPoliciesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipalId) + pb.literal("/federationPolicies") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListFederationPoliciesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listFederationPoliciesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listFederationPoliciesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListServicePrincipalFederationPoliciesIter returns an iterator that iterates +// over the results of ListServicePrincipalFederationPolicies. +// +// For example: +// +// for item, err := range c.ListServicePrincipalFederationPoliciesIter(ctx, &ListServicePrincipalFederationPoliciesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListServicePrincipalFederationPolicies call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListServicePrincipalFederationPolicies directly. +func (c *internalClient) ListServicePrincipalFederationPoliciesIter(ctx context.Context, req *ListServicePrincipalFederationPoliciesRequest, opts ...call.Option) iter.Seq2[*FederationPolicy, error] { + return func(yield func(*FederationPolicy, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListServicePrincipalFederationPoliciesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListServicePrincipalFederationPolicies(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Policies { + if !yield(&resp.Policies[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Update account federation policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateAccountFederationPolicy(ctx context.Context, req *UpdateAccountFederationPolicyRequest, opts ...call.Option) (*FederationPolicy, error) { + wireReq, err := updateAccountFederationPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Policy) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/federationPolicies/") + pb.singleSegment(*req.PolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "service_principal_id", wireReq.ServicePrincipalId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FederationPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp federationPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = federationPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update account federation policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateServicePrincipalFederationPolicy(ctx context.Context, req *UpdateServicePrincipalFederationPolicyRequest, opts ...call.Option) (*FederationPolicy, error) { + wireReq, err := updateServicePrincipalFederationPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Policy) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipalId) + pb.literal("/federationPolicies/") + pb.singleSegment(*req.PolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FederationPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp federationPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = federationPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a secret for the given service principal. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateServicePrincipalSecret(ctx context.Context, req *CreateServicePrincipalSecretRequest, opts ...call.Option) (*CreateServicePrincipalSecretResponse, error) { + wireReq, err := createServicePrincipalSecretRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipal) + pb.literal("/credentials/secrets") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateServicePrincipalSecretResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createServicePrincipalSecretResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createServicePrincipalSecretResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a secret for the given service principal. +func (c *internalClient) CreateServicePrincipalSecretProxy(ctx context.Context, req *CreateServicePrincipalSecretRequest, opts ...call.Option) (*CreateServicePrincipalSecretResponse, error) { + wireReq, err := createServicePrincipalSecretRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipal) + pb.literal("/credentials/secrets") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateServicePrincipalSecretResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createServicePrincipalSecretResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createServicePrincipalSecretResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a secret from the given service principal. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteServicePrincipalSecret(ctx context.Context, req *DeleteServicePrincipalSecretRequest, opts ...call.Option) (*DeleteServicePrincipalSecretResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipal) + pb.literal("/credentials/secrets/") + pb.singleSegment(*req.SecretId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteServicePrincipalSecretResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteServicePrincipalSecretResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a secret from the given service principal. +func (c *internalClient) DeleteServicePrincipalSecretProxy(ctx context.Context, req *DeleteServicePrincipalSecretRequest, opts ...call.Option) (*DeleteServicePrincipalSecretResponse, error) { + wireReq, err := deleteServicePrincipalSecretRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipal) + pb.literal("/credentials/secrets/") + pb.singleSegment(*req.SecretId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "account_id", wireReq.AccountId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteServicePrincipalSecretResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteServicePrincipalSecretResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List all secrets associated with the given service principal. This operation +// only returns information about the secrets themselves and does not include +// the secret values. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListServicePrincipalSecrets(ctx context.Context, req *ListServicePrincipalSecretsRequest, opts ...call.Option) (*ListServicePrincipalSecretsResponse, error) { + wireReq, err := listServicePrincipalSecretsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipal) + pb.literal("/credentials/secrets") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListServicePrincipalSecretsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listServicePrincipalSecretsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listServicePrincipalSecretsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListServicePrincipalSecretsIter returns an iterator that iterates +// over the results of ListServicePrincipalSecrets. +// +// For example: +// +// for item, err := range c.ListServicePrincipalSecretsIter(ctx, &ListServicePrincipalSecretsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListServicePrincipalSecrets call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListServicePrincipalSecrets directly. +func (c *internalClient) ListServicePrincipalSecretsIter(ctx context.Context, req *ListServicePrincipalSecretsRequest, opts ...call.Option) iter.Seq2[*ServicePrincipalSecret, error] { + return func(yield func(*ServicePrincipalSecret, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListServicePrincipalSecretsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListServicePrincipalSecrets(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Secrets { + if !yield(&resp.Secrets[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List all secrets associated with the given service principal. This operation +// only returns information about the secrets themselves and does not include +// the secret values. +func (c *internalClient) ListServicePrincipalSecretsProxy(ctx context.Context, req *ListServicePrincipalSecretsRequest, opts ...call.Option) (*ListServicePrincipalSecretsResponse, error) { + wireReq, err := listServicePrincipalSecretsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/servicePrincipals/") + pb.singleSegment(*req.ServicePrincipal) + pb.literal("/credentials/secrets") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "account_id", wireReq.AccountId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListServicePrincipalSecretsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listServicePrincipalSecretsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listServicePrincipalSecretsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListServicePrincipalSecretsProxyIter returns an iterator that iterates +// over the results of ListServicePrincipalSecretsProxy. +// +// For example: +// +// for item, err := range c.ListServicePrincipalSecretsProxyIter(ctx, &ListServicePrincipalSecretsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListServicePrincipalSecretsProxy call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListServicePrincipalSecretsProxy directly. +func (c *internalClient) ListServicePrincipalSecretsProxyIter(ctx context.Context, req *ListServicePrincipalSecretsRequest, opts ...call.Option) iter.Seq2[*ServicePrincipalSecret, error] { + return func(yield func(*ServicePrincipalSecret, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListServicePrincipalSecretsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListServicePrincipalSecretsProxy(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Secrets { + if !yield(&resp.Secrets[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} diff --git a/authentication/v1/genhelper.go b/authentication/v1/genhelper.go new file mode 100755 index 0000000..30422df --- /dev/null +++ b/authentication/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package authentication + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/authentication/v1/model.go b/authentication/v1/model.go new file mode 100755 index 0000000..c3167c9 --- /dev/null +++ b/authentication/v1/model.go @@ -0,0 +1,282 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package authentication + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type CreateAccountFederationPolicyRequest struct { + // The account id for the federation policy. + AccountId *string + // The service principal id for the federation policy. + ServicePrincipalId *int64 + // The identifier for the federation policy. The identifier must contain only + // lowercase alphanumeric characters, numbers, hyphens, and slashes. If + // unspecified, the id will be assigned by . + PolicyId *string + Policy *FederationPolicy +} + +type CreateServicePrincipalFederationPolicyRequest struct { + // The account id for the federation policy. + AccountId *string + // The service principal id for the federation policy. + ServicePrincipalId *int64 + // The identifier for the federation policy. The identifier must contain only + // lowercase alphanumeric characters, numbers, hyphens, and slashes. If + // unspecified, the id will be assigned by . + PolicyId *string + Policy *FederationPolicy +} + +type CreateServicePrincipalSecretRequest struct { + // The account ID. + AccountId *string + // The service principal ID. + ServicePrincipal *string + // The lifetime of the secret in seconds. If this parameter is not provided, the + // secret will have a default lifetime of 730 days (63072000s). + Lifetime *types.Duration +} + +type CreateServicePrincipalSecretResponse struct { + // ID of the secret + Id *string + // Secret Value + Secret *string + // Secret Hash + SecretHash *string + // UTC time when the secret was created + CreateTime *string + // UTC time when the secret was updated + UpdateTime *string + // Status of the secret + Status *string + // UTC time when the secret will expire. If the field is not present, the secret + // does not expire. + ExpireTime *types.Time +} + +type DeleteAccountFederationPolicyRequest struct { + // The account id for the federation policy. + AccountId *string + // The service principal id for the federation policy. + ServicePrincipalId *int64 + // The identifier for the federation policy. + PolicyId *string +} + +type DeleteServicePrincipalFederationPolicyRequest struct { + // The account id for the federation policy. + AccountId *string + // The service principal id for the federation policy. + ServicePrincipalId *int64 + // The identifier for the federation policy. + PolicyId *string +} + +type DeleteServicePrincipalSecretRequest struct { + // The account ID. + AccountId *string + // The service principal ID. + ServicePrincipal *string + // The secret ID. + SecretId *string +} + +type DeleteServicePrincipalSecretResponse struct { +} + +type FederationPolicy struct { + // Resource name for the federation policy. Example values include + // `accounts//federationPolicies/my-federation-policy` for Account + // Federation Policies, and + // `accounts//servicePrincipals//federationPolicies/my-federation-policy` + // for Service Principal Federation Policies. Typically an output parameter, + // which does not need to be specified in create or update requests. If + // specified in a request, must match the value in the request URL. + Name *string `fieldmask:"name"` + // Description of the federation policy. + Description *string `fieldmask:"description"` + Policy isFederationPolicy_Policy + // Creation time of the federation policy. + CreateTime *types.Time `fieldmask:"create_time"` + // Last update time of the federation policy. + UpdateTime *types.Time `fieldmask:"update_time"` + // Unique, immutable id of the federation policy. + Uid *string `fieldmask:"uid"` + // The service principal ID that this federation policy applies to. Output only. + // Only set for service principal federation policies. + ServicePrincipalId *int64 `fieldmask:"service_principal_id"` + // The ID of the federation policy. Output only. + PolicyId *string `fieldmask:"policy_id"` + _ [0]federationPolicyPolicyFieldMaskMetadata `fieldmask_oneof:"Policy"` +} + +type isFederationPolicy_Policy interface { + isFederationPolicy_Policy() +} + +// FederationPolicy_Policy_OidcPolicy selects OidcPolicy for FederationPolicy.Policy. +type FederationPolicy_Policy_OidcPolicy struct { + OidcPolicy OidcFederationPolicy `fieldmask:"oidc_policy"` +} + +func (*FederationPolicy_Policy_OidcPolicy) isFederationPolicy_Policy() {} + +type federationPolicyPolicyFieldMaskMetadata struct { + *FederationPolicy_Policy_OidcPolicy +} + +type GetAccountFederationPolicyRequest struct { + // The account id for the federation policy. + AccountId *string + // The service principal id for the federation policy. + ServicePrincipalId *int64 + // The identifier for the federation policy. + PolicyId *string +} + +type GetServicePrincipalFederationPolicyRequest struct { + // The account id for the federation policy. + AccountId *string + // The service principal id for the federation policy. + ServicePrincipalId *int64 + // The identifier for the federation policy. + PolicyId *string +} + +type ListAccountFederationPoliciesRequest struct { + // The account id for the federation policy. + AccountId *string + // The service principal id for the federation policy. + ServicePrincipalId *int64 + PageSize *int + PageToken *string +} + +type ListFederationPoliciesResponse struct { + Policies []FederationPolicy + NextPageToken *string +} + +type ListServicePrincipalFederationPoliciesRequest struct { + // The account id for the federation policy. + AccountId *string + // The service principal id for the federation policy. + ServicePrincipalId *int64 + PageSize *int + PageToken *string +} + +type ListServicePrincipalSecretsRequest struct { + // The account ID. + AccountId *string + // The service principal ID. + ServicePrincipal *string + // An opaque page token which was the `next_page_token` in the response of the + // previous request to list the secrets for this service principal. Provide this + // token to retrieve the next page of secret entries. When providing a + // `page_token`, all other parameters provided to the request must match the + // previous request. To list all of the secrets for a service principal, it is + // necessary to continue requesting pages of entries until the response contains + // no `next_page_token`. Note that the number of entries returned must not be + // used to determine when the listing is complete. + PageToken *string + PageSize *int +} + +type ListServicePrincipalSecretsResponse struct { + // List of the secrets + Secrets []ServicePrincipalSecret + // A token, which can be sent as `page_token` to retrieve the next page. + NextPageToken *string +} + +// Specifies the policy to use for validating OIDC claims in your federated +// tokens.. +type OidcFederationPolicy struct { + // The required token issuer, as specified in the 'iss' claim of federated + // tokens. + Issuer *string `fieldmask:"issuer"` + // The required token subject, as specified in the subject claim of federated + // tokens. Must be specified for service principal federation policies. Must not + // be specified for account federation policies. + Subject *string `fieldmask:"subject"` + // The allowed token audiences, as specified in the 'aud' claim of federated + // tokens. The audience identifier is intended to represent the recipient of the + // token. Can be any non-empty string value. As long as the audience in the + // token matches at least one audience in the policy, the token is considered a + // match. If audiences is unspecified, defaults to your account id. + Audiences []string `fieldmask:"audiences"` + // The claim that contains the subject of the token. If unspecified, the default + // value is 'sub'. + SubjectClaim *string `fieldmask:"subject_claim"` + // URL of the public keys used to validate the signature of federated tokens, in + // JWKS format. Most use cases should not need to specify this field. If + // jwks_uri and jwks_json are both unspecified (recommended), + // automatically fetches the public keys from your issuer’s well known + // endpoint. Databricks strongly recommends relying on your issuer’s well + // known endpoint for discovering public keys. + JwksUri *string `fieldmask:"jwks_uri"` + // The public keys used to validate the signature of federated tokens, in JWKS + // format. Most use cases should not need to specify this field. If jwks_uri and + // jwks_json are both unspecified (recommended), automatically + // fetches the public keys from your issuer’s well known endpoint. Databricks + // strongly recommends relying on your issuer’s well known endpoint for + // discovering public keys. + JwksJson *string `fieldmask:"jwks_json"` +} + +type ServicePrincipalSecret struct { + // ID of the secret + Id *string + // Secret Value + Secret *string + // Secret Hash + SecretHash *string + // UTC time when the secret was created + CreateTime *string + // UTC time when the secret was updated + UpdateTime *string + // Status of the secret + Status *string + // UTC time when the secret will expire. If the field is not present, the secret + // does not expire. + ExpireTime *types.Time +} + +type UpdateAccountFederationPolicyRequest struct { + // The account id for the federation policy. + AccountId *string + // The service principal id for the federation policy. + ServicePrincipalId *int64 + // The identifier for the federation policy. + PolicyId *string + Policy *FederationPolicy + // The field mask specifies which fields of the policy to update. To specify + // multiple fields in the field mask, use comma as the separator (no space). The + // special value '*' indicates that all fields should be updated (full + // replacement). If unspecified, all fields that are set in the policy provided + // in the update request will overwrite the corresponding fields in the existing + // policy. Example value: 'description,oidc_policy.audiences'. + UpdateMask *types.FieldMask[FederationPolicy] +} + +type UpdateServicePrincipalFederationPolicyRequest struct { + // The account id for the federation policy. + AccountId *string + // The service principal id for the federation policy. + ServicePrincipalId *int64 + // The identifier for the federation policy. + PolicyId *string + Policy *FederationPolicy + // The field mask specifies which fields of the policy to update. To specify + // multiple fields in the field mask, use comma as the separator (no space). The + // special value '*' indicates that all fields should be updated (full + // replacement). If unspecified, all fields that are set in the policy provided + // in the update request will overwrite the corresponding fields in the existing + // policy. Example value: 'description,oidc_policy.audiences'. + UpdateMask *types.FieldMask[FederationPolicy] +} diff --git a/authentication/v1/wire.go b/authentication/v1/wire.go new file mode 100755 index 0000000..9ed6a8f --- /dev/null +++ b/authentication/v1/wire.go @@ -0,0 +1,451 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package authentication + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createAccountFederationPolicyRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + Policy *federationPolicyWire `json:"policy,omitempty"` +} + +func createAccountFederationPolicyRequestToWire(v *CreateAccountFederationPolicyRequest) (*createAccountFederationPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + policyWireValue, err := federationPolicyToWire(v.Policy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountFederationPolicyRequest.Policy", err) + } + return &createAccountFederationPolicyRequestWire{ + AccountId: v.AccountId, + ServicePrincipalId: v.ServicePrincipalId, + PolicyId: v.PolicyId, + Policy: policyWireValue, + }, nil +} + +type createServicePrincipalFederationPolicyRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + Policy *federationPolicyWire `json:"policy,omitempty"` +} + +func createServicePrincipalFederationPolicyRequestToWire(v *CreateServicePrincipalFederationPolicyRequest) (*createServicePrincipalFederationPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + policyWireValue, err := federationPolicyToWire(v.Policy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateServicePrincipalFederationPolicyRequest.Policy", err) + } + return &createServicePrincipalFederationPolicyRequestWire{ + AccountId: v.AccountId, + ServicePrincipalId: v.ServicePrincipalId, + PolicyId: v.PolicyId, + Policy: policyWireValue, + }, nil +} + +type createServicePrincipalSecretRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipal *string `json:"service_principal,omitempty"` + Lifetime *types.Duration `json:"lifetime,omitempty"` +} + +func createServicePrincipalSecretRequestToWire(v *CreateServicePrincipalSecretRequest) (*createServicePrincipalSecretRequestWire, error) { + if v == nil { + return nil, nil + } + return &createServicePrincipalSecretRequestWire{ + AccountId: v.AccountId, + ServicePrincipal: v.ServicePrincipal, + Lifetime: v.Lifetime, + }, nil +} + +type createServicePrincipalSecretResponseWire struct { + Id *string `json:"id,omitempty"` + Secret *string `json:"secret,omitempty"` + SecretHash *string `json:"secret_hash,omitempty"` + CreateTime *string `json:"create_time,omitempty"` + UpdateTime *string `json:"update_time,omitempty"` + Status *string `json:"status,omitempty"` + ExpireTime *types.Time `json:"expire_time,omitempty"` +} + +func createServicePrincipalSecretResponseFromWire(w *createServicePrincipalSecretResponseWire) (*CreateServicePrincipalSecretResponse, error) { + if w == nil { + return nil, nil + } + return &CreateServicePrincipalSecretResponse{ + Id: w.Id, + Secret: w.Secret, + SecretHash: w.SecretHash, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Status: w.Status, + ExpireTime: w.ExpireTime, + }, nil +} + +type deleteAccountFederationPolicyRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` +} + +func deleteAccountFederationPolicyRequestToWire(v *DeleteAccountFederationPolicyRequest) (*deleteAccountFederationPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteAccountFederationPolicyRequestWire{ + AccountId: v.AccountId, + ServicePrincipalId: v.ServicePrincipalId, + PolicyId: v.PolicyId, + }, nil +} + +type deleteServicePrincipalSecretRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipal *string `json:"service_principal,omitempty"` + SecretId *string `json:"secret_id,omitempty"` +} + +func deleteServicePrincipalSecretRequestToWire(v *DeleteServicePrincipalSecretRequest) (*deleteServicePrincipalSecretRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteServicePrincipalSecretRequestWire{ + AccountId: v.AccountId, + ServicePrincipal: v.ServicePrincipal, + SecretId: v.SecretId, + }, nil +} + +type federationPolicyWire struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + OidcPolicy *oidcFederationPolicyWire `json:"oidc_policy,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Uid *string `json:"uid,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` +} + +func federationPolicyToWire(v *FederationPolicy) (*federationPolicyWire, error) { + if v == nil { + return nil, nil + } + var policyOidcPolicyWire *oidcFederationPolicyWire + switch value := v.Policy.(type) { + case nil: + case *FederationPolicy_Policy_OidcPolicy: + if value != nil { + policyOidcPolicyConverted, err := oidcFederationPolicyToWire(&value.OidcPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FederationPolicy.Policy.OidcPolicy", err) + } + policyOidcPolicyWire = policyOidcPolicyConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "FederationPolicy.Policy", value) + } + return &federationPolicyWire{ + Name: v.Name, + Description: v.Description, + OidcPolicy: policyOidcPolicyWire, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + Uid: v.Uid, + ServicePrincipalId: v.ServicePrincipalId, + PolicyId: v.PolicyId, + }, nil +} + +func federationPolicyFromWire(w *federationPolicyWire) (*FederationPolicy, error) { + if w == nil { + return nil, nil + } + policyMembers := 0 + if w.OidcPolicy != nil { + policyMembers++ + } + if policyMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "FederationPolicy.Policy") + } + var policySelection isFederationPolicy_Policy + switch { + case w.OidcPolicy != nil: + policyOidcPolicyConverted, err := oidcFederationPolicyFromWire(w.OidcPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FederationPolicy.Policy.OidcPolicy", err) + } + policySelection = &FederationPolicy_Policy_OidcPolicy{OidcPolicy: *policyOidcPolicyConverted} + } + return &FederationPolicy{ + Name: w.Name, + Description: w.Description, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Uid: w.Uid, + ServicePrincipalId: w.ServicePrincipalId, + PolicyId: w.PolicyId, + Policy: policySelection, + }, nil +} + +type getAccountFederationPolicyRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` +} + +func getAccountFederationPolicyRequestToWire(v *GetAccountFederationPolicyRequest) (*getAccountFederationPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + return &getAccountFederationPolicyRequestWire{ + AccountId: v.AccountId, + ServicePrincipalId: v.ServicePrincipalId, + PolicyId: v.PolicyId, + }, nil +} + +type listAccountFederationPoliciesRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listAccountFederationPoliciesRequestToWire(v *ListAccountFederationPoliciesRequest) (*listAccountFederationPoliciesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAccountFederationPoliciesRequestWire{ + AccountId: v.AccountId, + ServicePrincipalId: v.ServicePrincipalId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listFederationPoliciesResponseWire struct { + Policies []federationPolicyWire `json:"policies,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listFederationPoliciesResponseFromWire(w *listFederationPoliciesResponseWire) (*ListFederationPoliciesResponse, error) { + if w == nil { + return nil, nil + } + policiesPublicValue, err := convertSlice(w.Policies, federationPolicyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListFederationPoliciesResponse.Policies", err) + } + return &ListFederationPoliciesResponse{ + Policies: policiesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listServicePrincipalFederationPoliciesRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listServicePrincipalFederationPoliciesRequestToWire(v *ListServicePrincipalFederationPoliciesRequest) (*listServicePrincipalFederationPoliciesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listServicePrincipalFederationPoliciesRequestWire{ + AccountId: v.AccountId, + ServicePrincipalId: v.ServicePrincipalId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listServicePrincipalSecretsRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipal *string `json:"service_principal,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listServicePrincipalSecretsRequestToWire(v *ListServicePrincipalSecretsRequest) (*listServicePrincipalSecretsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listServicePrincipalSecretsRequestWire{ + AccountId: v.AccountId, + ServicePrincipal: v.ServicePrincipal, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listServicePrincipalSecretsResponseWire struct { + Secrets []servicePrincipalSecretWire `json:"secrets,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listServicePrincipalSecretsResponseFromWire(w *listServicePrincipalSecretsResponseWire) (*ListServicePrincipalSecretsResponse, error) { + if w == nil { + return nil, nil + } + secretsPublicValue, err := convertSlice(w.Secrets, servicePrincipalSecretFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListServicePrincipalSecretsResponse.Secrets", err) + } + return &ListServicePrincipalSecretsResponse{ + Secrets: secretsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type oidcFederationPolicyWire struct { + Issuer *string `json:"issuer,omitempty"` + Subject *string `json:"subject,omitempty"` + Audiences []string `json:"audiences,omitempty"` + SubjectClaim *string `json:"subject_claim,omitempty"` + JwksUri *string `json:"jwks_uri,omitempty"` + JwksJson *string `json:"jwks_json,omitempty"` +} + +func oidcFederationPolicyToWire(v *OidcFederationPolicy) (*oidcFederationPolicyWire, error) { + if v == nil { + return nil, nil + } + return &oidcFederationPolicyWire{ + Issuer: v.Issuer, + Subject: v.Subject, + Audiences: v.Audiences, + SubjectClaim: v.SubjectClaim, + JwksUri: v.JwksUri, + JwksJson: v.JwksJson, + }, nil +} + +func oidcFederationPolicyFromWire(w *oidcFederationPolicyWire) (*OidcFederationPolicy, error) { + if w == nil { + return nil, nil + } + return &OidcFederationPolicy{ + Issuer: w.Issuer, + Subject: w.Subject, + Audiences: w.Audiences, + SubjectClaim: w.SubjectClaim, + JwksUri: w.JwksUri, + JwksJson: w.JwksJson, + }, nil +} + +type servicePrincipalSecretWire struct { + Id *string `json:"id,omitempty"` + Secret *string `json:"secret,omitempty"` + SecretHash *string `json:"secret_hash,omitempty"` + CreateTime *string `json:"create_time,omitempty"` + UpdateTime *string `json:"update_time,omitempty"` + Status *string `json:"status,omitempty"` + ExpireTime *types.Time `json:"expire_time,omitempty"` +} + +func servicePrincipalSecretFromWire(w *servicePrincipalSecretWire) (*ServicePrincipalSecret, error) { + if w == nil { + return nil, nil + } + return &ServicePrincipalSecret{ + Id: w.Id, + Secret: w.Secret, + SecretHash: w.SecretHash, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Status: w.Status, + ExpireTime: w.ExpireTime, + }, nil +} + +type updateAccountFederationPolicyRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + Policy *federationPolicyWire `json:"policy,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateAccountFederationPolicyRequestToWire(v *UpdateAccountFederationPolicyRequest) (*updateAccountFederationPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + policyWireValue, err := federationPolicyToWire(v.Policy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountFederationPolicyRequest.Policy", err) + } + return &updateAccountFederationPolicyRequestWire{ + AccountId: v.AccountId, + ServicePrincipalId: v.ServicePrincipalId, + PolicyId: v.PolicyId, + Policy: policyWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateServicePrincipalFederationPolicyRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ServicePrincipalId *int64 `json:"service_principal_id,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + Policy *federationPolicyWire `json:"policy,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateServicePrincipalFederationPolicyRequestToWire(v *UpdateServicePrincipalFederationPolicyRequest) (*updateServicePrincipalFederationPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + policyWireValue, err := federationPolicyToWire(v.Policy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateServicePrincipalFederationPolicyRequest.Policy", err) + } + return &updateServicePrincipalFederationPolicyRequestWire{ + AccountId: v.AccountId, + ServicePrincipalId: v.ServicePrincipalId, + PolicyId: v.PolicyId, + Policy: policyWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/budgetpolicy/.package.json b/budgetpolicy/.package.json new file mode 100644 index 0000000..62570e7 --- /dev/null +++ b/budgetpolicy/.package.json @@ -0,0 +1,3 @@ +{ + "package": "budgetpolicy" +} diff --git a/budgetpolicy/CHANGELOG.md b/budgetpolicy/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/budgetpolicy/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/budgetpolicy/README.md b/budgetpolicy/README.md new file mode 100644 index 0000000..a0919ef --- /dev/null +++ b/budgetpolicy/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/budgetpolicy + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/budgetpolicy@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/budgetpolicy/v1" + +client, err := budgetpolicy.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/budgetpolicy/go.mod b/budgetpolicy/go.mod new file mode 100644 index 0000000..04440e2 --- /dev/null +++ b/budgetpolicy/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/budgetpolicy + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/budgetpolicy/internal/version.go b/budgetpolicy/internal/version.go new file mode 100644 index 0000000..a151038 --- /dev/null +++ b/budgetpolicy/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-budgetpolicy" + +const Version = "0.0.1-dev.1" diff --git a/budgetpolicy/v1/client.go b/budgetpolicy/v1/client.go new file mode 100755 index 0000000..e5acf7c --- /dev/null +++ b/budgetpolicy/v1/client.go @@ -0,0 +1,469 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package budgetpolicy + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/budgetpolicy/internal" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateBudgetPolicy(ctx context.Context, req *CreateBudgetPolicyRequest, opts ...call.Option) (*BudgetPolicy, error) { + wireReq, err := createBudgetPolicyRequestToWire(req) + if err != nil { + return nil, err + } + if wireReq.RequestId == nil || *wireReq.RequestId == "" { + wireReq.RequestId = new(generateRequestID()) + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/budget-policies") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *BudgetPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp budgetPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = budgetPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a policy +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteBudgetPolicy(ctx context.Context, req *DeleteBudgetPolicyRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/budget-policies/") + pb.singleSegment(*req.PolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Retrieves a policy by it's ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetBudgetPolicy(ctx context.Context, req *GetBudgetPolicyRequest, opts ...call.Option) (*BudgetPolicy, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/budget-policies/") + pb.singleSegment(*req.PolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *BudgetPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp budgetPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = budgetPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists all policies. Policies are returned in the alphabetically ascending +// order of their names. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListBudgetPolicies(ctx context.Context, req *ListBudgetPoliciesRequest, opts ...call.Option) (*ListBudgetPoliciesResponse, error) { + wireReq, err := listBudgetPoliciesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/budget-policies") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "filter_by", wireReq.FilterBy); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "sort_spec", wireReq.SortSpec); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListBudgetPoliciesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listBudgetPoliciesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listBudgetPoliciesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListBudgetPoliciesIter returns an iterator that iterates +// over the results of ListBudgetPolicies. +// +// For example: +// +// for item, err := range c.ListBudgetPoliciesIter(ctx, &ListBudgetPoliciesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListBudgetPolicies call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListBudgetPolicies directly. +func (c *internalClient) ListBudgetPoliciesIter(ctx context.Context, req *ListBudgetPoliciesRequest, opts ...call.Option) iter.Seq2[*BudgetPolicy, error] { + return func(yield func(*BudgetPolicy, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListBudgetPoliciesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListBudgetPolicies(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Policies { + if !yield(&resp.Policies[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates a policy +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateBudgetPolicy(ctx context.Context, req *UpdateBudgetPolicyRequest, opts ...call.Option) (*BudgetPolicy, error) { + wireReq, err := updateBudgetPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Policy) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/budget-policies/") + pb.singleSegment(*req.Policy.PolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "limit_config", wireReq.LimitConfig); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *BudgetPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp budgetPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = budgetPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/budgetpolicy/v1/genhelper.go b/budgetpolicy/v1/genhelper.go new file mode 100755 index 0000000..c1bfc83 --- /dev/null +++ b/budgetpolicy/v1/genhelper.go @@ -0,0 +1,236 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package budgetpolicy + +import ( + "bytes" + "context" + "crypto/rand" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// generateRequestID returns a random RFC 4122 version 4 UUID string, used as an +// idempotency token when the caller does not supply one. It uses crypto/rand to +// avoid a UUID dependency; a read failure is treated as unrecoverable. +func generateRequestID() string { + var b [16]byte + if _, err := rand.Read(b[:]); err != nil { + panic(fmt.Sprintf("generate request id: %v", err)) + } + b[6] = (b[6] & 0x0f) | 0x40 // version 4 + b[8] = (b[8] & 0x3f) | 0x80 // variant 10 + return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16]) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/budgetpolicy/v1/model.go b/budgetpolicy/v1/model.go new file mode 100755 index 0000000..91fa701 --- /dev/null +++ b/budgetpolicy/v1/model.go @@ -0,0 +1,140 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package budgetpolicy + +type SortSpec_Field string + +const ( + SortSpec_Field_Unspecified SortSpec_Field = "" + // Sort by policy name. + SortSpec_Field_PolicyName SortSpec_Field = "POLICY_NAME" +) + +// Contains the BudgetPolicy details.. +type BudgetPolicy struct { + // The Id of the policy. This field is generated by and globally + // unique. + PolicyId *string + // The name of the policy. - Must be unique among active policies. - Can contain + // only characters from the ISO 8859-1 (latin1) set. - Can't start with reserved + // keywords such as `databricks:default-policy`. + PolicyName *string + // A list of tags defined by the customer. At most 20 entries are allowed per + // policy. + CustomTags []CustomPolicyTag + // List of workspaces that this budget policy will be exclusively bound to. An + // empty binding implies that this budget policy is open to any workspace in the + // account. + BindingWorkspaceIds []int64 +} + +// A request to create a BudgetPolicy.. +type CreateBudgetPolicyRequest struct { + // A unique identifier for this request. Restricted to 36 ASCII characters. A + // random UUID is recommended. This request is only idempotent if a `request_id` + // is provided. + RequestId *string + // The account Id of the customer + AccountId *string + // The policy to create. `policy_id` needs to be empty as it will be generated + // `policy_name` must be provided, custom_tags may need to be provided depending + // on the cloud provider. All other fields are optional. + Policy *BudgetPolicy +} + +type CustomPolicyTag struct { + // The key of the tag. - Must be unique among all custom tags of the same policy + // - Cannot be “budget-policy-name”, “budget-policy-id” or + // "budget-policy-resolution-result" - these tags are preserved. + Key *string + // The value of the tag. + Value *string +} + +// Deletes a policy. +type DeleteBudgetPolicyRequest struct { + // The Id of the policy. + PolicyId *string + // The account Id of the customer + AccountId *string +} + +// Structured representation of a filter to be applied to a list of policies. +// All specified filters will be applied in conjunction.. +type Filter struct { + // The partial name of policies to be filtered on. If unspecified, all policies + // will be returned. + PolicyName *string + // The policy creator user id to be filtered on. If unspecified, all policies + // will be returned. + CreatorUserId *int64 + // Deprecated: Do not use this field in new integrations. Creator filtering will + // be removed in a future version. The policy creator user name to be filtered + // on. If unspecified, all policies will be returned. + CreatorUserName *string +} + +type GetBudgetPolicyRequest struct { + // The Id of the policy. + PolicyId *string + // The account Id of the customer + AccountId *string +} + +// The limit configuration of the policy. Limit configuration provide a budget +// policy level cost control by enforcing the limit.. +type LimitConfig struct { +} + +// Request to list budget policies. Uses pagination.. +type ListBudgetPoliciesRequest struct { + // The maximum number of budget policies to return. If unspecified, at most 100 + // budget policies will be returned. The maximum value is 1000; values above + // 1000 will be coerced to 1000. + PageSize *int + // A page token, received from a previous `ListServerlessPolicies` call. Provide + // this to retrieve the subsequent page. If unspecified, the first page will be + // returned. + // + // When paginating, all other parameters provided to + // `ListServerlessPoliciesRequest` must match the call that provided the page + // token. + PageToken *string + // A filter to apply to the list of policies. + FilterBy *Filter + // The sort specification. + SortSpec *SortSpec + // The account Id of the customer + AccountId *string +} + +// A list of policies.. +type ListBudgetPoliciesResponse struct { + Policies []BudgetPolicy + // A token that can be sent as `page_token` to retrieve the next page. If this + // field is omitted, there are no subsequent pages. + NextPageToken *string + // A token that can be sent as `page_token` to retrieve the previous page. In + // this field is omitted, there are no previous pages. + PreviousPageToken *string +} + +type SortSpec struct { + // The filed to sort by + Field SortSpec_Field + // Whether to sort in descending order. + Descending *bool +} + +// Updates a BudgetPolicy.. +type UpdateBudgetPolicyRequest struct { + // The policy to update. `creator_user_id` cannot be specified in the request. + // All other fields must be specified even if not changed. The `policy_id` is + // used to identify the policy to update. + Policy *BudgetPolicy + // The account Id of the customer + AccountId *string + // DEPRECATED. This is redundant field as LimitConfig is part of the + // BudgetPolicy + LimitConfig *LimitConfig +} diff --git a/budgetpolicy/v1/wire.go b/budgetpolicy/v1/wire.go new file mode 100755 index 0000000..ae43faf --- /dev/null +++ b/budgetpolicy/v1/wire.go @@ -0,0 +1,224 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package budgetpolicy + +import ( + "fmt" +) + +type budgetPolicyWire struct { + PolicyId *string `json:"policy_id,omitempty"` + PolicyName *string `json:"policy_name,omitempty"` + CustomTags []customPolicyTagWire `json:"custom_tags,omitempty"` + BindingWorkspaceIds []int64 `json:"binding_workspace_ids,omitempty"` +} + +func budgetPolicyToWire(v *BudgetPolicy) (*budgetPolicyWire, error) { + if v == nil { + return nil, nil + } + customTagsWireValue, err := convertSlice(v.CustomTags, customPolicyTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BudgetPolicy.CustomTags", err) + } + return &budgetPolicyWire{ + PolicyId: v.PolicyId, + PolicyName: v.PolicyName, + CustomTags: customTagsWireValue, + BindingWorkspaceIds: v.BindingWorkspaceIds, + }, nil +} + +func budgetPolicyFromWire(w *budgetPolicyWire) (*BudgetPolicy, error) { + if w == nil { + return nil, nil + } + customTagsPublicValue, err := convertSlice(w.CustomTags, customPolicyTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BudgetPolicy.CustomTags", err) + } + return &BudgetPolicy{ + PolicyId: w.PolicyId, + PolicyName: w.PolicyName, + CustomTags: customTagsPublicValue, + BindingWorkspaceIds: w.BindingWorkspaceIds, + }, nil +} + +type createBudgetPolicyRequestWire struct { + RequestId *string `json:"request_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + Policy *budgetPolicyWire `json:"policy,omitempty"` +} + +func createBudgetPolicyRequestToWire(v *CreateBudgetPolicyRequest) (*createBudgetPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + policyWireValue, err := budgetPolicyToWire(v.Policy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateBudgetPolicyRequest.Policy", err) + } + return &createBudgetPolicyRequestWire{ + RequestId: v.RequestId, + AccountId: v.AccountId, + Policy: policyWireValue, + }, nil +} + +type customPolicyTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func customPolicyTagToWire(v *CustomPolicyTag) (*customPolicyTagWire, error) { + if v == nil { + return nil, nil + } + return &customPolicyTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func customPolicyTagFromWire(w *customPolicyTagWire) (*CustomPolicyTag, error) { + if w == nil { + return nil, nil + } + return &CustomPolicyTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type filterWire struct { + PolicyName *string `json:"policy_name,omitempty"` + CreatorUserId *int64 `json:"creator_user_id,omitempty"` + CreatorUserName *string `json:"creator_user_name,omitempty"` +} + +func filterToWire(v *Filter) (*filterWire, error) { + if v == nil { + return nil, nil + } + return &filterWire{ + PolicyName: v.PolicyName, + CreatorUserId: v.CreatorUserId, + CreatorUserName: v.CreatorUserName, + }, nil +} + +type limitConfigWire struct { +} + +func limitConfigToWire(v *LimitConfig) (*limitConfigWire, error) { + if v == nil { + return nil, nil + } + return &limitConfigWire{}, nil +} + +type listBudgetPoliciesRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` + FilterBy *filterWire `json:"filter_by,omitempty"` + SortSpec *sortSpecWire `json:"sort_spec,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func listBudgetPoliciesRequestToWire(v *ListBudgetPoliciesRequest) (*listBudgetPoliciesRequestWire, error) { + if v == nil { + return nil, nil + } + filterByWireValue, err := filterToWire(v.FilterBy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListBudgetPoliciesRequest.FilterBy", err) + } + sortSpecWireValue, err := sortSpecToWire(v.SortSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListBudgetPoliciesRequest.SortSpec", err) + } + return &listBudgetPoliciesRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + FilterBy: filterByWireValue, + SortSpec: sortSpecWireValue, + AccountId: v.AccountId, + }, nil +} + +type listBudgetPoliciesResponseWire struct { + Policies []budgetPolicyWire `json:"policies,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` + PreviousPageToken *string `json:"previous_page_token,omitempty"` +} + +func listBudgetPoliciesResponseFromWire(w *listBudgetPoliciesResponseWire) (*ListBudgetPoliciesResponse, error) { + if w == nil { + return nil, nil + } + policiesPublicValue, err := convertSlice(w.Policies, budgetPolicyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListBudgetPoliciesResponse.Policies", err) + } + return &ListBudgetPoliciesResponse{ + Policies: policiesPublicValue, + NextPageToken: w.NextPageToken, + PreviousPageToken: w.PreviousPageToken, + }, nil +} + +type sortSpecWire struct { + Field SortSpec_Field `json:"field,omitempty"` + Descending *bool `json:"descending,omitempty"` +} + +func sortSpecToWire(v *SortSpec) (*sortSpecWire, error) { + if v == nil { + return nil, nil + } + return &sortSpecWire{ + Field: v.Field, + Descending: v.Descending, + }, nil +} + +type updateBudgetPolicyRequestWire struct { + Policy *budgetPolicyWire `json:"policy,omitempty"` + AccountId *string `json:"account_id,omitempty"` + LimitConfig *limitConfigWire `json:"limit_config,omitempty"` +} + +func updateBudgetPolicyRequestToWire(v *UpdateBudgetPolicyRequest) (*updateBudgetPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + policyWireValue, err := budgetPolicyToWire(v.Policy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateBudgetPolicyRequest.Policy", err) + } + limitConfigWireValue, err := limitConfigToWire(v.LimitConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateBudgetPolicyRequest.LimitConfig", err) + } + return &updateBudgetPolicyRequestWire{ + Policy: policyWireValue, + AccountId: v.AccountId, + LimitConfig: limitConfigWireValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/budgets/.package.json b/budgets/.package.json new file mode 100644 index 0000000..f9fb515 --- /dev/null +++ b/budgets/.package.json @@ -0,0 +1,3 @@ +{ + "package": "budgets" +} diff --git a/budgets/CHANGELOG.md b/budgets/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/budgets/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/budgets/README.md b/budgets/README.md new file mode 100644 index 0000000..0f05b0e --- /dev/null +++ b/budgets/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/budgets + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/budgets@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/budgets/v1" + +client, err := budgets.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/budgets/go.mod b/budgets/go.mod new file mode 100644 index 0000000..495cb52 --- /dev/null +++ b/budgets/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/budgets + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/budgets/internal/version.go b/budgets/internal/version.go new file mode 100644 index 0000000..70ff57e --- /dev/null +++ b/budgets/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-budgets" + +const Version = "0.0.1-dev.1" diff --git a/budgets/v1/client.go b/budgets/v1/client.go new file mode 100755 index 0000000..ed5145c --- /dev/null +++ b/budgets/v1/client.go @@ -0,0 +1,467 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package budgets + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/budgets/internal" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a new budget configuration for an account. For full details, see +// https://docs.databricks.com/en/admin/account-settings/budgets.html. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateBudgetConfiguration(ctx context.Context, req *CreateBudgetConfigurationRequest, opts ...call.Option) (*CreateBudgetConfigurationResponse, error) { + wireReq, err := createBudgetConfigurationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/budgets") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateBudgetConfigurationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createBudgetConfigurationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createBudgetConfigurationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a budget configuration for an account. Both account and budget +// configuration are specified by ID. This cannot be undone. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteBudgetConfiguration(ctx context.Context, req *DeleteBudgetConfigurationRequest, opts ...call.Option) (*DeleteBudgetConfigurationResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/budgets/") + pb.singleSegment(*req.BudgetId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteBudgetConfigurationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteBudgetConfigurationResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a budget configuration for an account. Both account and budget +// configuration are specified by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetBudgetConfiguration(ctx context.Context, req *GetBudgetConfigurationRequest, opts ...call.Option) (*GetBudgetConfigurationResponse, error) { + wireReq, err := getBudgetConfigurationRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/budgets/") + pb.singleSegment(*req.BudgetId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_spend_status", wireReq.IncludeSpendStatus); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetBudgetConfigurationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getBudgetConfigurationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getBudgetConfigurationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets all budgets associated with this account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListBudgetConfigurations(ctx context.Context, req *ListBudgetConfigurationsRequest, opts ...call.Option) (*ListBudgetConfigurationsResponse, error) { + wireReq, err := listBudgetConfigurationsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/budgets") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_spend_status", wireReq.IncludeSpendStatus); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_workspace_budgets", wireReq.IncludeWorkspaceBudgets); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListBudgetConfigurationsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listBudgetConfigurationsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listBudgetConfigurationsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListBudgetConfigurationsIter returns an iterator that iterates +// over the results of ListBudgetConfigurations. +// +// For example: +// +// for item, err := range c.ListBudgetConfigurationsIter(ctx, &ListBudgetConfigurationsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListBudgetConfigurations call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListBudgetConfigurations directly. +func (c *internalClient) ListBudgetConfigurationsIter(ctx context.Context, req *ListBudgetConfigurationsRequest, opts ...call.Option) iter.Seq2[*BudgetConfiguration, error] { + return func(yield func(*BudgetConfiguration, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListBudgetConfigurationsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListBudgetConfigurations(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Budgets { + if !yield(&resp.Budgets[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates a budget configuration for an account. Both account and budget +// configuration are specified by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateBudgetConfiguration(ctx context.Context, req *UpdateBudgetConfigurationRequest, opts ...call.Option) (*UpdateBudgetConfigurationResponse, error) { + wireReq, err := updateBudgetConfigurationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/budgets/") + pb.singleSegment(*req.BudgetId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateBudgetConfigurationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateBudgetConfigurationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateBudgetConfigurationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/budgets/v1/genhelper.go b/budgets/v1/genhelper.go new file mode 100755 index 0000000..5128aa3 --- /dev/null +++ b/budgets/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package budgets + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/budgets/v1/model.go b/budgets/v1/model.go new file mode 100755 index 0000000..f22fc93 --- /dev/null +++ b/budgets/v1/model.go @@ -0,0 +1,270 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package budgets + +// Type of action that a budget alert executes when its threshold is crossed. +type ActionConfigurationType string + +const ( + ActionConfigurationType_Unspecified ActionConfigurationType = "" + ActionConfigurationType_EmailNotification ActionConfigurationType = "EMAIL_NOTIFICATION" + // Blocks further usage when the alert threshold is reached. Supported only on + // AI Gateway budgets. No `target` is required for this action type. + ActionConfigurationType_BlockUsage ActionConfigurationType = "BLOCK_USAGE" +) + +type AlertConfigurationQuantityType string + +const ( + AlertConfigurationQuantityType_Unspecified AlertConfigurationQuantityType = "" + AlertConfigurationQuantityType_ListPriceDollarsUsd AlertConfigurationQuantityType = "LIST_PRICE_DOLLARS_USD" +) + +// Evaluation scope for an alert configuration. +type AlertConfigurationScopeType string + +const ( + AlertConfigurationScopeType_Unspecified AlertConfigurationScopeType = "" + // Alert evaluates aggregate spend across all users. + AlertConfigurationScopeType_AlertConfigurationScopeTypeShared AlertConfigurationScopeType = "ALERT_CONFIGURATION_SCOPE_TYPE_SHARED" + // Alert evaluates spend per individual user identity. + AlertConfigurationScopeType_AlertConfigurationScopeTypePerUser AlertConfigurationScopeType = "ALERT_CONFIGURATION_SCOPE_TYPE_PER_USER" +) + +type AlertConfigurationTimePeriod string + +const ( + AlertConfigurationTimePeriod_Unspecified AlertConfigurationTimePeriod = "" + AlertConfigurationTimePeriod_Month AlertConfigurationTimePeriod = "MONTH" +) + +type AlertConfigurationTriggerType string + +const ( + AlertConfigurationTriggerType_Unspecified AlertConfigurationTriggerType = "" + AlertConfigurationTriggerType_CumulativeSpendingExceeded AlertConfigurationTriggerType = "CUMULATIVE_SPENDING_EXCEEDED" +) + +// Resource scope for a budget configuration. Determines whether the budget +// tracks all resources or a specific resource. +type BudgetResourceType string + +const ( + BudgetResourceType_Unspecified BudgetResourceType = "" + // The budget applies to spending across all resources. + BudgetResourceType_BudgetResourceTypeAllResources BudgetResourceType = "BUDGET_RESOURCE_TYPE_ALL_RESOURCES" + // The budget applies only to Unity AI Gateway spending. + BudgetResourceType_BudgetResourceTypeUnityAiGateway BudgetResourceType = "BUDGET_RESOURCE_TYPE_UNITY_AI_GATEWAY" +) + +type BudgetConfigurationFilter_Operator string + +const ( + BudgetConfigurationFilter_Operator_Unspecified BudgetConfigurationFilter_Operator = "" + BudgetConfigurationFilter_Operator_In BudgetConfigurationFilter_Operator = "IN" +) + +type ActionConfiguration struct { + // action configuration ID. + ActionConfigurationId *string + // The type of the action. + ActionType ActionConfigurationType + // Target for the action. For example, an email address. + Target *string +} + +type AlertConfiguration struct { + // alert configuration ID. + AlertConfigurationId *string + // The time window of usage data for the budget. + TimePeriod AlertConfigurationTimePeriod + // The evaluation method to determine when this budget alert is in a triggered + // state. + TriggerType AlertConfigurationTriggerType + // The way to calculate cost for this budget alert. This is what + // `quantity_threshold` is measured in. + QuantityType AlertConfigurationQuantityType + // The threshold for the budget alert to determine if it is in a triggered + // state. The number is evaluated based on `quantity_type`. + QuantityThreshold *string + // Configured actions for this alert. These define what happens when an alert + // enters a triggered state. + ActionConfigurations []ActionConfiguration + // How the alert threshold is evaluated. Determines whether spend is tracked in + // aggregate or per individual user. + ScopeType AlertConfigurationScopeType + // Per-principal threshold overrides for this alert. Only applies to per-user + // alerts (`scope_type` = `ALERT_CONFIGURATION_SCOPE_TYPE_PER_USER`); ignored + // for shared alerts. + PrincipalOverrides []PrincipalOverride +} + +type BudgetConfiguration struct { + // budget configuration ID. + BudgetConfigurationId *string + // account ID. + AccountId *string + // Creation time of this budget configuration. + CreateTime *int64 + // Update time of this budget configuration. + UpdateTime *int64 + // Alerts to configure when this budget is in a triggered state. Budgets must + // have exactly one alert configuration. + AlertConfigurations []AlertConfiguration + // Configured filters for this budget. These are applied to your account's usage + // to limit the scope of what is considered for this budget. Leave empty to + // include all usage for this account. All provided filters must be matched for + // usage to be included. + Filter *BudgetConfigurationFilter + // Human-readable name of budget configuration. Max Length: 128 + DisplayName *string + // The resource scope for this budget. Determines whether the budget tracks all + // resources or a specific resource. + ResourceType BudgetResourceType +} + +type BudgetConfigurationFilter struct { + // If provided, usage must match with the provided workspace IDs. + WorkspaceId *BudgetConfigurationFilter_WorkspaceIdClause + // A list of tag keys and values that will limit the budget to usage that + // includes those specific custom tags. Tags are case-sensitive and should be + // entered exactly as they appear in your usage data. + Tags []BudgetConfigurationFilter_TagClause +} + +type BudgetConfigurationFilter_Clause struct { + Operator BudgetConfigurationFilter_Operator + Values []string +} + +type BudgetConfigurationFilter_TagClause struct { + Key *string + Value *BudgetConfigurationFilter_Clause +} + +type BudgetConfigurationFilter_WorkspaceIdClause struct { + Operator BudgetConfigurationFilter_Operator + Values []int64 +} + +type CreateBudgetConfigurationBudget struct { + // budget configuration ID. + BudgetConfigurationId *string + // account ID. + AccountId *string + // Creation time of this budget configuration. + CreateTime *int64 + // Update time of this budget configuration. + UpdateTime *int64 + // Alerts to configure when this budget is in a triggered state. Budgets must + // have exactly one alert configuration. + AlertConfigurations []AlertConfiguration + // Configured filters for this budget. These are applied to your account's usage + // to limit the scope of what is considered for this budget. Leave empty to + // include all usage for this account. All provided filters must be matched for + // usage to be included. + Filter *BudgetConfigurationFilter + // Human-readable name of budget configuration. Max Length: 128 + DisplayName *string + // The resource scope for this budget. Determines whether the budget tracks all + // resources or a specific resource. + ResourceType BudgetResourceType +} + +type CreateBudgetConfigurationRequest struct { + // Properties of the new budget configuration. + Budget *CreateBudgetConfigurationBudget +} + +type CreateBudgetConfigurationResponse struct { + // The created budget configuration. + Budget *BudgetConfiguration +} + +// * Delete budget. +type DeleteBudgetConfigurationRequest struct { + // The budget configuration ID. + BudgetId *string + // account ID. + AccountId *string +} + +type DeleteBudgetConfigurationResponse struct { +} + +type GetBudgetConfigurationRequest struct { + // The budget configuration ID + BudgetId *string + // account ID. + AccountId *string + IncludeSpendStatus *bool +} + +type GetBudgetConfigurationResponse struct { + Budget *BudgetConfiguration +} + +type ListBudgetConfigurationsRequest struct { + // account ID. + AccountId *string + // A page token received from a previous get all budget configurations call. + // This token can be used to retrieve the subsequent page. Requests first page + // if absent. + PageToken *string + IncludeSpendStatus *bool + IncludeWorkspaceBudgets *bool +} + +type ListBudgetConfigurationsResponse struct { + Budgets []BudgetConfiguration + // Token which can be sent as `page_token` to retrieve the next page of results. + // If this field is omitted, there are no subsequent budgets. + NextPageToken *string +} + +// Per-principal threshold override on a PER_USER alert: bumps the alert's +// quantity_threshold for one principal_id.. +type PrincipalOverride struct { + // Account-level principal id (user, group, or service principal). + PrincipalId *int64 + // Dollar amount that overrides the parent alert's quantity_threshold for this + // principal. + OverrideThreshold *string +} + +type UpdateBudgetConfigurationBudget struct { + // budget configuration ID. + BudgetConfigurationId *string + // account ID. + AccountId *string + // Creation time of this budget configuration. + CreateTime *int64 + // Update time of this budget configuration. + UpdateTime *int64 + // Alerts to configure when this budget is in a triggered state. Budgets must + // have exactly one alert configuration. + AlertConfigurations []AlertConfiguration + // Configured filters for this budget. These are applied to your account's usage + // to limit the scope of what is considered for this budget. Leave empty to + // include all usage for this account. All provided filters must be matched for + // usage to be included. + Filter *BudgetConfigurationFilter + // Human-readable name of budget configuration. Max Length: 128 + DisplayName *string + // The resource scope for this budget. Determines whether the budget tracks all + // resources or a specific resource. + ResourceType BudgetResourceType +} + +type UpdateBudgetConfigurationRequest struct { + // The budget configuration ID. + BudgetId *string + // The updated budget. This will overwrite the budget specified by the budget + // ID. + Budget *UpdateBudgetConfigurationBudget +} + +type UpdateBudgetConfigurationResponse struct { + // The updated budget. + Budget *BudgetConfiguration +} diff --git a/budgets/v1/wire.go b/budgets/v1/wire.go new file mode 100755 index 0000000..82b7f17 --- /dev/null +++ b/budgets/v1/wire.go @@ -0,0 +1,505 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package budgets + +import ( + "fmt" +) + +type actionConfigurationWire struct { + ActionConfigurationId *string `json:"action_configuration_id,omitempty"` + ActionType ActionConfigurationType `json:"action_type,omitempty"` + Target *string `json:"target,omitempty"` +} + +func actionConfigurationToWire(v *ActionConfiguration) (*actionConfigurationWire, error) { + if v == nil { + return nil, nil + } + return &actionConfigurationWire{ + ActionConfigurationId: v.ActionConfigurationId, + ActionType: v.ActionType, + Target: v.Target, + }, nil +} + +func actionConfigurationFromWire(w *actionConfigurationWire) (*ActionConfiguration, error) { + if w == nil { + return nil, nil + } + return &ActionConfiguration{ + ActionConfigurationId: w.ActionConfigurationId, + ActionType: w.ActionType, + Target: w.Target, + }, nil +} + +type alertConfigurationWire struct { + AlertConfigurationId *string `json:"alert_configuration_id,omitempty"` + TimePeriod AlertConfigurationTimePeriod `json:"time_period,omitempty"` + TriggerType AlertConfigurationTriggerType `json:"trigger_type,omitempty"` + QuantityType AlertConfigurationQuantityType `json:"quantity_type,omitempty"` + QuantityThreshold *string `json:"quantity_threshold,omitempty"` + ActionConfigurations []actionConfigurationWire `json:"action_configurations,omitempty"` + ScopeType AlertConfigurationScopeType `json:"scope_type,omitempty"` + PrincipalOverrides []principalOverrideWire `json:"principal_overrides,omitempty"` +} + +func alertConfigurationToWire(v *AlertConfiguration) (*alertConfigurationWire, error) { + if v == nil { + return nil, nil + } + actionConfigurationsWireValue, err := convertSlice(v.ActionConfigurations, actionConfigurationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertConfiguration.ActionConfigurations", err) + } + principalOverridesWireValue, err := convertSlice(v.PrincipalOverrides, principalOverrideToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertConfiguration.PrincipalOverrides", err) + } + return &alertConfigurationWire{ + AlertConfigurationId: v.AlertConfigurationId, + TimePeriod: v.TimePeriod, + TriggerType: v.TriggerType, + QuantityType: v.QuantityType, + QuantityThreshold: v.QuantityThreshold, + ActionConfigurations: actionConfigurationsWireValue, + ScopeType: v.ScopeType, + PrincipalOverrides: principalOverridesWireValue, + }, nil +} + +func alertConfigurationFromWire(w *alertConfigurationWire) (*AlertConfiguration, error) { + if w == nil { + return nil, nil + } + actionConfigurationsPublicValue, err := convertSlice(w.ActionConfigurations, actionConfigurationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertConfiguration.ActionConfigurations", err) + } + principalOverridesPublicValue, err := convertSlice(w.PrincipalOverrides, principalOverrideFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertConfiguration.PrincipalOverrides", err) + } + return &AlertConfiguration{ + AlertConfigurationId: w.AlertConfigurationId, + TimePeriod: w.TimePeriod, + TriggerType: w.TriggerType, + QuantityType: w.QuantityType, + QuantityThreshold: w.QuantityThreshold, + ActionConfigurations: actionConfigurationsPublicValue, + ScopeType: w.ScopeType, + PrincipalOverrides: principalOverridesPublicValue, + }, nil +} + +type budgetConfigurationWire struct { + BudgetConfigurationId *string `json:"budget_configuration_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + CreateTime *int64 `json:"create_time,omitempty"` + UpdateTime *int64 `json:"update_time,omitempty"` + AlertConfigurations []alertConfigurationWire `json:"alert_configurations,omitempty"` + Filter *budgetConfigurationFilterWire `json:"filter,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + ResourceType BudgetResourceType `json:"resource_type,omitempty"` +} + +func budgetConfigurationFromWire(w *budgetConfigurationWire) (*BudgetConfiguration, error) { + if w == nil { + return nil, nil + } + alertConfigurationsPublicValue, err := convertSlice(w.AlertConfigurations, alertConfigurationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BudgetConfiguration.AlertConfigurations", err) + } + filterPublicValue, err := budgetConfigurationFilterFromWire(w.Filter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BudgetConfiguration.Filter", err) + } + return &BudgetConfiguration{ + BudgetConfigurationId: w.BudgetConfigurationId, + AccountId: w.AccountId, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + AlertConfigurations: alertConfigurationsPublicValue, + Filter: filterPublicValue, + DisplayName: w.DisplayName, + ResourceType: w.ResourceType, + }, nil +} + +type budgetConfigurationFilterWire struct { + WorkspaceId *budgetConfigurationFilter_WorkspaceIdClauseWire `json:"workspace_id,omitempty"` + Tags []budgetConfigurationFilter_TagClauseWire `json:"tags,omitempty"` +} + +func budgetConfigurationFilterToWire(v *BudgetConfigurationFilter) (*budgetConfigurationFilterWire, error) { + if v == nil { + return nil, nil + } + workspaceIdWireValue, err := budgetConfigurationFilter_WorkspaceIdClauseToWire(v.WorkspaceId) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BudgetConfigurationFilter.WorkspaceId", err) + } + tagsWireValue, err := convertSlice(v.Tags, budgetConfigurationFilter_TagClauseToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BudgetConfigurationFilter.Tags", err) + } + return &budgetConfigurationFilterWire{ + WorkspaceId: workspaceIdWireValue, + Tags: tagsWireValue, + }, nil +} + +func budgetConfigurationFilterFromWire(w *budgetConfigurationFilterWire) (*BudgetConfigurationFilter, error) { + if w == nil { + return nil, nil + } + workspaceIdPublicValue, err := budgetConfigurationFilter_WorkspaceIdClauseFromWire(w.WorkspaceId) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BudgetConfigurationFilter.WorkspaceId", err) + } + tagsPublicValue, err := convertSlice(w.Tags, budgetConfigurationFilter_TagClauseFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BudgetConfigurationFilter.Tags", err) + } + return &BudgetConfigurationFilter{ + WorkspaceId: workspaceIdPublicValue, + Tags: tagsPublicValue, + }, nil +} + +type budgetConfigurationFilter_ClauseWire struct { + Operator BudgetConfigurationFilter_Operator `json:"operator,omitempty"` + Values []string `json:"values,omitempty"` +} + +func budgetConfigurationFilter_ClauseToWire(v *BudgetConfigurationFilter_Clause) (*budgetConfigurationFilter_ClauseWire, error) { + if v == nil { + return nil, nil + } + return &budgetConfigurationFilter_ClauseWire{ + Operator: v.Operator, + Values: v.Values, + }, nil +} + +func budgetConfigurationFilter_ClauseFromWire(w *budgetConfigurationFilter_ClauseWire) (*BudgetConfigurationFilter_Clause, error) { + if w == nil { + return nil, nil + } + return &BudgetConfigurationFilter_Clause{ + Operator: w.Operator, + Values: w.Values, + }, nil +} + +type budgetConfigurationFilter_TagClauseWire struct { + Key *string `json:"key,omitempty"` + Value *budgetConfigurationFilter_ClauseWire `json:"value,omitempty"` +} + +func budgetConfigurationFilter_TagClauseToWire(v *BudgetConfigurationFilter_TagClause) (*budgetConfigurationFilter_TagClauseWire, error) { + if v == nil { + return nil, nil + } + valueWireValue, err := budgetConfigurationFilter_ClauseToWire(v.Value) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BudgetConfigurationFilter_TagClause.Value", err) + } + return &budgetConfigurationFilter_TagClauseWire{ + Key: v.Key, + Value: valueWireValue, + }, nil +} + +func budgetConfigurationFilter_TagClauseFromWire(w *budgetConfigurationFilter_TagClauseWire) (*BudgetConfigurationFilter_TagClause, error) { + if w == nil { + return nil, nil + } + valuePublicValue, err := budgetConfigurationFilter_ClauseFromWire(w.Value) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BudgetConfigurationFilter_TagClause.Value", err) + } + return &BudgetConfigurationFilter_TagClause{ + Key: w.Key, + Value: valuePublicValue, + }, nil +} + +type budgetConfigurationFilter_WorkspaceIdClauseWire struct { + Operator BudgetConfigurationFilter_Operator `json:"operator,omitempty"` + Values []int64 `json:"values,omitempty"` +} + +func budgetConfigurationFilter_WorkspaceIdClauseToWire(v *BudgetConfigurationFilter_WorkspaceIdClause) (*budgetConfigurationFilter_WorkspaceIdClauseWire, error) { + if v == nil { + return nil, nil + } + return &budgetConfigurationFilter_WorkspaceIdClauseWire{ + Operator: v.Operator, + Values: v.Values, + }, nil +} + +func budgetConfigurationFilter_WorkspaceIdClauseFromWire(w *budgetConfigurationFilter_WorkspaceIdClauseWire) (*BudgetConfigurationFilter_WorkspaceIdClause, error) { + if w == nil { + return nil, nil + } + return &BudgetConfigurationFilter_WorkspaceIdClause{ + Operator: w.Operator, + Values: w.Values, + }, nil +} + +type createBudgetConfigurationBudgetWire struct { + BudgetConfigurationId *string `json:"budget_configuration_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + CreateTime *int64 `json:"create_time,omitempty"` + UpdateTime *int64 `json:"update_time,omitempty"` + AlertConfigurations []alertConfigurationWire `json:"alert_configurations,omitempty"` + Filter *budgetConfigurationFilterWire `json:"filter,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + ResourceType BudgetResourceType `json:"resource_type,omitempty"` +} + +func createBudgetConfigurationBudgetToWire(v *CreateBudgetConfigurationBudget) (*createBudgetConfigurationBudgetWire, error) { + if v == nil { + return nil, nil + } + alertConfigurationsWireValue, err := convertSlice(v.AlertConfigurations, alertConfigurationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateBudgetConfigurationBudget.AlertConfigurations", err) + } + filterWireValue, err := budgetConfigurationFilterToWire(v.Filter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateBudgetConfigurationBudget.Filter", err) + } + return &createBudgetConfigurationBudgetWire{ + BudgetConfigurationId: v.BudgetConfigurationId, + AccountId: v.AccountId, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + AlertConfigurations: alertConfigurationsWireValue, + Filter: filterWireValue, + DisplayName: v.DisplayName, + ResourceType: v.ResourceType, + }, nil +} + +type createBudgetConfigurationRequestWire struct { + Budget *createBudgetConfigurationBudgetWire `json:"budget,omitempty"` +} + +func createBudgetConfigurationRequestToWire(v *CreateBudgetConfigurationRequest) (*createBudgetConfigurationRequestWire, error) { + if v == nil { + return nil, nil + } + budgetWireValue, err := createBudgetConfigurationBudgetToWire(v.Budget) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateBudgetConfigurationRequest.Budget", err) + } + return &createBudgetConfigurationRequestWire{ + Budget: budgetWireValue, + }, nil +} + +type createBudgetConfigurationResponseWire struct { + Budget *budgetConfigurationWire `json:"budget,omitempty"` +} + +func createBudgetConfigurationResponseFromWire(w *createBudgetConfigurationResponseWire) (*CreateBudgetConfigurationResponse, error) { + if w == nil { + return nil, nil + } + budgetPublicValue, err := budgetConfigurationFromWire(w.Budget) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateBudgetConfigurationResponse.Budget", err) + } + return &CreateBudgetConfigurationResponse{ + Budget: budgetPublicValue, + }, nil +} + +type getBudgetConfigurationRequestWire struct { + BudgetId *string `json:"budget_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + IncludeSpendStatus *bool `json:"include_spend_status,omitempty"` +} + +func getBudgetConfigurationRequestToWire(v *GetBudgetConfigurationRequest) (*getBudgetConfigurationRequestWire, error) { + if v == nil { + return nil, nil + } + return &getBudgetConfigurationRequestWire{ + BudgetId: v.BudgetId, + AccountId: v.AccountId, + IncludeSpendStatus: v.IncludeSpendStatus, + }, nil +} + +type getBudgetConfigurationResponseWire struct { + Budget *budgetConfigurationWire `json:"budget,omitempty"` +} + +func getBudgetConfigurationResponseFromWire(w *getBudgetConfigurationResponseWire) (*GetBudgetConfigurationResponse, error) { + if w == nil { + return nil, nil + } + budgetPublicValue, err := budgetConfigurationFromWire(w.Budget) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetBudgetConfigurationResponse.Budget", err) + } + return &GetBudgetConfigurationResponse{ + Budget: budgetPublicValue, + }, nil +} + +type listBudgetConfigurationsRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + IncludeSpendStatus *bool `json:"include_spend_status,omitempty"` + IncludeWorkspaceBudgets *bool `json:"include_workspace_budgets,omitempty"` +} + +func listBudgetConfigurationsRequestToWire(v *ListBudgetConfigurationsRequest) (*listBudgetConfigurationsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listBudgetConfigurationsRequestWire{ + AccountId: v.AccountId, + PageToken: v.PageToken, + IncludeSpendStatus: v.IncludeSpendStatus, + IncludeWorkspaceBudgets: v.IncludeWorkspaceBudgets, + }, nil +} + +type listBudgetConfigurationsResponseWire struct { + Budgets []budgetConfigurationWire `json:"budgets,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listBudgetConfigurationsResponseFromWire(w *listBudgetConfigurationsResponseWire) (*ListBudgetConfigurationsResponse, error) { + if w == nil { + return nil, nil + } + budgetsPublicValue, err := convertSlice(w.Budgets, budgetConfigurationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListBudgetConfigurationsResponse.Budgets", err) + } + return &ListBudgetConfigurationsResponse{ + Budgets: budgetsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type principalOverrideWire struct { + PrincipalId *int64 `json:"principal_id,omitempty"` + OverrideThreshold *string `json:"override_threshold,omitempty"` +} + +func principalOverrideToWire(v *PrincipalOverride) (*principalOverrideWire, error) { + if v == nil { + return nil, nil + } + return &principalOverrideWire{ + PrincipalId: v.PrincipalId, + OverrideThreshold: v.OverrideThreshold, + }, nil +} + +func principalOverrideFromWire(w *principalOverrideWire) (*PrincipalOverride, error) { + if w == nil { + return nil, nil + } + return &PrincipalOverride{ + PrincipalId: w.PrincipalId, + OverrideThreshold: w.OverrideThreshold, + }, nil +} + +type updateBudgetConfigurationBudgetWire struct { + BudgetConfigurationId *string `json:"budget_configuration_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + CreateTime *int64 `json:"create_time,omitempty"` + UpdateTime *int64 `json:"update_time,omitempty"` + AlertConfigurations []alertConfigurationWire `json:"alert_configurations,omitempty"` + Filter *budgetConfigurationFilterWire `json:"filter,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + ResourceType BudgetResourceType `json:"resource_type,omitempty"` +} + +func updateBudgetConfigurationBudgetToWire(v *UpdateBudgetConfigurationBudget) (*updateBudgetConfigurationBudgetWire, error) { + if v == nil { + return nil, nil + } + alertConfigurationsWireValue, err := convertSlice(v.AlertConfigurations, alertConfigurationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateBudgetConfigurationBudget.AlertConfigurations", err) + } + filterWireValue, err := budgetConfigurationFilterToWire(v.Filter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateBudgetConfigurationBudget.Filter", err) + } + return &updateBudgetConfigurationBudgetWire{ + BudgetConfigurationId: v.BudgetConfigurationId, + AccountId: v.AccountId, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + AlertConfigurations: alertConfigurationsWireValue, + Filter: filterWireValue, + DisplayName: v.DisplayName, + ResourceType: v.ResourceType, + }, nil +} + +type updateBudgetConfigurationRequestWire struct { + BudgetId *string `json:"budget_id,omitempty"` + Budget *updateBudgetConfigurationBudgetWire `json:"budget,omitempty"` +} + +func updateBudgetConfigurationRequestToWire(v *UpdateBudgetConfigurationRequest) (*updateBudgetConfigurationRequestWire, error) { + if v == nil { + return nil, nil + } + budgetWireValue, err := updateBudgetConfigurationBudgetToWire(v.Budget) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateBudgetConfigurationRequest.Budget", err) + } + return &updateBudgetConfigurationRequestWire{ + BudgetId: v.BudgetId, + Budget: budgetWireValue, + }, nil +} + +type updateBudgetConfigurationResponseWire struct { + Budget *budgetConfigurationWire `json:"budget,omitempty"` +} + +func updateBudgetConfigurationResponseFromWire(w *updateBudgetConfigurationResponseWire) (*UpdateBudgetConfigurationResponse, error) { + if w == nil { + return nil, nil + } + budgetPublicValue, err := budgetConfigurationFromWire(w.Budget) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateBudgetConfigurationResponse.Budget", err) + } + return &UpdateBudgetConfigurationResponse{ + Budget: budgetPublicValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/cleanrooms/.package.json b/cleanrooms/.package.json new file mode 100644 index 0000000..c9baf18 --- /dev/null +++ b/cleanrooms/.package.json @@ -0,0 +1,3 @@ +{ + "package": "cleanrooms" +} diff --git a/cleanrooms/CHANGELOG.md b/cleanrooms/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/cleanrooms/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/cleanrooms/README.md b/cleanrooms/README.md new file mode 100644 index 0000000..8bac332 --- /dev/null +++ b/cleanrooms/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/cleanrooms + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/cleanrooms@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/cleanrooms/v1" + +client, err := cleanrooms.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/cleanrooms/go.mod b/cleanrooms/go.mod new file mode 100644 index 0000000..35a5d6e --- /dev/null +++ b/cleanrooms/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/cleanrooms + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/cleanrooms/internal/version.go b/cleanrooms/internal/version.go new file mode 100644 index 0000000..bc5c3e7 --- /dev/null +++ b/cleanrooms/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-cleanrooms" + +const Version = "0.0.1-dev.1" diff --git a/cleanrooms/v1/client.go b/cleanrooms/v1/client.go new file mode 100755 index 0000000..1fbb613 --- /dev/null +++ b/cleanrooms/v1/client.go @@ -0,0 +1,1878 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package cleanrooms + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/cleanrooms/internal" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a new clean room with the specified collaborators. This method is +// asynchronous; the returned name field inside the clean_room field can be used +// to poll the clean room status, using the [cleanrooms/get] method. When this +// method returns, the clean room will be in a PROVISIONING state, with only +// name, owner, comment, created_at and status populated. The clean room will be +// usable once it enters an ACTIVE state. +// +// The caller must be a metastore admin or have the **CREATE_CLEAN_ROOM** +// privilege on the metastore. +// +// [cleanrooms/get]: https://docs.databricks.com/api/workspace/cleanrooms/get +func (c *internalClient) createCleanRoomBase(ctx context.Context, req *CreateCleanRoomRequest, opts ...call.Option) (*CleanRoom, error) { + wireReq, err := createCleanRoomRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.CleanRoom) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/clean-rooms" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CleanRoom + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cleanRoomWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cleanRoomFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a new clean room with the specified collaborators. This method is +// asynchronous; the returned name field inside the clean_room field can be used +// to poll the clean room status, using the [cleanrooms/get] method. When this +// method returns, the clean room will be in a PROVISIONING state, with only +// name, owner, comment, created_at and status populated. The clean room will be +// usable once it enters an ACTIVE state. +// +// The caller must be a metastore admin or have the **CREATE_CLEAN_ROOM** +// privilege on the metastore. +// +// [cleanrooms/get]: https://docs.databricks.com/api/workspace/cleanrooms/get +func (c *internalClient) CreateCleanRoom(ctx context.Context, req *CreateCleanRoomRequest, opts ...call.Option) (*CreateCleanRoomWaiter, error) { + resp, err := c.createCleanRoomBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.Name == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "Name") + } + return &CreateCleanRoomWaiter{ + poll: c.GetCleanRoom, + name: *resp.Name, + }, nil +} + +// CreateCleanRoomWaiter tracks the state of the operation started by CreateCleanRoom. +type CreateCleanRoomWaiter struct { + poll func(context.Context, *GetCleanRoomRequest, ...call.Option) (*CleanRoom, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateCleanRoomWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetCleanRoomRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case CleanRoom_Status_Enum_Active: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateCleanRoomWaiter) Wait(ctx context.Context, opts ...lro.Option) (*CleanRoom, error) { + var result *CleanRoom + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetCleanRoomRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case CleanRoom_Status_Enum_Active: + result = pollResp + return nil + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Create a clean room asset —share an asset like a notebook or table into the +// clean room. For each UC asset that is added through this method, the clean +// room owner must also have enough privilege on the asset to consume it. The +// privilege must be maintained indefinitely for the clean room to be able to +// access the asset. Typically, you should use a group as the clean room owner. +func (c *internalClient) CreateCleanRoomAsset(ctx context.Context, req *CreateCleanRoomAssetRequest, opts ...call.Option) (*CleanRoomAsset, error) { + wireReq, err := createCleanRoomAssetRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Asset) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.Asset.CleanRoomName) + pb.literal("/assets") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CleanRoomAsset + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cleanRoomAssetWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cleanRoomAssetFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Submit an asset review +func (c *internalClient) CreateCleanRoomAssetReview(ctx context.Context, req *CreateCleanRoomAssetReviewRequest, opts ...call.Option) (*CreateCleanRoomAssetReviewResponse, error) { + wireReq, err := createCleanRoomAssetReviewRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + if req.AssetType == "" { + return nil, fmt.Errorf("path parameter %q is required", "asset_type") + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/assets/") + pb.singleSegment(req.AssetType) + pb.literal("/") + pb.singleSegment(*req.Name) + pb.literal("/reviews") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateCleanRoomAssetReviewResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createCleanRoomAssetReviewResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createCleanRoomAssetReviewResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create an auto-approval rule +func (c *internalClient) CreateCleanRoomAutoApprovalRule(ctx context.Context, req *CreateCleanRoomAutoApprovalRuleRequest, opts ...call.Option) (*CleanRoomAutoApprovalRule, error) { + wireReq, err := createCleanRoomAutoApprovalRuleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.AutoApprovalRule.CleanRoomName) + pb.literal("/auto-approval-rules") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CleanRoomAutoApprovalRule + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cleanRoomAutoApprovalRuleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cleanRoomAutoApprovalRuleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create the output catalog of the clean room. +func (c *internalClient) CreateCleanRoomOutputCatalog(ctx context.Context, req *CreateCleanRoomOutputCatalogRequest, opts ...call.Option) (*CreateCleanRoomOutputCatalogResponse, error) { + wireReq, err := createCleanRoomOutputCatalogRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.OutputCatalog) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/output-catalogs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateCleanRoomOutputCatalogResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createCleanRoomOutputCatalogResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createCleanRoomOutputCatalogResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a clean room. After deletion, the clean room will be removed from the +// metastore. If the other collaborators have not deleted the clean room, they +// will still have the clean room in their metastore, but it will be in a +// DELETED state and no operations other than deletion can be performed on it. +func (c *internalClient) DeleteCleanRoom(ctx context.Context, req *DeleteCleanRoomRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete a clean room asset - unshare/remove the asset from the clean room +func (c *internalClient) DeleteCleanRoomAsset(ctx context.Context, req *DeleteCleanRoomAssetRequest, opts ...call.Option) (*DeleteCleanRoomAssetResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + if req.AssetType == "" { + return nil, fmt.Errorf("path parameter %q is required", "asset_type") + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/assets/") + pb.singleSegment(req.AssetType) + pb.literal("/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteCleanRoomAssetResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteCleanRoomAssetResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a auto-approval rule by rule ID +func (c *internalClient) DeleteCleanRoomAutoApprovalRule(ctx context.Context, req *DeleteCleanRoomAutoApprovalRuleRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/auto-approval-rules/") + pb.singleSegment(*req.RuleId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Get the details of a clean room given its name. +func (c *internalClient) GetCleanRoom(ctx context.Context, req *GetCleanRoomRequest, opts ...call.Option) (*CleanRoom, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CleanRoom + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cleanRoomWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cleanRoomFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get the details of a clean room asset by its type and full name. +func (c *internalClient) GetCleanRoomAsset(ctx context.Context, req *GetCleanRoomAssetRequest, opts ...call.Option) (*CleanRoomAsset, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + if req.AssetType == "" { + return nil, fmt.Errorf("path parameter %q is required", "asset_type") + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/assets/") + pb.singleSegment(req.AssetType) + pb.literal("/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CleanRoomAsset + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cleanRoomAssetWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cleanRoomAssetFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a specific revision of an asset +func (c *internalClient) GetCleanRoomAssetRevision(ctx context.Context, req *GetCleanRoomAssetRevisionRequest, opts ...call.Option) (*CleanRoomAsset, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + if req.AssetType == "" { + return nil, fmt.Errorf("path parameter %q is required", "asset_type") + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/assets/") + pb.singleSegment(req.AssetType) + pb.literal("/") + pb.singleSegment(*req.Name) + pb.literal("/revisions/") + pb.singleSegment(*req.Etag) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CleanRoomAsset + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cleanRoomAssetWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cleanRoomAssetFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a auto-approval rule by rule ID +func (c *internalClient) GetCleanRoomAutoApprovalRule(ctx context.Context, req *GetCleanRoomAutoApprovalRuleRequest, opts ...call.Option) (*CleanRoomAutoApprovalRule, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/auto-approval-rules/") + pb.singleSegment(*req.RuleId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CleanRoomAutoApprovalRule + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cleanRoomAutoApprovalRuleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cleanRoomAutoApprovalRuleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List revisions for an asset +func (c *internalClient) ListCleanRoomAssetRevisions(ctx context.Context, req *ListCleanRoomAssetRevisionsRequest, opts ...call.Option) (*ListCleanRoomAssetRevisionsResponse, error) { + wireReq, err := listCleanRoomAssetRevisionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + if req.AssetType == "" { + return nil, fmt.Errorf("path parameter %q is required", "asset_type") + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/assets/") + pb.singleSegment(req.AssetType) + pb.literal("/") + pb.singleSegment(*req.Name) + pb.literal("/revisions") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCleanRoomAssetRevisionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCleanRoomAssetRevisionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCleanRoomAssetRevisionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCleanRoomAssetRevisionsIter returns an iterator that iterates +// over the results of ListCleanRoomAssetRevisions. +// +// For example: +// +// for item, err := range c.ListCleanRoomAssetRevisionsIter(ctx, &ListCleanRoomAssetRevisionsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCleanRoomAssetRevisions call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCleanRoomAssetRevisions directly. +func (c *internalClient) ListCleanRoomAssetRevisionsIter(ctx context.Context, req *ListCleanRoomAssetRevisionsRequest, opts ...call.Option) iter.Seq2[*CleanRoomAsset, error] { + return func(yield func(*CleanRoomAsset, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCleanRoomAssetRevisionsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCleanRoomAssetRevisions(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Revisions { + if !yield(&resp.Revisions[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List assets. +func (c *internalClient) ListCleanRoomAssets(ctx context.Context, req *ListCleanRoomAssetsRequest, opts ...call.Option) (*ListCleanRoomAssetsResponse, error) { + wireReq, err := listCleanRoomAssetsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/assets") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCleanRoomAssetsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCleanRoomAssetsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCleanRoomAssetsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCleanRoomAssetsIter returns an iterator that iterates +// over the results of ListCleanRoomAssets. +// +// For example: +// +// for item, err := range c.ListCleanRoomAssetsIter(ctx, &ListCleanRoomAssetsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCleanRoomAssets call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCleanRoomAssets directly. +func (c *internalClient) ListCleanRoomAssetsIter(ctx context.Context, req *ListCleanRoomAssetsRequest, opts ...call.Option) iter.Seq2[*CleanRoomAsset, error] { + return func(yield func(*CleanRoomAsset, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCleanRoomAssetsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCleanRoomAssets(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Assets { + if !yield(&resp.Assets[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List all auto-approval rules for the caller +func (c *internalClient) ListCleanRoomAutoApprovalRules(ctx context.Context, req *ListCleanRoomAutoApprovalRulesRequest, opts ...call.Option) (*ListCleanRoomAutoApprovalRulesResponse, error) { + wireReq, err := listCleanRoomAutoApprovalRulesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/auto-approval-rules") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCleanRoomAutoApprovalRulesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCleanRoomAutoApprovalRulesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCleanRoomAutoApprovalRulesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCleanRoomAutoApprovalRulesIter returns an iterator that iterates +// over the results of ListCleanRoomAutoApprovalRules. +// +// For example: +// +// for item, err := range c.ListCleanRoomAutoApprovalRulesIter(ctx, &ListCleanRoomAutoApprovalRulesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCleanRoomAutoApprovalRules call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCleanRoomAutoApprovalRules directly. +func (c *internalClient) ListCleanRoomAutoApprovalRulesIter(ctx context.Context, req *ListCleanRoomAutoApprovalRulesRequest, opts ...call.Option) iter.Seq2[*CleanRoomAutoApprovalRule, error] { + return func(yield func(*CleanRoomAutoApprovalRule, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCleanRoomAutoApprovalRulesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCleanRoomAutoApprovalRules(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Rules { + if !yield(&resp.Rules[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List all the historical notebook task runs in a clean room. +func (c *internalClient) ListCleanRoomNotebookTaskRuns(ctx context.Context, req *ListCleanRoomNotebookTaskRunsRequest, opts ...call.Option) (*ListCleanRoomNotebookTaskRunsResponse, error) { + wireReq, err := listCleanRoomNotebookTaskRunsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/runs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "notebook_name", wireReq.NotebookName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCleanRoomNotebookTaskRunsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCleanRoomNotebookTaskRunsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCleanRoomNotebookTaskRunsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCleanRoomNotebookTaskRunsIter returns an iterator that iterates +// over the results of ListCleanRoomNotebookTaskRuns. +// +// For example: +// +// for item, err := range c.ListCleanRoomNotebookTaskRunsIter(ctx, &ListCleanRoomNotebookTaskRunsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCleanRoomNotebookTaskRuns call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCleanRoomNotebookTaskRuns directly. +func (c *internalClient) ListCleanRoomNotebookTaskRunsIter(ctx context.Context, req *ListCleanRoomNotebookTaskRunsRequest, opts ...call.Option) iter.Seq2[*CleanRoomNotebookTaskRun, error] { + return func(yield func(*CleanRoomNotebookTaskRun, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCleanRoomNotebookTaskRunsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCleanRoomNotebookTaskRuns(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Runs { + if !yield(&resp.Runs[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List all the historical task runs in a clean room. +func (c *internalClient) ListCleanRoomTaskRunsHandler(ctx context.Context, req *ListCleanRoomTaskRunsRequest, opts ...call.Option) (*ListCleanRoomTaskRunsResponse, error) { + wireReq, err := listCleanRoomTaskRunsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/task-runs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if wireReq.TaskType != "" { + if err := addQueryValue(queryParams, "task_type", wireReq.TaskType); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCleanRoomTaskRunsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCleanRoomTaskRunsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCleanRoomTaskRunsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCleanRoomTaskRunsHandlerIter returns an iterator that iterates +// over the results of ListCleanRoomTaskRunsHandler. +// +// For example: +// +// for item, err := range c.ListCleanRoomTaskRunsHandlerIter(ctx, &ListCleanRoomTaskRunsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCleanRoomTaskRunsHandler call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCleanRoomTaskRunsHandler directly. +func (c *internalClient) ListCleanRoomTaskRunsHandlerIter(ctx context.Context, req *ListCleanRoomTaskRunsRequest, opts ...call.Option) iter.Seq2[*CleanRoomTaskRun, error] { + return func(yield func(*CleanRoomTaskRun, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCleanRoomTaskRunsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCleanRoomTaskRunsHandler(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Runs { + if !yield(&resp.Runs[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get a list of all clean rooms of the metastore. Only clean rooms the caller +// has access to are returned. +func (c *internalClient) ListCleanRooms(ctx context.Context, req *ListCleanRoomsRequest, opts ...call.Option) (*ListCleanRoomsResponse, error) { + wireReq, err := listCleanRoomsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/clean-rooms" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCleanRoomsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCleanRoomsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCleanRoomsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCleanRoomsIter returns an iterator that iterates +// over the results of ListCleanRooms. +// +// For example: +// +// for item, err := range c.ListCleanRoomsIter(ctx, &ListCleanRoomsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCleanRooms call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCleanRooms directly. +func (c *internalClient) ListCleanRoomsIter(ctx context.Context, req *ListCleanRoomsRequest, opts ...call.Option) iter.Seq2[*CleanRoom, error] { + return func(yield func(*CleanRoom, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCleanRoomsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCleanRooms(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.CleanRooms { + if !yield(&resp.CleanRooms[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Update a clean room. The caller must be the owner of the clean room, have +// **MODIFY_CLEAN_ROOM** privilege, or be metastore admin. +// +// When the caller is a metastore admin, only the __owner__ field can be +// updated. +func (c *internalClient) UpdateCleanRoom(ctx context.Context, req *UpdateCleanRoomRequest, opts ...call.Option) (*CleanRoom, error) { + wireReq, err := updateCleanRoomRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CleanRoom + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cleanRoomWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cleanRoomFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a clean room asset. For example, updating the content of a notebook; +// changing the shared partitions of a table; etc. +func (c *internalClient) UpdateCleanRoomAsset(ctx context.Context, req *UpdateCleanRoomAssetRequest, opts ...call.Option) (*CleanRoomAsset, error) { + wireReq, err := updateCleanRoomAssetRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Asset) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + if req.Asset.AssetType == "" { + return nil, fmt.Errorf("path parameter %q is required", "asset_type") + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.CleanRoomName) + pb.literal("/assets/") + pb.singleSegment(req.Asset.AssetType) + pb.literal("/") + pb.singleSegment(*req.Asset.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CleanRoomAsset + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cleanRoomAssetWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cleanRoomAssetFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a auto-approval rule by rule ID +func (c *internalClient) UpdateCleanRoomAutoApprovalRule(ctx context.Context, req *UpdateCleanRoomAutoApprovalRuleRequest, opts ...call.Option) (*CleanRoomAutoApprovalRule, error) { + wireReq, err := updateCleanRoomAutoApprovalRuleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.AutoApprovalRule) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/clean-rooms/") + pb.singleSegment(*req.AutoApprovalRule.CleanRoomName) + pb.literal("/auto-approval-rules/") + pb.singleSegment(*req.AutoApprovalRule.RuleId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CleanRoomAutoApprovalRule + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cleanRoomAutoApprovalRuleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cleanRoomAutoApprovalRuleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/cleanrooms/v1/genhelper.go b/cleanrooms/v1/genhelper.go new file mode 100755 index 0000000..f1cd505 --- /dev/null +++ b/cleanrooms/v1/genhelper.go @@ -0,0 +1,243 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package cleanrooms + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/cleanrooms/v1/model.go b/cleanrooms/v1/model.go new file mode 100755 index 0000000..5c56ffb --- /dev/null +++ b/cleanrooms/v1/model.go @@ -0,0 +1,1214 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package cleanrooms + +// Copied from elastic-spark-common/api/messages/runs.proto. Using the original +// definition to remove coupling with jobs API definition +type CleanRoomTaskRunLifeCycleState string + +const ( + CleanRoomTaskRunLifeCycleState_Unspecified CleanRoomTaskRunLifeCycleState = "" + CleanRoomTaskRunLifeCycleState_Pending CleanRoomTaskRunLifeCycleState = "PENDING" + CleanRoomTaskRunLifeCycleState_Running CleanRoomTaskRunLifeCycleState = "RUNNING" + CleanRoomTaskRunLifeCycleState_Terminating CleanRoomTaskRunLifeCycleState = "TERMINATING" + CleanRoomTaskRunLifeCycleState_Terminated CleanRoomTaskRunLifeCycleState = "TERMINATED" + CleanRoomTaskRunLifeCycleState_Skipped CleanRoomTaskRunLifeCycleState = "SKIPPED" + CleanRoomTaskRunLifeCycleState_InternalError CleanRoomTaskRunLifeCycleState = "INTERNAL_ERROR" + CleanRoomTaskRunLifeCycleState_Blocked CleanRoomTaskRunLifeCycleState = "BLOCKED" + CleanRoomTaskRunLifeCycleState_WaitingForRetry CleanRoomTaskRunLifeCycleState = "WAITING_FOR_RETRY" + CleanRoomTaskRunLifeCycleState_Queued CleanRoomTaskRunLifeCycleState = "QUEUED" +) + +// Copied from elastic-spark-common/api/messages/runs.proto. Using the original +// definition to avoid cyclic dependency. +type CleanRoomTaskRunResultState string + +const ( + CleanRoomTaskRunResultState_Unspecified CleanRoomTaskRunResultState = "" + CleanRoomTaskRunResultState_Success CleanRoomTaskRunResultState = "SUCCESS" + CleanRoomTaskRunResultState_Failed CleanRoomTaskRunResultState = "FAILED" + CleanRoomTaskRunResultState_Timedout CleanRoomTaskRunResultState = "TIMEDOUT" + CleanRoomTaskRunResultState_Canceled CleanRoomTaskRunResultState = "CANCELED" + CleanRoomTaskRunResultState_MaximumConcurrentRunsReached CleanRoomTaskRunResultState = "MAXIMUM_CONCURRENT_RUNS_REACHED" + CleanRoomTaskRunResultState_UpstreamCanceled CleanRoomTaskRunResultState = "UPSTREAM_CANCELED" + CleanRoomTaskRunResultState_UpstreamFailed CleanRoomTaskRunResultState = "UPSTREAM_FAILED" + CleanRoomTaskRunResultState_Excluded CleanRoomTaskRunResultState = "EXCLUDED" + CleanRoomTaskRunResultState_Evicted CleanRoomTaskRunResultState = "EVICTED" + CleanRoomTaskRunResultState_SuccessWithFailures CleanRoomTaskRunResultState = "SUCCESS_WITH_FAILURES" + CleanRoomTaskRunResultState_UpstreamEvicted CleanRoomTaskRunResultState = "UPSTREAM_EVICTED" + // 12 is reserved for previously used SUCCESS_WITH_SKIPPED_CELLS + CleanRoomTaskRunResultState_Disabled CleanRoomTaskRunResultState = "DISABLED" +) + +type CleanRoomTaskType string + +const ( + CleanRoomTaskType_Unspecified CleanRoomTaskType = "" + CleanRoomTaskType_Notebook CleanRoomTaskType = "NOTEBOOK" + CleanRoomTaskType_Jar CleanRoomTaskType = "JAR" +) + +type ColumnTypeName string + +const ( + ColumnTypeName_Unspecified ColumnTypeName = "" + ColumnTypeName_Boolean ColumnTypeName = "BOOLEAN" + ColumnTypeName_Byte ColumnTypeName = "BYTE" + ColumnTypeName_Short ColumnTypeName = "SHORT" + ColumnTypeName_Int ColumnTypeName = "INT" + ColumnTypeName_Long ColumnTypeName = "LONG" + ColumnTypeName_Float ColumnTypeName = "FLOAT" + ColumnTypeName_Double ColumnTypeName = "DOUBLE" + ColumnTypeName_Date ColumnTypeName = "DATE" + ColumnTypeName_Timestamp ColumnTypeName = "TIMESTAMP" + ColumnTypeName_String ColumnTypeName = "STRING" + ColumnTypeName_Binary ColumnTypeName = "BINARY" + ColumnTypeName_Decimal ColumnTypeName = "DECIMAL" + ColumnTypeName_Interval ColumnTypeName = "INTERVAL" + ColumnTypeName_Array ColumnTypeName = "ARRAY" + ColumnTypeName_Struct ColumnTypeName = "STRUCT" + ColumnTypeName_Map ColumnTypeName = "MAP" + ColumnTypeName_Char ColumnTypeName = "CHAR" + ColumnTypeName_Null ColumnTypeName = "NULL" + ColumnTypeName_UserDefinedType ColumnTypeName = "USER_DEFINED_TYPE" + ColumnTypeName_TimestampNtz ColumnTypeName = "TIMESTAMP_NTZ" + ColumnTypeName_Variant ColumnTypeName = "VARIANT" + ColumnTypeName_Geometry ColumnTypeName = "GEOMETRY" + ColumnTypeName_Geography ColumnTypeName = "GEOGRAPHY" + ColumnTypeName_TableType ColumnTypeName = "TABLE_TYPE" +) + +// Compliance standard for SHIELD customers. See README.md for how instructions +// of how to add new standards. +type ComplianceStandard string + +const ( + ComplianceStandard_Unspecified ComplianceStandard = "" + // For customers who buy Enhanced Security Compliance (ESC) product but don't + // belong to any standards. + ComplianceStandard_None ComplianceStandard = "NONE" + // Industry standards below + ComplianceStandard_Hipaa ComplianceStandard = "HIPAA" + ComplianceStandard_PciDss ComplianceStandard = "PCI_DSS" + ComplianceStandard_FedrampModerate ComplianceStandard = "FEDRAMP_MODERATE" + ComplianceStandard_IrapProtected ComplianceStandard = "IRAP_PROTECTED" + // Only available in AWS GovCloud + ComplianceStandard_FedrampHigh ComplianceStandard = "FEDRAMP_HIGH" + ComplianceStandard_FedrampIl5 ComplianceStandard = "FEDRAMP_IL5" + // International Traffic in Arms Regulations (ITAR); Export Administration + // Regulations (EAR) + ComplianceStandard_ItarEar ComplianceStandard = "ITAR_EAR" + // UK Cyber Essential Plus + ComplianceStandard_CyberEssentialPlus ComplianceStandard = "CYBER_ESSENTIAL_PLUS" + // The Government of Canada (GC) Protected B + // https://www.tpsgc-pwgsc.gc.ca/esc-src/protection-safeguarding/niveaux-levels-eng.html + ComplianceStandard_CanadaProtectedB ComplianceStandard = "CANADA_PROTECTED_B" + // Japan Information system Security Management and Assessment Program + // https://www.ismap.go.jp/csm?id=kb_article_view&sysparm_article=KB0010301&sys_kb_id=9b6741cec305821032713201150131c2&spa=1 + ComplianceStandard_Ismap ComplianceStandard = "ISMAP" + // HITRUST https://hitrustalliance.net/ + ComplianceStandard_Hitrust ComplianceStandard = "HITRUST" + // Korea Financial Security Institute + ComplianceStandard_KFsi ComplianceStandard = "K_FSI" + // Cloud Computing Compliance Criteria Catalogue for Germany + ComplianceStandard_GermanyC5 ComplianceStandard = "GERMANY_C5" + // Trusted Information Security Assessment Exchange, a compliance standard for + // automotive industry for Germany + ComplianceStandard_GermanyTisax ComplianceStandard = "GERMANY_TISAX" + // KSA ECC/CCC/DCC standards. Saudi Arabia cybersecurity compliance frameworks + // mandated by the National Cybersecurity Authority (NCA). + ComplianceStandard_KsaEccCccDcc ComplianceStandard = "KSA_ECC_CCC_DCC" +) + +type CleanRoom_AccessRestricted string + +const ( + CleanRoom_AccessRestricted_Unspecified CleanRoom_AccessRestricted = "" + CleanRoom_AccessRestricted_CspMismatch CleanRoom_AccessRestricted = "CSP_MISMATCH" +) + +type CleanRoom_Status_Enum string + +const ( + CleanRoom_Status_Enum_Unspecified CleanRoom_Status_Enum = "" + CleanRoom_Status_Enum_Active CleanRoom_Status_Enum = "ACTIVE" + CleanRoom_Status_Enum_Provisioning CleanRoom_Status_Enum = "PROVISIONING" + CleanRoom_Status_Enum_Deleted CleanRoom_Status_Enum = "DELETED" + CleanRoom_Status_Enum_Failed CleanRoom_Status_Enum = "FAILED" +) + +type CleanRoomAsset_AssetType string + +const ( + CleanRoomAsset_AssetType_Unspecified CleanRoomAsset_AssetType = "" + CleanRoomAsset_AssetType_Table CleanRoomAsset_AssetType = "TABLE" + CleanRoomAsset_AssetType_NotebookFile CleanRoomAsset_AssetType = "NOTEBOOK_FILE" + CleanRoomAsset_AssetType_Volume CleanRoomAsset_AssetType = "VOLUME" + CleanRoomAsset_AssetType_View CleanRoomAsset_AssetType = "VIEW" + CleanRoomAsset_AssetType_ForeignTable CleanRoomAsset_AssetType = "FOREIGN_TABLE" + CleanRoomAsset_AssetType_JarAnalysis CleanRoomAsset_AssetType = "JAR_ANALYSIS" +) + +type CleanRoomAsset_Status_Enum string + +const ( + CleanRoomAsset_Status_Enum_Unspecified CleanRoomAsset_Status_Enum = "" + CleanRoomAsset_Status_Enum_Active CleanRoomAsset_Status_Enum = "ACTIVE" + CleanRoomAsset_Status_Enum_PermissionDenied CleanRoomAsset_Status_Enum = "PERMISSION_DENIED" + CleanRoomAsset_Status_Enum_Pending CleanRoomAsset_Status_Enum = "PENDING" +) + +type CleanRoomAutoApprovalRule_AuthorScope string + +const ( + CleanRoomAutoApprovalRule_AuthorScope_Unspecified CleanRoomAutoApprovalRule_AuthorScope = "" + CleanRoomAutoApprovalRule_AuthorScope_AnyAuthor CleanRoomAutoApprovalRule_AuthorScope = "ANY_AUTHOR" +) + +type CleanRoomJarAnalysisReview_JarAnalysisReviewState string + +const ( + CleanRoomJarAnalysisReview_JarAnalysisReviewState_Unspecified CleanRoomJarAnalysisReview_JarAnalysisReviewState = "" + CleanRoomJarAnalysisReview_JarAnalysisReviewState_Approved CleanRoomJarAnalysisReview_JarAnalysisReviewState = "APPROVED" + CleanRoomJarAnalysisReview_JarAnalysisReviewState_Rejected CleanRoomJarAnalysisReview_JarAnalysisReviewState = "REJECTED" + CleanRoomJarAnalysisReview_JarAnalysisReviewState_Pending CleanRoomJarAnalysisReview_JarAnalysisReviewState = "PENDING" +) + +type CleanRoomJarAnalysisReview_JarAnalysisReviewSubReason string + +const ( + CleanRoomJarAnalysisReview_JarAnalysisReviewSubReason_Unspecified CleanRoomJarAnalysisReview_JarAnalysisReviewSubReason = "" + CleanRoomJarAnalysisReview_JarAnalysisReviewSubReason_AutoApproved CleanRoomJarAnalysisReview_JarAnalysisReviewSubReason = "AUTO_APPROVED" +) + +type CleanRoomNotebookReview_NotebookReviewState string + +const ( + CleanRoomNotebookReview_NotebookReviewState_Unspecified CleanRoomNotebookReview_NotebookReviewState = "" + CleanRoomNotebookReview_NotebookReviewState_Approved CleanRoomNotebookReview_NotebookReviewState = "APPROVED" + CleanRoomNotebookReview_NotebookReviewState_Rejected CleanRoomNotebookReview_NotebookReviewState = "REJECTED" + CleanRoomNotebookReview_NotebookReviewState_Pending CleanRoomNotebookReview_NotebookReviewState = "PENDING" +) + +type CleanRoomNotebookReview_NotebookReviewSubReason string + +const ( + CleanRoomNotebookReview_NotebookReviewSubReason_Unspecified CleanRoomNotebookReview_NotebookReviewSubReason = "" + CleanRoomNotebookReview_NotebookReviewSubReason_Backfilled CleanRoomNotebookReview_NotebookReviewSubReason = "BACKFILLED" + CleanRoomNotebookReview_NotebookReviewSubReason_AutoApproved CleanRoomNotebookReview_NotebookReviewSubReason = "AUTO_APPROVED" +) + +type CleanRoomOutputCatalog_OutputCatalogStatus string + +const ( + CleanRoomOutputCatalog_OutputCatalogStatus_Unspecified CleanRoomOutputCatalog_OutputCatalogStatus = "" + // The clean room is not eligible for output catalog. + CleanRoomOutputCatalog_OutputCatalogStatus_NotEligible CleanRoomOutputCatalog_OutputCatalogStatus = "NOT_ELIGIBLE" + // The output catalog of the clean room is not yet created. + CleanRoomOutputCatalog_OutputCatalogStatus_NotCreated CleanRoomOutputCatalog_OutputCatalogStatus = "NOT_CREATED" + // The output catalog of the clean room is created. + CleanRoomOutputCatalog_OutputCatalogStatus_Created CleanRoomOutputCatalog_OutputCatalogStatus = "CREATED" +) + +// The filtering protocol used by the DP. For private and public preview, SEG +// will only support TCP filtering (i.e. DNS based filtering, filtering by +// destination IP address), so protocol will be set to TCP by default and hidden +// from the user. In the future, users may be able to select HTTP filtering +// (i.e. SNI based filtering, filtering by FQDN). +type EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationFilteringProtocol string + +const ( + EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationFilteringProtocol_Unspecified EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationFilteringProtocol = "" + EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationFilteringProtocol_Tcp EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationFilteringProtocol = "TCP" +) + +type EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationType string + +const ( + EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationType_Unspecified EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationType = "" + EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationType_Fqdn EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationType = "FQDN" +) + +type EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_LogOnlyModeType string + +const ( + EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_LogOnlyModeType_Unspecified EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_LogOnlyModeType = "" + EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_LogOnlyModeType_AllServices EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_LogOnlyModeType = "ALL_SERVICES" + EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_LogOnlyModeType_SelectedServices EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_LogOnlyModeType = "SELECTED_SERVICES" +) + +// The values should match the list of workloads used in networkconfig.proto +type EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_WorkloadType string + +const ( + EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_WorkloadType_Unspecified EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_WorkloadType = "" + EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_WorkloadType_Dbsql EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_WorkloadType = "DBSQL" + EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_WorkloadType_MlServing EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_WorkloadType = "ML_SERVING" +) + +// At which level can and managed compute access +// Internet. FULL_ACCESS: can access Internet. No blocking rules +// will apply. RESTRICTED_ACCESS: can only access explicitly +// allowed internet and storage destinations, as well as UC connections and +// external locations. PRIVATE_ACCESS_ONLY (not used): can only +// access destinations via private link. +type EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode string + +const ( + EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode_Unspecified EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode = "" + EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode_FullAccess EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode = "FULL_ACCESS" + EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode_PrivateAccessOnly EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode = "PRIVATE_ACCESS_ONLY" + EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode_RestrictedAccess EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode = "RESTRICTED_ACCESS" +) + +type EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType string + +const ( + EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType_Unspecified EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType = "" + EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType_AwsS3 EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType = "AWS_S3" + EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType_CloudflareR2 EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType = "CLOUDFLARE_R2" + EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType_AzureStorage EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType = "AZURE_STORAGE" + EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType_GoogleCloudStorage EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType = "GOOGLE_CLOUD_STORAGE" +) + +type PartitionSpecification_Partition_PartitionValue_PartitionValueOp string + +const ( + PartitionSpecification_Partition_PartitionValue_PartitionValueOp_Unspecified PartitionSpecification_Partition_PartitionValue_PartitionValueOp = "" + PartitionSpecification_Partition_PartitionValue_PartitionValueOp_Like PartitionSpecification_Partition_PartitionValue_PartitionValueOp = "LIKE" +) + +type CleanRoom struct { + // The name of the clean room. It should follow [UC securable naming + // requirements]. + // + // [UC securable naming requirements]: https://docs.databricks.com/en/data-governance/unity-catalog/index.html#securable-object-naming-requirements + Name *string + // Central clean room details. During creation, users need to specify + // cloud_vendor, region, and collaborators.global_metastore_id. This field will + // not be filled in the ListCleanRooms call. + RemoteDetailedInfo *CleanRoomRemoteDetail + // This is the username of the owner of the local clean room + // securable for permission management. + Owner *string + Comment *string + // When the clean room was created, in epoch milliseconds. + CreatedAt *int64 + // When the clean room was last updated, in epoch milliseconds. + UpdatedAt *int64 + // Clean room status. + Status CleanRoom_Status_Enum + // The alias of the collaborator tied to the local clean room. + LocalCollaboratorAlias *string + // Output catalog of the clean room. It is an output only field. Output catalog + // is manipulated using the separate CreateCleanRoomOutputCatalog API. + OutputCatalog *CleanRoomOutputCatalog + // Whether clean room access is restricted due to [CSP] + // + // [CSP]: https://docs.databricks.com/en/security/privacy/security-profile.html + AccessRestricted CleanRoom_AccessRestricted + // Whether allow task to write to shared output schema. When enabled, clean room + // task runs triggered by the current collaborator can write to the run-scoped + // shared output schema which is accessible by all collaborators. + EnableSharedOutput *bool +} + +// Clean room status.. +type CleanRoom_Status struct { +} + +// Metadata of the clean room asset. +type CleanRoomAsset struct { + // The name of the clean room this asset belongs to. This field is required for + // create operations and populated by the server for responses. + CleanRoomName *string + // A fully qualified name that uniquely identifies the asset within the clean + // room. This is also the name displayed in the clean room UI. + // + // For UC securable assets (tables, volumes, etc.), the format is + // *shared_catalog*.*shared_schema*.*asset_name* + // + // For notebooks, the name is the notebook file name. For jar analyses, the name + // is the jar analysis name. + Name *string + // The type of the asset. + AssetType CleanRoomAsset_AssetType + // When the asset is added to the clean room, in epoch milliseconds. + AddedAt *int64 + // Status of the asset + Status CleanRoomAsset_Status_Enum + // The alias of the collaborator who owns this asset + OwnerCollaboratorAlias *string + // asset-type specific local information of the asset + LocalDetails isCleanRoomAsset_LocalDetails + // the asset-type specific information. Will not be returned by list + Details isCleanRoomAsset_Details +} + +type isCleanRoomAsset_LocalDetails interface { + isCleanRoomAsset_LocalDetails() +} + +// CleanRoomAsset_LocalDetails_TableLocalDetails selects TableLocalDetails for CleanRoomAsset.LocalDetails. +// Local details for a table that are only available to its owner. Present if +// and only if **asset_type** is **TABLE** +type CleanRoomAsset_LocalDetails_TableLocalDetails struct { + TableLocalDetails CleanRoomAsset_TableLocalDetails +} + +func (*CleanRoomAsset_LocalDetails_TableLocalDetails) isCleanRoomAsset_LocalDetails() {} + +// CleanRoomAsset_LocalDetails_VolumeLocalDetails selects VolumeLocalDetails for CleanRoomAsset.LocalDetails. +// Local details for a volume that are only available to its owner. Present if +// and only if **asset_type** is **VOLUME** +type CleanRoomAsset_LocalDetails_VolumeLocalDetails struct { + VolumeLocalDetails CleanRoomAsset_VolumeLocalDetails +} + +func (*CleanRoomAsset_LocalDetails_VolumeLocalDetails) isCleanRoomAsset_LocalDetails() {} + +// CleanRoomAsset_LocalDetails_ViewLocalDetails selects ViewLocalDetails for CleanRoomAsset.LocalDetails. +// Local details for a view that are only available to its owner. Present if and +// only if **asset_type** is **VIEW** +type CleanRoomAsset_LocalDetails_ViewLocalDetails struct { + ViewLocalDetails CleanRoomAsset_ViewLocalDetails +} + +func (*CleanRoomAsset_LocalDetails_ViewLocalDetails) isCleanRoomAsset_LocalDetails() {} + +// CleanRoomAsset_LocalDetails_ForeignTableLocalDetails selects ForeignTableLocalDetails for CleanRoomAsset.LocalDetails. +// Local details for a foreign that are only available to its owner. Present if +// and only if **asset_type** is **FOREIGN_TABLE** +type CleanRoomAsset_LocalDetails_ForeignTableLocalDetails struct { + ForeignTableLocalDetails CleanRoomAsset_ForeignTableLocalDetails +} + +func (*CleanRoomAsset_LocalDetails_ForeignTableLocalDetails) isCleanRoomAsset_LocalDetails() {} + +type isCleanRoomAsset_Details interface { + isCleanRoomAsset_Details() +} + +// CleanRoomAsset_Details_Table selects Table for CleanRoomAsset.Details. +// Table details available to all collaborators of the clean room. Present if +// and only if **asset_type** is **TABLE** +type CleanRoomAsset_Details_Table struct { + Table CleanRoomAsset_Table +} + +func (*CleanRoomAsset_Details_Table) isCleanRoomAsset_Details() {} + +// CleanRoomAsset_Details_Notebook selects Notebook for CleanRoomAsset.Details. +// Notebook details available to all collaborators of the clean room. Present if +// and only if **asset_type** is **NOTEBOOK_FILE** +type CleanRoomAsset_Details_Notebook struct { + Notebook CleanRoomAsset_Notebook +} + +func (*CleanRoomAsset_Details_Notebook) isCleanRoomAsset_Details() {} + +// CleanRoomAsset_Details_View selects View for CleanRoomAsset.Details. +// View details available to all collaborators of the clean room. Present if and +// only if **asset_type** is **VIEW** +type CleanRoomAsset_Details_View struct { + View CleanRoomAsset_View +} + +func (*CleanRoomAsset_Details_View) isCleanRoomAsset_Details() {} + +// CleanRoomAsset_Details_ForeignTable selects ForeignTable for CleanRoomAsset.Details. +// Foreign table details available to all collaborators of the clean room. +// Present if and only if **asset_type** is **FOREIGN_TABLE** +type CleanRoomAsset_Details_ForeignTable struct { + ForeignTable CleanRoomAsset_ForeignTable +} + +func (*CleanRoomAsset_Details_ForeignTable) isCleanRoomAsset_Details() {} + +// CleanRoomAsset_Details_JarAnalysis selects JarAnalysis for CleanRoomAsset.Details. +// Jar analysis details available to all collaborators of the clean room. +// Present if and only if **asset_type** is **JAR_ANALYSIS** +type CleanRoomAsset_Details_JarAnalysis struct { + JarAnalysis CleanRoomAsset_JarAnalysis +} + +func (*CleanRoomAsset_Details_JarAnalysis) isCleanRoomAsset_Details() {} + +type CleanRoomAsset_ForeignTable struct { + // The metadata information of the columns in the foreign table + Columns []ColumnInfo +} + +type CleanRoomAsset_ForeignTableLocalDetails struct { + // The fully qualified name of the foreign table in its owner's local metastore, + // in the format of *catalog*.*schema*.*foreign_table_name* + LocalName *string +} + +type CleanRoomAsset_JarAnalysis struct { + // Server generated etag that represents the jar analysis version. + Etag *string + // Optional description of the jar analysis shown to all collaborators. + Description *string + // Collaborators that can run the jar. + RunnerCollaboratorAliases []string + // All existing approvals or rejections. + Reviews []CleanRoomJarAnalysisReview + // Top-level status derived from all reviews. + ReviewState CleanRoomJarAnalysisReview_JarAnalysisReviewState + // The full name of the class containing the main method to be executed. This + // class must be contained in a JAR provided as a library The code must use + // `SparkContext.getOrCreate` to obtain a Spark context; otherwise, runs of the + // job fail + MainClassName *string + // The full paths in central to the jar files that are added to the library + // during execution (e.g. /Volumes/creator/schema/volume/folder/my_jar_file.jar) + // Only returned for the owner collaborator. + CentralJarFilePaths []string + // The serverless environment version used to execute the JAR analysis (e.g. + // "4"). Defaults to "4-scala-preview" if not specified. + EnvironmentVersion *string +} + +type CleanRoomAsset_Notebook struct { + // Base 64 representation of the notebook contents. This is the same format as + // returned by [workspace/export] with the format of **HTML**. + // + // [workspace/export]: https://docs.databricks.com/api/workspace/workspace/export + NotebookContent *string + // Server generated etag that represents the notebook version. + Etag *string + // Aliases of collaborators that can run the notebook. + RunnerCollaboratorAliases []string + // All existing approvals or rejections + Reviews []CleanRoomNotebookReview + // Top-level status derived from all reviews + ReviewState CleanRoomNotebookReview_NotebookReviewState + // Optional description of the notebook shown to all collaborators. + Description *string + // The serverless environment version used to execute the notebook (e.g. "4"). + // Defaults to "2" if not specified. + EnvironmentVersion *string +} + +type CleanRoomAsset_Status struct { +} + +type CleanRoomAsset_Table struct { + // The metadata information of the columns in the table + Columns []ColumnInfo +} + +type CleanRoomAsset_TableLocalDetails struct { + // The fully qualified name of the table in its owner's local metastore, in the + // format of *catalog*.*schema*.*table_name* + LocalName *string + // Partition filtering specification for a shared table. + Partitions []PartitionSpecification_Partition +} + +type CleanRoomAsset_View struct { + // The metadata information of the columns in the view + Columns []ColumnInfo +} + +type CleanRoomAsset_ViewLocalDetails struct { + // The fully qualified name of the view in its owner's local metastore, in the + // format of *catalog*.*schema*.*view_name* + LocalName *string +} + +type CleanRoomAsset_VolumeLocalDetails struct { + // The fully qualified name of the volume in its owner's local metastore, in the + // format of *catalog*.*schema*.*volume_name* + LocalName *string +} + +type CleanRoomAutoApprovalRule struct { + // The name of the clean room this auto-approval rule belongs to. + CleanRoomName *string + // A generated UUID identifying the rule. + RuleId *string + // The owner of the rule to whom the rule applies. + RuleOwnerCollaboratorAlias *string + // The auto-approved notebook authors. For 2P, this can only be the other + // collaborator. + Authors isCleanRoomAutoApprovalRule_Authors + // The auto-approved notebook runners. Initially, this can only be one specific + // runner. + Runners isCleanRoomAutoApprovalRule_Runners + // Timestamp of when the rule was created, in epoch milliseconds. + CreatedAt *int64 +} + +type isCleanRoomAutoApprovalRule_Authors interface { + isCleanRoomAutoApprovalRule_Authors() +} + +// CleanRoomAutoApprovalRule_Authors_AuthorCollaboratorAlias selects AuthorCollaboratorAlias for CleanRoomAutoApprovalRule.Authors. +// Collaborator alias of the author covered by the rule. Only one of +// `author_collaborator_alias` and `author_scope` can be set. +type CleanRoomAutoApprovalRule_Authors_AuthorCollaboratorAlias struct { + AuthorCollaboratorAlias string +} + +func (*CleanRoomAutoApprovalRule_Authors_AuthorCollaboratorAlias) isCleanRoomAutoApprovalRule_Authors() { +} + +// CleanRoomAutoApprovalRule_Authors_AuthorScope selects AuthorScope for CleanRoomAutoApprovalRule.Authors. +// Scope of authors covered by the rule. Only one of `author_collaborator_alias` +// and `author_scope` can be set. +type CleanRoomAutoApprovalRule_Authors_AuthorScope struct { + AuthorScope CleanRoomAutoApprovalRule_AuthorScope +} + +func (*CleanRoomAutoApprovalRule_Authors_AuthorScope) isCleanRoomAutoApprovalRule_Authors() {} + +type isCleanRoomAutoApprovalRule_Runners interface { + isCleanRoomAutoApprovalRule_Runners() +} + +// CleanRoomAutoApprovalRule_Runners_RunnerCollaboratorAlias selects RunnerCollaboratorAlias for CleanRoomAutoApprovalRule.Runners. +// Collaborator alias of the runner covered by the rule. +type CleanRoomAutoApprovalRule_Runners_RunnerCollaboratorAlias struct { + RunnerCollaboratorAlias string +} + +func (*CleanRoomAutoApprovalRule_Runners_RunnerCollaboratorAlias) isCleanRoomAutoApprovalRule_Runners() { +} + +// Publicly visible clean room collaborator.. +type CleanRoomCollaborator struct { + // The global Unity Catalog metastore ID of the collaborator. The identifier is + // of format cloud:region:metastore-uuid. + GlobalMetastoreId *string + // [Organization + // name](:method:metastores/list#metastores-delta_sharing_organization_name) + // configured in the metastore + OrganizationName *string + // Workspace ID of the user who is receiving the clean room "invitation". Must + // be specified if invite_recipient_email is specified. It should be empty when + // the collaborator is the creator of the clean room. + InviteRecipientWorkspaceId *int64 + // Email of the user who is receiving the clean room "invitation". It should be + // empty for the creator of the clean room, and non-empty for the invitees of + // the clean room. It is only returned in the output when clean room creator + // calls GET + InviteRecipientEmail *string + // Collaborator alias specified by the clean room creator. It is unique across + // all collaborators of this clean room, and used to derive multiple values + // internally such as catalog alias and clean room name for single metastore + // clean rooms. It should follow [UC securable naming requirements]. + // + // [UC securable naming requirements]: https://docs.databricks.com/en/data-governance/unity-catalog/index.html#securable-object-naming-requirements + CollaboratorAlias *string + // Generated display name for the collaborator. In the case of a single + // metastore clean room, it is the clean room name. For x-metastore clean rooms, + // it is the organization name of the metastore. It is not restricted to these + // values and could change in the future + DisplayName *string +} + +// This only applies to a JAR Analysis as a first-class asset in the Clean Room, +// and not to Volumes. +type CleanRoomJarAnalysisReview struct { + // collaborator alias of the reviewer + ReviewerCollaboratorAlias *string + // timestamp of when the review was submitted + CreatedAtMillis *int64 + // review outcome + ReviewState CleanRoomJarAnalysisReview_JarAnalysisReviewState + // review comment + Comment *string + // specified when the review was not explicitly made by a user + ReviewSubReason CleanRoomJarAnalysisReview_JarAnalysisReviewSubReason +} + +type CleanRoomNotebookReview struct { + // Collaborator alias of the reviewer + ReviewerCollaboratorAlias *string + // When the review was submitted, in epoch milliseconds + CreatedAtMillis *int64 + // Review outcome + ReviewState CleanRoomNotebookReview_NotebookReviewState + // Review comment + Comment *string + // Specified when the review was not explicitly made by a user + ReviewSubReason CleanRoomNotebookReview_NotebookReviewSubReason +} + +// Stores information about a single task run.. +type CleanRoomNotebookTaskRun struct { + // Asset name of the notebook executed in this task run. + NotebookName *string + // When the task run started, in epoch milliseconds. + StartTime *int64 + // Duration of the task run, in milliseconds. + RunDuration *int64 + // State of the task run. + NotebookJobRunState *CleanRoomTaskRunState + // Job run info of the task in the runner's local workspace. This field is only + // included in the LIST API. if the task was run within the same workspace the + // API is being called. If the task run was in a different workspace under the + // same metastore, only the workspace_id is included. + CollaboratorJobRunInfo *CollaboratorJobRunInfo + // Name of the output schema associated with the clean rooms notebook task run. + OutputSchemaName *string + // Expiration time of the output schema of the task run (if any), in epoch + // milliseconds. + OutputSchemaExpirationTime *int64 + // Etag of the notebook executed in this task run, used to identify the notebook + // version. + NotebookEtag *string + // The timestamp of when the notebook was last updated. + NotebookUpdatedAt *int64 + // Name of the shared output schema associated with the clean rooms notebook + // task run. This schema is accessible by all collaborators when + // enable_shared_output is true. + SharedOutputSchemaName *string + // Expiration time of the shared output schema of the task run (if any), in + // epoch milliseconds. + SharedOutputSchemaExpirationTime *int64 +} + +type CleanRoomOutputCatalog struct { + Status CleanRoomOutputCatalog_OutputCatalogStatus + // The name of the output catalog in UC. It should follow [UC securable naming + // requirements]. The field will always exist if status is CREATED. + // + // [UC securable naming requirements]: https://docs.databricks.com/en/data-governance/unity-catalog/index.html#securable-object-naming-requirements + CatalogName *string +} + +// Publicly visible central clean room details.. +type CleanRoomRemoteDetail struct { + // Central clean room ID. + CentralCleanRoomId *string + // Cloud vendor (aws,azure,gcp) of the central clean room. + CloudVendor *string + // Region of the central clean room. + Region *string + // Collaborators in the central clean room. There should one and only one + // collaborator in the list that satisfies the owner condition: + // + // 1. It has the creator's global_metastore_id (determined by caller of + // CreateCleanRoom). + // + // 2. Its invite_recipient_email is empty. + Collaborators []CleanRoomCollaborator + // Collaborator who creates the clean room. + Creator *CleanRoomCollaborator + // Egress network policy to apply to the central clean room workspace. + EgressNetworkPolicy *EgressNetworkPolicy + ComplianceSecurityProfile *ComplianceSecurityProfile + // Whether to enable shared output for the central clean room. When enabled, + // clean room task runs can write to the run-scoped shared output schema which + // is accessible by all collaborators. + EnableSharedOutput *bool + // Alias of the provider collaborator. If set, packaged clean rooms mode is + // enabled. The consumer's experience is restricted: they can view notebook + // names and READMEs, add their own data assets, and trigger runs, but cannot + // view notebook code, provider data assets, or notebook run output. + PackageProviderCollaboratorAlias *string +} + +// Stores information about a single task run.. +type CleanRoomTaskRun struct { + // Name of the executable. + Name *string + // The type of Clean Room task. + TaskType CleanRoomTaskType + // When the task run started, in epoch milliseconds. + StartTime *int64 + // Duration of the task run, in milliseconds. + RunDuration *int64 + // State of the task run. + TaskRunState *CleanRoomTaskRunState + // Job run info of the task in the runner's local workspace. This field is only + // included in the LIST API if the task was run within the same workspace the + // API is being called. If the task run was in a different workspace under the + // same metastore, only the workspace_id is included. + CollaboratorJobRunInfo *CollaboratorJobRunInfo + // Information about run output + OutputInfo *CleanRoomTaskRun_OutputInfo + // Information about the analysis run (etag, updated at) + AnalysisDetails *CleanRoomTaskRun_CleanRoomTaskAnalysisDetails + // Information about shared output accessible by all collaborators. This field + // is only populated when enable_shared_output is true. + SharedOutputInfo *CleanRoomTaskRun_OutputInfo +} + +type CleanRoomTaskRun_CleanRoomTaskAnalysisDetails struct { + // Etag of the asset executed in this task run, used to identify the asset + // version. + Etag *string + // The timestamp of when the asset was last updated. + UpdatedAt *int64 +} + +type CleanRoomTaskRun_OutputInfo struct { + // Name of the output schema associated with the clean room task run. + OutputSchemaName *string + // Expiration time of the output schema of the task run (if any), in epoch + // milliseconds. + OutputSchemaExpirationTime *int64 +} + +// Stores the run state of the clean rooms notebook task.. +type CleanRoomTaskRunState struct { + // A value indicating the run's current lifecycle state. This field is always + // available in the response. Note: Additional states might be introduced in + // future releases. + LifeCycleState CleanRoomTaskRunLifeCycleState + // A value indicating the run's result. This field is only available for + // terminal lifecycle states. Note: Additional states might be introduced in + // future releases. + ResultState CleanRoomTaskRunResultState +} + +type CollaboratorJobRunInfo struct { + // Job ID of the task run in the collaborator's workspace. + CollaboratorJobId *int64 + // Job run ID of the task run in the collaborator's workspace. + CollaboratorJobRunId *int64 + // Task run ID of the task run in the collaborator's workspace. + CollaboratorTaskRunId *int64 + // ID of the collaborator's workspace that triggered the task run. + CollaboratorWorkspaceId *int64 + // Alias of the collaborator that triggered the task run. + CollaboratorAlias *string +} + +type ColumnInfo struct { + // Name of Column. + Name *string + // Full data type specification as SQL/catalogString text. + TypeText *string + TypeName ColumnTypeName + // Ordinal position of column (starting at position 0). + Position *int + // Digits of precision; required for DecimalTypes. + TypePrecision *int + // Digits to right of decimal; Required for DecimalTypes. + TypeScale *int + // Format of IntervalType. + TypeIntervalType *string + // Full data type specification, JSON-serialized. + TypeJson *string + // User-provided free-form text description. + Comment *string + // Whether field may be Null (default: true). + Nullable *bool + // Partition index for column. + PartitionIndex *int + Mask *ColumnMask +} + +type ColumnMask struct { + // The full name of the column mask SQL UDF. + FunctionName *string + // The list of additional table columns to be passed as input to the column mask + // function. The first arg of the mask function should be of the type of the + // column being masked and the types of the rest of the args should match the + // types of columns in 'using_column_names'. + UsingColumnNames []string + // The list of additional table columns or literals to be passed as additional + // arguments to a column mask function. This is the replacement of the + // deprecated using_column_names field and carries information about the types + // (alias or constant) of the arguments to the mask function. + UsingArguments []PolicyFunctionArgument +} + +// The compliance security profile used to process regulated data following +// compliance standards.. +type ComplianceSecurityProfile struct { + // Whether the compliance security profile is enabled. + IsEnabled *bool + // The list of compliance standards that the compliance security profile is + // configured to enforce. + ComplianceStandards []ComplianceStandard +} + +type CreateCleanRoomAssetRequest struct { + Asset *CleanRoomAsset +} + +type CreateCleanRoomAssetReviewRequest struct { + // Name of the clean room + CleanRoomName *string + // Name of the asset + Name *string + // Asset type. Can either be NOTEBOOK_FILE or JAR_ANALYSIS. + AssetType CleanRoomAsset_AssetType + Review isCreateCleanRoomAssetReviewRequest_Review +} + +type isCreateCleanRoomAssetReviewRequest_Review interface { + isCreateCleanRoomAssetReviewRequest_Review() +} + +// CreateCleanRoomAssetReviewRequest_Review_NotebookReview selects NotebookReview for CreateCleanRoomAssetReviewRequest.Review. +type CreateCleanRoomAssetReviewRequest_Review_NotebookReview struct { + NotebookReview NotebookVersionReview +} + +func (*CreateCleanRoomAssetReviewRequest_Review_NotebookReview) isCreateCleanRoomAssetReviewRequest_Review() { +} + +// CreateCleanRoomAssetReviewRequest_Review_JarAnalysisReview selects JarAnalysisReview for CreateCleanRoomAssetReviewRequest.Review. +type CreateCleanRoomAssetReviewRequest_Review_JarAnalysisReview struct { + JarAnalysisReview JarAnalysisVersionReview +} + +func (*CreateCleanRoomAssetReviewRequest_Review_JarAnalysisReview) isCreateCleanRoomAssetReviewRequest_Review() { +} + +type CreateCleanRoomAssetReviewResponse struct { + // All existing notebook approvals or rejections + NotebookReviews []CleanRoomNotebookReview + // All existing jar analysis approvals or rejections + JarAnalysisReviews []CleanRoomJarAnalysisReview + ReviewState isCreateCleanRoomAssetReviewResponse_ReviewState +} + +type isCreateCleanRoomAssetReviewResponse_ReviewState interface { + isCreateCleanRoomAssetReviewResponse_ReviewState() +} + +// CreateCleanRoomAssetReviewResponse_ReviewState_NotebookReviewState selects NotebookReviewState for CreateCleanRoomAssetReviewResponse.ReviewState. +// Top-level status derived from all reviews +type CreateCleanRoomAssetReviewResponse_ReviewState_NotebookReviewState struct { + NotebookReviewState CleanRoomNotebookReview_NotebookReviewState +} + +func (*CreateCleanRoomAssetReviewResponse_ReviewState_NotebookReviewState) isCreateCleanRoomAssetReviewResponse_ReviewState() { +} + +// CreateCleanRoomAssetReviewResponse_ReviewState_JarAnalysisReviewState selects JarAnalysisReviewState for CreateCleanRoomAssetReviewResponse.ReviewState. +// top-level status derived from all reviews +type CreateCleanRoomAssetReviewResponse_ReviewState_JarAnalysisReviewState struct { + JarAnalysisReviewState CleanRoomJarAnalysisReview_JarAnalysisReviewState +} + +func (*CreateCleanRoomAssetReviewResponse_ReviewState_JarAnalysisReviewState) isCreateCleanRoomAssetReviewResponse_ReviewState() { +} + +type CreateCleanRoomAutoApprovalRuleRequest struct { + AutoApprovalRule *CleanRoomAutoApprovalRule +} + +type CreateCleanRoomOutputCatalogRequest struct { + // Name of the clean room. + CleanRoomName *string + OutputCatalog *CleanRoomOutputCatalog +} + +type CreateCleanRoomOutputCatalogResponse struct { + OutputCatalog *CleanRoomOutputCatalog +} + +type CreateCleanRoomRequest struct { + CleanRoom *CleanRoom +} + +type DeleteCleanRoomAssetRequest struct { + // Name of the clean room. + CleanRoomName *string + // The type of the asset. + AssetType CleanRoomAsset_AssetType + // The fully qualified name of the asset, it is same as the name field in + // CleanRoomAsset. + Name *string +} + +// Response for delete clean room request. Using an empty message since the +// generic Empty proto does not externd UnshadedMessageMarker.. +type DeleteCleanRoomAssetResponse struct { +} + +type DeleteCleanRoomAutoApprovalRuleRequest struct { + CleanRoomName *string + RuleId *string +} + +type DeleteCleanRoomRequest struct { + // Name of the clean room. + Name *string +} + +// The network policies applying for egress traffic. This message is used by the +// UI/REST API. We translate this message to the format expected by the +// dataplane in Lakehouse Network Manager (for the format expected by the +// dataplane, see networkconfig.textproto).. +type EgressNetworkPolicy struct { + // The access policy enforced for egress traffic to the internet. + InternetAccess *EgressNetworkPolicy_InternetAccessPolicy +} + +type EgressNetworkPolicy_InternetAccessPolicy struct { + RestrictionMode EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode + AllowedInternetDestinations []EgressNetworkPolicy_InternetAccessPolicy_InternetDestination + AllowedStorageDestinations []EgressNetworkPolicy_InternetAccessPolicy_StorageDestination + // Optional. If not specified, assume the policy is enforced for all workloads. + LogOnlyMode *EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode +} + +// Users can specify accessible internet destinations when outbound access is +// restricted. We only support domain name (FQDN) destinations for the time +// being, though going forwards we want to support host names and IP addresses.. +type EgressNetworkPolicy_InternetAccessPolicy_InternetDestination struct { + Destination *string + Type EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationType + Protocol EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationFilteringProtocol +} + +type EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode struct { + LogOnlyModeType EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_LogOnlyModeType + Workloads []EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_WorkloadType +} + +// Users can specify accessible storage destinations.. +type EgressNetworkPolicy_InternetAccessPolicy_StorageDestination struct { + BucketName *string + Region *string + Type EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType + AzureStorageAccount *string + AllowedPaths []string + AzureStorageService *string + AzureDnsZone *string + AzureContainer *string +} + +type GetCleanRoomAssetRequest struct { + // Name of the clean room. + CleanRoomName *string + // The type of the asset. + AssetType CleanRoomAsset_AssetType + // The fully qualified name of the asset, it is same as the name field in + // CleanRoomAsset. + Name *string +} + +type GetCleanRoomAssetRevisionRequest struct { + // Name of the clean room. + CleanRoomName *string + // Name of the asset. + Name *string + // Asset type. Only NOTEBOOK_FILE is supported. + AssetType CleanRoomAsset_AssetType + // Revision etag to fetch. If not provided, the latest revision will be + // returned. + Etag *string +} + +type GetCleanRoomAutoApprovalRuleRequest struct { + CleanRoomName *string + RuleId *string +} + +type GetCleanRoomRequest struct { + Name *string +} + +type JarAnalysisVersionReview struct { + // Etag identifying the jar analysis version, with its value being a hash of an + // internally-generated UUID + Etag *string + // Review outcome + ReviewState CleanRoomJarAnalysisReview_JarAnalysisReviewState + // Review comment + Comment *string +} + +type ListCleanRoomAssetRevisionsRequest struct { + // Name of the clean room. + CleanRoomName *string + // Name of the asset. + Name *string + // Asset type. Only NOTEBOOK_FILE is supported. + AssetType CleanRoomAsset_AssetType + // Maximum number of asset revisions to return. Defaults to 10. + PageSize *int + // Opaque pagination token to go to next page based on the previous query. + PageToken *string +} + +type ListCleanRoomAssetRevisionsResponse struct { + Revisions []CleanRoomAsset + NextPageToken *string +} + +type ListCleanRoomAssetsRequest struct { + // Name of the clean room. + CleanRoomName *string + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListCleanRoomAssetsResponse struct { + // Assets in the clean room. + Assets []CleanRoomAsset + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. page_token should be set to this value for the next request (for + // the next page of results). + NextPageToken *string +} + +type ListCleanRoomAutoApprovalRulesRequest struct { + CleanRoomName *string + // Maximum number of auto-approval rules to return. Defaults to 100. + PageSize *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListCleanRoomAutoApprovalRulesResponse struct { + Rules []CleanRoomAutoApprovalRule + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. page_token should be set to this value for the next request (for + // the next page of results). + NextPageToken *string +} + +type ListCleanRoomNotebookTaskRunsRequest struct { + // Name of the clean room. + CleanRoomName *string + // Notebook name + NotebookName *string + // The maximum number of task runs to return. Currently ignored - all runs will + // be returned. + PageSize *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListCleanRoomNotebookTaskRunsResponse struct { + // Name of the clean room. + Runs []CleanRoomNotebookTaskRun + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. page_token should be set to this value for the next request (for + // the next page of results). + NextPageToken *string +} + +type ListCleanRoomTaskRunsRequest struct { + // Name of the clean room. + CleanRoomName *string + // Executable name. + Name *string + // Filter by the type of Clean Room task. + TaskType CleanRoomTaskType + // The maximum number of task runs to return. Maximum value of 100. + PageSize *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListCleanRoomTaskRunsResponse struct { + // Task runs in the clean room. + Runs []CleanRoomTaskRun + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. page_token should be set to this value for the next request (for + // the next page of results). + NextPageToken *string +} + +type ListCleanRoomsRequest struct { + // Maximum number of clean rooms to return (i.e., the page length). Defaults to + // 100. + PageSize *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListCleanRoomsResponse struct { + CleanRooms []CleanRoom + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. page_token should be set to this value for the next request (for + // the next page of results). + NextPageToken *string +} + +type NotebookVersionReview struct { + // Etag identifying the notebook version + Etag *string + // Review outcome + ReviewState CleanRoomNotebookReview_NotebookReviewState + // Review comment + Comment *string +} + +// PartitionSpecification defines the format of partition filtering +// specification for shared tables. It consists of a list of Partitions which in +// turn include a list of PartitionValues. - Partitions inside a single +// PartitionSpecification have OR logical relationship. - PartitionValues inside +// a single Partition have AND logical relationship. - PartitionValue.name must +// have distinct values inside a single Partition.. +type PartitionSpecification struct { +} + +type PartitionSpecification_Partition struct { + // An array of partition values. + Values []PartitionSpecification_Partition_PartitionValue +} + +type PartitionSpecification_Partition_PartitionValue struct { + // The name of the partition column. + Name *string + // The value of the partition column. When this value is not set, it means + // `null` value. When this field is set, field `recipient_property_key` can not + // be set. + Value *string + // The key of a Delta Sharing recipient's property. For example + // "databricks-account-id". When this field is set, field `value` can not be + // set. + RecipientPropertyKey *string + // The operator to apply for the value. + Op PartitionSpecification_Partition_PartitionValue_PartitionValueOp +} + +// A positional argument passed to a row filter or column mask function. +// Distinguishes between column references and literals.. +type PolicyFunctionArgument struct { + Arg isPolicyFunctionArgument_Arg +} + +type isPolicyFunctionArgument_Arg interface { + isPolicyFunctionArgument_Arg() +} + +// PolicyFunctionArgument_Arg_Column selects Column for PolicyFunctionArgument.Arg. +// A column reference. +type PolicyFunctionArgument_Arg_Column struct { + Column string +} + +func (*PolicyFunctionArgument_Arg_Column) isPolicyFunctionArgument_Arg() {} + +// PolicyFunctionArgument_Arg_Constant selects Constant for PolicyFunctionArgument.Arg. +// A constant literal. +type PolicyFunctionArgument_Arg_Constant struct { + Constant string +} + +func (*PolicyFunctionArgument_Arg_Constant) isPolicyFunctionArgument_Arg() {} + +type UpdateCleanRoomAssetRequest struct { + // Name of the clean room. + CleanRoomName *string + // The asset to update. The asset's `name` and `asset_type` fields are used to + // identify the asset to update. + Asset *CleanRoomAsset +} + +type UpdateCleanRoomAutoApprovalRuleRequest struct { + // The auto-approval rule to update. The rule_id field is used to identify the + // rule to update. + AutoApprovalRule *CleanRoomAutoApprovalRule +} + +type UpdateCleanRoomRequest struct { + // Name of the clean room. + Name *string + CleanRoom *CleanRoom +} diff --git a/cleanrooms/v1/wire.go b/cleanrooms/v1/wire.go new file mode 100755 index 0000000..cd190e3 --- /dev/null +++ b/cleanrooms/v1/wire.go @@ -0,0 +1,1985 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package cleanrooms + +import ( + "fmt" +) + +type cleanRoomWire struct { + Name *string `json:"name,omitempty"` + RemoteDetailedInfo *cleanRoomRemoteDetailWire `json:"remote_detailed_info,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + Status CleanRoom_Status_Enum `json:"status,omitempty"` + LocalCollaboratorAlias *string `json:"local_collaborator_alias,omitempty"` + OutputCatalog *cleanRoomOutputCatalogWire `json:"output_catalog,omitempty"` + AccessRestricted CleanRoom_AccessRestricted `json:"access_restricted,omitempty"` + EnableSharedOutput *bool `json:"enable_shared_output,omitempty"` +} + +func cleanRoomToWire(v *CleanRoom) (*cleanRoomWire, error) { + if v == nil { + return nil, nil + } + remoteDetailedInfoWireValue, err := cleanRoomRemoteDetailToWire(v.RemoteDetailedInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoom.RemoteDetailedInfo", err) + } + outputCatalogWireValue, err := cleanRoomOutputCatalogToWire(v.OutputCatalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoom.OutputCatalog", err) + } + return &cleanRoomWire{ + Name: v.Name, + RemoteDetailedInfo: remoteDetailedInfoWireValue, + Owner: v.Owner, + Comment: v.Comment, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + Status: v.Status, + LocalCollaboratorAlias: v.LocalCollaboratorAlias, + OutputCatalog: outputCatalogWireValue, + AccessRestricted: v.AccessRestricted, + EnableSharedOutput: v.EnableSharedOutput, + }, nil +} + +func cleanRoomFromWire(w *cleanRoomWire) (*CleanRoom, error) { + if w == nil { + return nil, nil + } + remoteDetailedInfoPublicValue, err := cleanRoomRemoteDetailFromWire(w.RemoteDetailedInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoom.RemoteDetailedInfo", err) + } + outputCatalogPublicValue, err := cleanRoomOutputCatalogFromWire(w.OutputCatalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoom.OutputCatalog", err) + } + return &CleanRoom{ + Name: w.Name, + RemoteDetailedInfo: remoteDetailedInfoPublicValue, + Owner: w.Owner, + Comment: w.Comment, + CreatedAt: w.CreatedAt, + UpdatedAt: w.UpdatedAt, + Status: w.Status, + LocalCollaboratorAlias: w.LocalCollaboratorAlias, + OutputCatalog: outputCatalogPublicValue, + AccessRestricted: w.AccessRestricted, + EnableSharedOutput: w.EnableSharedOutput, + }, nil +} + +type cleanRoomAssetWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + Name *string `json:"name,omitempty"` + AssetType CleanRoomAsset_AssetType `json:"asset_type,omitempty"` + AddedAt *int64 `json:"added_at,omitempty"` + Status CleanRoomAsset_Status_Enum `json:"status,omitempty"` + OwnerCollaboratorAlias *string `json:"owner_collaborator_alias,omitempty"` + TableLocalDetails *cleanRoomAsset_TableLocalDetailsWire `json:"table_local_details,omitempty"` + VolumeLocalDetails *cleanRoomAsset_VolumeLocalDetailsWire `json:"volume_local_details,omitempty"` + ViewLocalDetails *cleanRoomAsset_ViewLocalDetailsWire `json:"view_local_details,omitempty"` + ForeignTableLocalDetails *cleanRoomAsset_ForeignTableLocalDetailsWire `json:"foreign_table_local_details,omitempty"` + Table *cleanRoomAsset_TableWire `json:"table,omitempty"` + Notebook *cleanRoomAsset_NotebookWire `json:"notebook,omitempty"` + View *cleanRoomAsset_ViewWire `json:"view,omitempty"` + ForeignTable *cleanRoomAsset_ForeignTableWire `json:"foreign_table,omitempty"` + JarAnalysis *cleanRoomAsset_JarAnalysisWire `json:"jar_analysis,omitempty"` +} + +func cleanRoomAssetToWire(v *CleanRoomAsset) (*cleanRoomAssetWire, error) { + if v == nil { + return nil, nil + } + var localDetailsTableLocalDetailsWire *cleanRoomAsset_TableLocalDetailsWire + var localDetailsVolumeLocalDetailsWire *cleanRoomAsset_VolumeLocalDetailsWire + var localDetailsViewLocalDetailsWire *cleanRoomAsset_ViewLocalDetailsWire + var localDetailsForeignTableLocalDetailsWire *cleanRoomAsset_ForeignTableLocalDetailsWire + switch value := v.LocalDetails.(type) { + case nil: + case *CleanRoomAsset_LocalDetails_TableLocalDetails: + if value != nil { + localDetailsTableLocalDetailsConverted, err := cleanRoomAsset_TableLocalDetailsToWire(&value.TableLocalDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.LocalDetails.TableLocalDetails", err) + } + localDetailsTableLocalDetailsWire = localDetailsTableLocalDetailsConverted + } + case *CleanRoomAsset_LocalDetails_VolumeLocalDetails: + if value != nil { + localDetailsVolumeLocalDetailsConverted, err := cleanRoomAsset_VolumeLocalDetailsToWire(&value.VolumeLocalDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.LocalDetails.VolumeLocalDetails", err) + } + localDetailsVolumeLocalDetailsWire = localDetailsVolumeLocalDetailsConverted + } + case *CleanRoomAsset_LocalDetails_ViewLocalDetails: + if value != nil { + localDetailsViewLocalDetailsConverted, err := cleanRoomAsset_ViewLocalDetailsToWire(&value.ViewLocalDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.LocalDetails.ViewLocalDetails", err) + } + localDetailsViewLocalDetailsWire = localDetailsViewLocalDetailsConverted + } + case *CleanRoomAsset_LocalDetails_ForeignTableLocalDetails: + if value != nil { + localDetailsForeignTableLocalDetailsConverted, err := cleanRoomAsset_ForeignTableLocalDetailsToWire(&value.ForeignTableLocalDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.LocalDetails.ForeignTableLocalDetails", err) + } + localDetailsForeignTableLocalDetailsWire = localDetailsForeignTableLocalDetailsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CleanRoomAsset.LocalDetails", value) + } + var detailsTableWire *cleanRoomAsset_TableWire + var detailsNotebookWire *cleanRoomAsset_NotebookWire + var detailsViewWire *cleanRoomAsset_ViewWire + var detailsForeignTableWire *cleanRoomAsset_ForeignTableWire + var detailsJarAnalysisWire *cleanRoomAsset_JarAnalysisWire + switch value := v.Details.(type) { + case nil: + case *CleanRoomAsset_Details_Table: + if value != nil { + detailsTableConverted, err := cleanRoomAsset_TableToWire(&value.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.Details.Table", err) + } + detailsTableWire = detailsTableConverted + } + case *CleanRoomAsset_Details_Notebook: + if value != nil { + detailsNotebookConverted, err := cleanRoomAsset_NotebookToWire(&value.Notebook) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.Details.Notebook", err) + } + detailsNotebookWire = detailsNotebookConverted + } + case *CleanRoomAsset_Details_View: + if value != nil { + detailsViewConverted, err := cleanRoomAsset_ViewToWire(&value.View) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.Details.View", err) + } + detailsViewWire = detailsViewConverted + } + case *CleanRoomAsset_Details_ForeignTable: + if value != nil { + detailsForeignTableConverted, err := cleanRoomAsset_ForeignTableToWire(&value.ForeignTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.Details.ForeignTable", err) + } + detailsForeignTableWire = detailsForeignTableConverted + } + case *CleanRoomAsset_Details_JarAnalysis: + if value != nil { + detailsJarAnalysisConverted, err := cleanRoomAsset_JarAnalysisToWire(&value.JarAnalysis) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.Details.JarAnalysis", err) + } + detailsJarAnalysisWire = detailsJarAnalysisConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CleanRoomAsset.Details", value) + } + return &cleanRoomAssetWire{ + CleanRoomName: v.CleanRoomName, + Name: v.Name, + AssetType: v.AssetType, + AddedAt: v.AddedAt, + Status: v.Status, + OwnerCollaboratorAlias: v.OwnerCollaboratorAlias, + TableLocalDetails: localDetailsTableLocalDetailsWire, + VolumeLocalDetails: localDetailsVolumeLocalDetailsWire, + ViewLocalDetails: localDetailsViewLocalDetailsWire, + ForeignTableLocalDetails: localDetailsForeignTableLocalDetailsWire, + Table: detailsTableWire, + Notebook: detailsNotebookWire, + View: detailsViewWire, + ForeignTable: detailsForeignTableWire, + JarAnalysis: detailsJarAnalysisWire, + }, nil +} + +func cleanRoomAssetFromWire(w *cleanRoomAssetWire) (*CleanRoomAsset, error) { + if w == nil { + return nil, nil + } + localDetailsMembers := 0 + if w.TableLocalDetails != nil { + localDetailsMembers++ + } + if w.VolumeLocalDetails != nil { + localDetailsMembers++ + } + if w.ViewLocalDetails != nil { + localDetailsMembers++ + } + if w.ForeignTableLocalDetails != nil { + localDetailsMembers++ + } + if localDetailsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "CleanRoomAsset.LocalDetails") + } + detailsMembers := 0 + if w.Table != nil { + detailsMembers++ + } + if w.Notebook != nil { + detailsMembers++ + } + if w.View != nil { + detailsMembers++ + } + if w.ForeignTable != nil { + detailsMembers++ + } + if w.JarAnalysis != nil { + detailsMembers++ + } + if detailsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "CleanRoomAsset.Details") + } + var localDetailsSelection isCleanRoomAsset_LocalDetails + switch { + case w.TableLocalDetails != nil: + localDetailsTableLocalDetailsConverted, err := cleanRoomAsset_TableLocalDetailsFromWire(w.TableLocalDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.LocalDetails.TableLocalDetails", err) + } + localDetailsSelection = &CleanRoomAsset_LocalDetails_TableLocalDetails{TableLocalDetails: *localDetailsTableLocalDetailsConverted} + case w.VolumeLocalDetails != nil: + localDetailsVolumeLocalDetailsConverted, err := cleanRoomAsset_VolumeLocalDetailsFromWire(w.VolumeLocalDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.LocalDetails.VolumeLocalDetails", err) + } + localDetailsSelection = &CleanRoomAsset_LocalDetails_VolumeLocalDetails{VolumeLocalDetails: *localDetailsVolumeLocalDetailsConverted} + case w.ViewLocalDetails != nil: + localDetailsViewLocalDetailsConverted, err := cleanRoomAsset_ViewLocalDetailsFromWire(w.ViewLocalDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.LocalDetails.ViewLocalDetails", err) + } + localDetailsSelection = &CleanRoomAsset_LocalDetails_ViewLocalDetails{ViewLocalDetails: *localDetailsViewLocalDetailsConverted} + case w.ForeignTableLocalDetails != nil: + localDetailsForeignTableLocalDetailsConverted, err := cleanRoomAsset_ForeignTableLocalDetailsFromWire(w.ForeignTableLocalDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.LocalDetails.ForeignTableLocalDetails", err) + } + localDetailsSelection = &CleanRoomAsset_LocalDetails_ForeignTableLocalDetails{ForeignTableLocalDetails: *localDetailsForeignTableLocalDetailsConverted} + } + var detailsSelection isCleanRoomAsset_Details + switch { + case w.Table != nil: + detailsTableConverted, err := cleanRoomAsset_TableFromWire(w.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.Details.Table", err) + } + detailsSelection = &CleanRoomAsset_Details_Table{Table: *detailsTableConverted} + case w.Notebook != nil: + detailsNotebookConverted, err := cleanRoomAsset_NotebookFromWire(w.Notebook) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.Details.Notebook", err) + } + detailsSelection = &CleanRoomAsset_Details_Notebook{Notebook: *detailsNotebookConverted} + case w.View != nil: + detailsViewConverted, err := cleanRoomAsset_ViewFromWire(w.View) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.Details.View", err) + } + detailsSelection = &CleanRoomAsset_Details_View{View: *detailsViewConverted} + case w.ForeignTable != nil: + detailsForeignTableConverted, err := cleanRoomAsset_ForeignTableFromWire(w.ForeignTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.Details.ForeignTable", err) + } + detailsSelection = &CleanRoomAsset_Details_ForeignTable{ForeignTable: *detailsForeignTableConverted} + case w.JarAnalysis != nil: + detailsJarAnalysisConverted, err := cleanRoomAsset_JarAnalysisFromWire(w.JarAnalysis) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset.Details.JarAnalysis", err) + } + detailsSelection = &CleanRoomAsset_Details_JarAnalysis{JarAnalysis: *detailsJarAnalysisConverted} + } + return &CleanRoomAsset{ + CleanRoomName: w.CleanRoomName, + Name: w.Name, + AssetType: w.AssetType, + AddedAt: w.AddedAt, + Status: w.Status, + OwnerCollaboratorAlias: w.OwnerCollaboratorAlias, + LocalDetails: localDetailsSelection, + Details: detailsSelection, + }, nil +} + +type cleanRoomAsset_ForeignTableWire struct { + Columns []columnInfoWire `json:"columns,omitempty"` +} + +func cleanRoomAsset_ForeignTableToWire(v *CleanRoomAsset_ForeignTable) (*cleanRoomAsset_ForeignTableWire, error) { + if v == nil { + return nil, nil + } + columnsWireValue, err := convertSlice(v.Columns, columnInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_ForeignTable.Columns", err) + } + return &cleanRoomAsset_ForeignTableWire{ + Columns: columnsWireValue, + }, nil +} + +func cleanRoomAsset_ForeignTableFromWire(w *cleanRoomAsset_ForeignTableWire) (*CleanRoomAsset_ForeignTable, error) { + if w == nil { + return nil, nil + } + columnsPublicValue, err := convertSlice(w.Columns, columnInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_ForeignTable.Columns", err) + } + return &CleanRoomAsset_ForeignTable{ + Columns: columnsPublicValue, + }, nil +} + +type cleanRoomAsset_ForeignTableLocalDetailsWire struct { + LocalName *string `json:"local_name,omitempty"` +} + +func cleanRoomAsset_ForeignTableLocalDetailsToWire(v *CleanRoomAsset_ForeignTableLocalDetails) (*cleanRoomAsset_ForeignTableLocalDetailsWire, error) { + if v == nil { + return nil, nil + } + return &cleanRoomAsset_ForeignTableLocalDetailsWire{ + LocalName: v.LocalName, + }, nil +} + +func cleanRoomAsset_ForeignTableLocalDetailsFromWire(w *cleanRoomAsset_ForeignTableLocalDetailsWire) (*CleanRoomAsset_ForeignTableLocalDetails, error) { + if w == nil { + return nil, nil + } + return &CleanRoomAsset_ForeignTableLocalDetails{ + LocalName: w.LocalName, + }, nil +} + +type cleanRoomAsset_JarAnalysisWire struct { + Etag *string `json:"etag,omitempty"` + Description *string `json:"description,omitempty"` + RunnerCollaboratorAliases []string `json:"runner_collaborator_aliases,omitempty"` + Reviews []cleanRoomJarAnalysisReviewWire `json:"reviews,omitempty"` + ReviewState CleanRoomJarAnalysisReview_JarAnalysisReviewState `json:"review_state,omitempty"` + MainClassName *string `json:"main_class_name,omitempty"` + CentralJarFilePaths []string `json:"central_jar_file_paths,omitempty"` + EnvironmentVersion *string `json:"environment_version,omitempty"` +} + +func cleanRoomAsset_JarAnalysisToWire(v *CleanRoomAsset_JarAnalysis) (*cleanRoomAsset_JarAnalysisWire, error) { + if v == nil { + return nil, nil + } + reviewsWireValue, err := convertSlice(v.Reviews, cleanRoomJarAnalysisReviewToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_JarAnalysis.Reviews", err) + } + return &cleanRoomAsset_JarAnalysisWire{ + Etag: v.Etag, + Description: v.Description, + RunnerCollaboratorAliases: v.RunnerCollaboratorAliases, + Reviews: reviewsWireValue, + ReviewState: v.ReviewState, + MainClassName: v.MainClassName, + CentralJarFilePaths: v.CentralJarFilePaths, + EnvironmentVersion: v.EnvironmentVersion, + }, nil +} + +func cleanRoomAsset_JarAnalysisFromWire(w *cleanRoomAsset_JarAnalysisWire) (*CleanRoomAsset_JarAnalysis, error) { + if w == nil { + return nil, nil + } + reviewsPublicValue, err := convertSlice(w.Reviews, cleanRoomJarAnalysisReviewFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_JarAnalysis.Reviews", err) + } + return &CleanRoomAsset_JarAnalysis{ + Etag: w.Etag, + Description: w.Description, + RunnerCollaboratorAliases: w.RunnerCollaboratorAliases, + Reviews: reviewsPublicValue, + ReviewState: w.ReviewState, + MainClassName: w.MainClassName, + CentralJarFilePaths: w.CentralJarFilePaths, + EnvironmentVersion: w.EnvironmentVersion, + }, nil +} + +type cleanRoomAsset_NotebookWire struct { + NotebookContent *string `json:"notebook_content,omitempty"` + Etag *string `json:"etag,omitempty"` + RunnerCollaboratorAliases []string `json:"runner_collaborator_aliases,omitempty"` + Reviews []cleanRoomNotebookReviewWire `json:"reviews,omitempty"` + ReviewState CleanRoomNotebookReview_NotebookReviewState `json:"review_state,omitempty"` + Description *string `json:"description,omitempty"` + EnvironmentVersion *string `json:"environment_version,omitempty"` +} + +func cleanRoomAsset_NotebookToWire(v *CleanRoomAsset_Notebook) (*cleanRoomAsset_NotebookWire, error) { + if v == nil { + return nil, nil + } + reviewsWireValue, err := convertSlice(v.Reviews, cleanRoomNotebookReviewToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_Notebook.Reviews", err) + } + return &cleanRoomAsset_NotebookWire{ + NotebookContent: v.NotebookContent, + Etag: v.Etag, + RunnerCollaboratorAliases: v.RunnerCollaboratorAliases, + Reviews: reviewsWireValue, + ReviewState: v.ReviewState, + Description: v.Description, + EnvironmentVersion: v.EnvironmentVersion, + }, nil +} + +func cleanRoomAsset_NotebookFromWire(w *cleanRoomAsset_NotebookWire) (*CleanRoomAsset_Notebook, error) { + if w == nil { + return nil, nil + } + reviewsPublicValue, err := convertSlice(w.Reviews, cleanRoomNotebookReviewFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_Notebook.Reviews", err) + } + return &CleanRoomAsset_Notebook{ + NotebookContent: w.NotebookContent, + Etag: w.Etag, + RunnerCollaboratorAliases: w.RunnerCollaboratorAliases, + Reviews: reviewsPublicValue, + ReviewState: w.ReviewState, + Description: w.Description, + EnvironmentVersion: w.EnvironmentVersion, + }, nil +} + +type cleanRoomAsset_TableWire struct { + Columns []columnInfoWire `json:"columns,omitempty"` +} + +func cleanRoomAsset_TableToWire(v *CleanRoomAsset_Table) (*cleanRoomAsset_TableWire, error) { + if v == nil { + return nil, nil + } + columnsWireValue, err := convertSlice(v.Columns, columnInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_Table.Columns", err) + } + return &cleanRoomAsset_TableWire{ + Columns: columnsWireValue, + }, nil +} + +func cleanRoomAsset_TableFromWire(w *cleanRoomAsset_TableWire) (*CleanRoomAsset_Table, error) { + if w == nil { + return nil, nil + } + columnsPublicValue, err := convertSlice(w.Columns, columnInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_Table.Columns", err) + } + return &CleanRoomAsset_Table{ + Columns: columnsPublicValue, + }, nil +} + +type cleanRoomAsset_TableLocalDetailsWire struct { + LocalName *string `json:"local_name,omitempty"` + Partitions []partitionSpecification_PartitionWire `json:"partitions,omitempty"` +} + +func cleanRoomAsset_TableLocalDetailsToWire(v *CleanRoomAsset_TableLocalDetails) (*cleanRoomAsset_TableLocalDetailsWire, error) { + if v == nil { + return nil, nil + } + partitionsWireValue, err := convertSlice(v.Partitions, partitionSpecification_PartitionToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_TableLocalDetails.Partitions", err) + } + return &cleanRoomAsset_TableLocalDetailsWire{ + LocalName: v.LocalName, + Partitions: partitionsWireValue, + }, nil +} + +func cleanRoomAsset_TableLocalDetailsFromWire(w *cleanRoomAsset_TableLocalDetailsWire) (*CleanRoomAsset_TableLocalDetails, error) { + if w == nil { + return nil, nil + } + partitionsPublicValue, err := convertSlice(w.Partitions, partitionSpecification_PartitionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_TableLocalDetails.Partitions", err) + } + return &CleanRoomAsset_TableLocalDetails{ + LocalName: w.LocalName, + Partitions: partitionsPublicValue, + }, nil +} + +type cleanRoomAsset_ViewWire struct { + Columns []columnInfoWire `json:"columns,omitempty"` +} + +func cleanRoomAsset_ViewToWire(v *CleanRoomAsset_View) (*cleanRoomAsset_ViewWire, error) { + if v == nil { + return nil, nil + } + columnsWireValue, err := convertSlice(v.Columns, columnInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_View.Columns", err) + } + return &cleanRoomAsset_ViewWire{ + Columns: columnsWireValue, + }, nil +} + +func cleanRoomAsset_ViewFromWire(w *cleanRoomAsset_ViewWire) (*CleanRoomAsset_View, error) { + if w == nil { + return nil, nil + } + columnsPublicValue, err := convertSlice(w.Columns, columnInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomAsset_View.Columns", err) + } + return &CleanRoomAsset_View{ + Columns: columnsPublicValue, + }, nil +} + +type cleanRoomAsset_ViewLocalDetailsWire struct { + LocalName *string `json:"local_name,omitempty"` +} + +func cleanRoomAsset_ViewLocalDetailsToWire(v *CleanRoomAsset_ViewLocalDetails) (*cleanRoomAsset_ViewLocalDetailsWire, error) { + if v == nil { + return nil, nil + } + return &cleanRoomAsset_ViewLocalDetailsWire{ + LocalName: v.LocalName, + }, nil +} + +func cleanRoomAsset_ViewLocalDetailsFromWire(w *cleanRoomAsset_ViewLocalDetailsWire) (*CleanRoomAsset_ViewLocalDetails, error) { + if w == nil { + return nil, nil + } + return &CleanRoomAsset_ViewLocalDetails{ + LocalName: w.LocalName, + }, nil +} + +type cleanRoomAsset_VolumeLocalDetailsWire struct { + LocalName *string `json:"local_name,omitempty"` +} + +func cleanRoomAsset_VolumeLocalDetailsToWire(v *CleanRoomAsset_VolumeLocalDetails) (*cleanRoomAsset_VolumeLocalDetailsWire, error) { + if v == nil { + return nil, nil + } + return &cleanRoomAsset_VolumeLocalDetailsWire{ + LocalName: v.LocalName, + }, nil +} + +func cleanRoomAsset_VolumeLocalDetailsFromWire(w *cleanRoomAsset_VolumeLocalDetailsWire) (*CleanRoomAsset_VolumeLocalDetails, error) { + if w == nil { + return nil, nil + } + return &CleanRoomAsset_VolumeLocalDetails{ + LocalName: w.LocalName, + }, nil +} + +type cleanRoomAutoApprovalRuleWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + RuleId *string `json:"rule_id,omitempty"` + RuleOwnerCollaboratorAlias *string `json:"rule_owner_collaborator_alias,omitempty"` + AuthorCollaboratorAlias *string `json:"author_collaborator_alias,omitempty"` + AuthorScope CleanRoomAutoApprovalRule_AuthorScope `json:"author_scope,omitempty"` + RunnerCollaboratorAlias *string `json:"runner_collaborator_alias,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` +} + +func cleanRoomAutoApprovalRuleToWire(v *CleanRoomAutoApprovalRule) (*cleanRoomAutoApprovalRuleWire, error) { + if v == nil { + return nil, nil + } + var authorsAuthorCollaboratorAliasWire *string + var authorsAuthorScopeWire CleanRoomAutoApprovalRule_AuthorScope + switch value := v.Authors.(type) { + case nil: + case *CleanRoomAutoApprovalRule_Authors_AuthorCollaboratorAlias: + if value != nil { + authorsAuthorCollaboratorAliasWire = new(value.AuthorCollaboratorAlias) + } + case *CleanRoomAutoApprovalRule_Authors_AuthorScope: + if value != nil { + authorsAuthorScopeWire = value.AuthorScope + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CleanRoomAutoApprovalRule.Authors", value) + } + var runnersRunnerCollaboratorAliasWire *string + switch value := v.Runners.(type) { + case nil: + case *CleanRoomAutoApprovalRule_Runners_RunnerCollaboratorAlias: + if value != nil { + runnersRunnerCollaboratorAliasWire = new(value.RunnerCollaboratorAlias) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CleanRoomAutoApprovalRule.Runners", value) + } + return &cleanRoomAutoApprovalRuleWire{ + CleanRoomName: v.CleanRoomName, + RuleId: v.RuleId, + RuleOwnerCollaboratorAlias: v.RuleOwnerCollaboratorAlias, + AuthorCollaboratorAlias: authorsAuthorCollaboratorAliasWire, + AuthorScope: authorsAuthorScopeWire, + RunnerCollaboratorAlias: runnersRunnerCollaboratorAliasWire, + CreatedAt: v.CreatedAt, + }, nil +} + +func cleanRoomAutoApprovalRuleFromWire(w *cleanRoomAutoApprovalRuleWire) (*CleanRoomAutoApprovalRule, error) { + if w == nil { + return nil, nil + } + authorsMembers := 0 + if w.AuthorCollaboratorAlias != nil { + authorsMembers++ + } + if w.AuthorScope != "" { + authorsMembers++ + } + if authorsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "CleanRoomAutoApprovalRule.Authors") + } + runnersMembers := 0 + if w.RunnerCollaboratorAlias != nil { + runnersMembers++ + } + if runnersMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "CleanRoomAutoApprovalRule.Runners") + } + var authorsSelection isCleanRoomAutoApprovalRule_Authors + switch { + case w.AuthorCollaboratorAlias != nil: + authorsSelection = &CleanRoomAutoApprovalRule_Authors_AuthorCollaboratorAlias{AuthorCollaboratorAlias: *w.AuthorCollaboratorAlias} + case w.AuthorScope != "": + authorsSelection = &CleanRoomAutoApprovalRule_Authors_AuthorScope{AuthorScope: w.AuthorScope} + } + var runnersSelection isCleanRoomAutoApprovalRule_Runners + switch { + case w.RunnerCollaboratorAlias != nil: + runnersSelection = &CleanRoomAutoApprovalRule_Runners_RunnerCollaboratorAlias{RunnerCollaboratorAlias: *w.RunnerCollaboratorAlias} + } + return &CleanRoomAutoApprovalRule{ + CleanRoomName: w.CleanRoomName, + RuleId: w.RuleId, + RuleOwnerCollaboratorAlias: w.RuleOwnerCollaboratorAlias, + CreatedAt: w.CreatedAt, + Authors: authorsSelection, + Runners: runnersSelection, + }, nil +} + +type cleanRoomCollaboratorWire struct { + GlobalMetastoreId *string `json:"global_metastore_id,omitempty"` + OrganizationName *string `json:"organization_name,omitempty"` + InviteRecipientWorkspaceId *int64 `json:"invite_recipient_workspace_id,omitempty"` + InviteRecipientEmail *string `json:"invite_recipient_email,omitempty"` + CollaboratorAlias *string `json:"collaborator_alias,omitempty"` + DisplayName *string `json:"display_name,omitempty"` +} + +func cleanRoomCollaboratorToWire(v *CleanRoomCollaborator) (*cleanRoomCollaboratorWire, error) { + if v == nil { + return nil, nil + } + return &cleanRoomCollaboratorWire{ + GlobalMetastoreId: v.GlobalMetastoreId, + OrganizationName: v.OrganizationName, + InviteRecipientWorkspaceId: v.InviteRecipientWorkspaceId, + InviteRecipientEmail: v.InviteRecipientEmail, + CollaboratorAlias: v.CollaboratorAlias, + DisplayName: v.DisplayName, + }, nil +} + +func cleanRoomCollaboratorFromWire(w *cleanRoomCollaboratorWire) (*CleanRoomCollaborator, error) { + if w == nil { + return nil, nil + } + return &CleanRoomCollaborator{ + GlobalMetastoreId: w.GlobalMetastoreId, + OrganizationName: w.OrganizationName, + InviteRecipientWorkspaceId: w.InviteRecipientWorkspaceId, + InviteRecipientEmail: w.InviteRecipientEmail, + CollaboratorAlias: w.CollaboratorAlias, + DisplayName: w.DisplayName, + }, nil +} + +type cleanRoomJarAnalysisReviewWire struct { + ReviewerCollaboratorAlias *string `json:"reviewer_collaborator_alias,omitempty"` + CreatedAtMillis *int64 `json:"created_at_millis,omitempty"` + ReviewState CleanRoomJarAnalysisReview_JarAnalysisReviewState `json:"review_state,omitempty"` + Comment *string `json:"comment,omitempty"` + ReviewSubReason CleanRoomJarAnalysisReview_JarAnalysisReviewSubReason `json:"review_sub_reason,omitempty"` +} + +func cleanRoomJarAnalysisReviewToWire(v *CleanRoomJarAnalysisReview) (*cleanRoomJarAnalysisReviewWire, error) { + if v == nil { + return nil, nil + } + return &cleanRoomJarAnalysisReviewWire{ + ReviewerCollaboratorAlias: v.ReviewerCollaboratorAlias, + CreatedAtMillis: v.CreatedAtMillis, + ReviewState: v.ReviewState, + Comment: v.Comment, + ReviewSubReason: v.ReviewSubReason, + }, nil +} + +func cleanRoomJarAnalysisReviewFromWire(w *cleanRoomJarAnalysisReviewWire) (*CleanRoomJarAnalysisReview, error) { + if w == nil { + return nil, nil + } + return &CleanRoomJarAnalysisReview{ + ReviewerCollaboratorAlias: w.ReviewerCollaboratorAlias, + CreatedAtMillis: w.CreatedAtMillis, + ReviewState: w.ReviewState, + Comment: w.Comment, + ReviewSubReason: w.ReviewSubReason, + }, nil +} + +type cleanRoomNotebookReviewWire struct { + ReviewerCollaboratorAlias *string `json:"reviewer_collaborator_alias,omitempty"` + CreatedAtMillis *int64 `json:"created_at_millis,omitempty"` + ReviewState CleanRoomNotebookReview_NotebookReviewState `json:"review_state,omitempty"` + Comment *string `json:"comment,omitempty"` + ReviewSubReason CleanRoomNotebookReview_NotebookReviewSubReason `json:"review_sub_reason,omitempty"` +} + +func cleanRoomNotebookReviewToWire(v *CleanRoomNotebookReview) (*cleanRoomNotebookReviewWire, error) { + if v == nil { + return nil, nil + } + return &cleanRoomNotebookReviewWire{ + ReviewerCollaboratorAlias: v.ReviewerCollaboratorAlias, + CreatedAtMillis: v.CreatedAtMillis, + ReviewState: v.ReviewState, + Comment: v.Comment, + ReviewSubReason: v.ReviewSubReason, + }, nil +} + +func cleanRoomNotebookReviewFromWire(w *cleanRoomNotebookReviewWire) (*CleanRoomNotebookReview, error) { + if w == nil { + return nil, nil + } + return &CleanRoomNotebookReview{ + ReviewerCollaboratorAlias: w.ReviewerCollaboratorAlias, + CreatedAtMillis: w.CreatedAtMillis, + ReviewState: w.ReviewState, + Comment: w.Comment, + ReviewSubReason: w.ReviewSubReason, + }, nil +} + +type cleanRoomNotebookTaskRunWire struct { + NotebookName *string `json:"notebook_name,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + RunDuration *int64 `json:"run_duration,omitempty"` + NotebookJobRunState *cleanRoomTaskRunStateWire `json:"notebook_job_run_state,omitempty"` + CollaboratorJobRunInfo *collaboratorJobRunInfoWire `json:"collaborator_job_run_info,omitempty"` + OutputSchemaName *string `json:"output_schema_name,omitempty"` + OutputSchemaExpirationTime *int64 `json:"output_schema_expiration_time,omitempty"` + NotebookEtag *string `json:"notebook_etag,omitempty"` + NotebookUpdatedAt *int64 `json:"notebook_updated_at,omitempty"` + SharedOutputSchemaName *string `json:"shared_output_schema_name,omitempty"` + SharedOutputSchemaExpirationTime *int64 `json:"shared_output_schema_expiration_time,omitempty"` +} + +func cleanRoomNotebookTaskRunFromWire(w *cleanRoomNotebookTaskRunWire) (*CleanRoomNotebookTaskRun, error) { + if w == nil { + return nil, nil + } + notebookJobRunStatePublicValue, err := cleanRoomTaskRunStateFromWire(w.NotebookJobRunState) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomNotebookTaskRun.NotebookJobRunState", err) + } + collaboratorJobRunInfoPublicValue, err := collaboratorJobRunInfoFromWire(w.CollaboratorJobRunInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomNotebookTaskRun.CollaboratorJobRunInfo", err) + } + return &CleanRoomNotebookTaskRun{ + NotebookName: w.NotebookName, + StartTime: w.StartTime, + RunDuration: w.RunDuration, + NotebookJobRunState: notebookJobRunStatePublicValue, + CollaboratorJobRunInfo: collaboratorJobRunInfoPublicValue, + OutputSchemaName: w.OutputSchemaName, + OutputSchemaExpirationTime: w.OutputSchemaExpirationTime, + NotebookEtag: w.NotebookEtag, + NotebookUpdatedAt: w.NotebookUpdatedAt, + SharedOutputSchemaName: w.SharedOutputSchemaName, + SharedOutputSchemaExpirationTime: w.SharedOutputSchemaExpirationTime, + }, nil +} + +type cleanRoomOutputCatalogWire struct { + Status CleanRoomOutputCatalog_OutputCatalogStatus `json:"status,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` +} + +func cleanRoomOutputCatalogToWire(v *CleanRoomOutputCatalog) (*cleanRoomOutputCatalogWire, error) { + if v == nil { + return nil, nil + } + return &cleanRoomOutputCatalogWire{ + Status: v.Status, + CatalogName: v.CatalogName, + }, nil +} + +func cleanRoomOutputCatalogFromWire(w *cleanRoomOutputCatalogWire) (*CleanRoomOutputCatalog, error) { + if w == nil { + return nil, nil + } + return &CleanRoomOutputCatalog{ + Status: w.Status, + CatalogName: w.CatalogName, + }, nil +} + +type cleanRoomRemoteDetailWire struct { + CentralCleanRoomId *string `json:"central_clean_room_id,omitempty"` + CloudVendor *string `json:"cloud_vendor,omitempty"` + Region *string `json:"region,omitempty"` + Collaborators []cleanRoomCollaboratorWire `json:"collaborators,omitempty"` + Creator *cleanRoomCollaboratorWire `json:"creator,omitempty"` + EgressNetworkPolicy *egressNetworkPolicyWire `json:"egress_network_policy,omitempty"` + ComplianceSecurityProfile *complianceSecurityProfileWire `json:"compliance_security_profile,omitempty"` + EnableSharedOutput *bool `json:"enable_shared_output,omitempty"` + PackageProviderCollaboratorAlias *string `json:"package_provider_collaborator_alias,omitempty"` +} + +func cleanRoomRemoteDetailToWire(v *CleanRoomRemoteDetail) (*cleanRoomRemoteDetailWire, error) { + if v == nil { + return nil, nil + } + collaboratorsWireValue, err := convertSlice(v.Collaborators, cleanRoomCollaboratorToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomRemoteDetail.Collaborators", err) + } + creatorWireValue, err := cleanRoomCollaboratorToWire(v.Creator) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomRemoteDetail.Creator", err) + } + egressNetworkPolicyWireValue, err := egressNetworkPolicyToWire(v.EgressNetworkPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomRemoteDetail.EgressNetworkPolicy", err) + } + complianceSecurityProfileWireValue, err := complianceSecurityProfileToWire(v.ComplianceSecurityProfile) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomRemoteDetail.ComplianceSecurityProfile", err) + } + return &cleanRoomRemoteDetailWire{ + CentralCleanRoomId: v.CentralCleanRoomId, + CloudVendor: v.CloudVendor, + Region: v.Region, + Collaborators: collaboratorsWireValue, + Creator: creatorWireValue, + EgressNetworkPolicy: egressNetworkPolicyWireValue, + ComplianceSecurityProfile: complianceSecurityProfileWireValue, + EnableSharedOutput: v.EnableSharedOutput, + PackageProviderCollaboratorAlias: v.PackageProviderCollaboratorAlias, + }, nil +} + +func cleanRoomRemoteDetailFromWire(w *cleanRoomRemoteDetailWire) (*CleanRoomRemoteDetail, error) { + if w == nil { + return nil, nil + } + collaboratorsPublicValue, err := convertSlice(w.Collaborators, cleanRoomCollaboratorFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomRemoteDetail.Collaborators", err) + } + creatorPublicValue, err := cleanRoomCollaboratorFromWire(w.Creator) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomRemoteDetail.Creator", err) + } + egressNetworkPolicyPublicValue, err := egressNetworkPolicyFromWire(w.EgressNetworkPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomRemoteDetail.EgressNetworkPolicy", err) + } + complianceSecurityProfilePublicValue, err := complianceSecurityProfileFromWire(w.ComplianceSecurityProfile) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomRemoteDetail.ComplianceSecurityProfile", err) + } + return &CleanRoomRemoteDetail{ + CentralCleanRoomId: w.CentralCleanRoomId, + CloudVendor: w.CloudVendor, + Region: w.Region, + Collaborators: collaboratorsPublicValue, + Creator: creatorPublicValue, + EgressNetworkPolicy: egressNetworkPolicyPublicValue, + ComplianceSecurityProfile: complianceSecurityProfilePublicValue, + EnableSharedOutput: w.EnableSharedOutput, + PackageProviderCollaboratorAlias: w.PackageProviderCollaboratorAlias, + }, nil +} + +type cleanRoomTaskRunWire struct { + Name *string `json:"name,omitempty"` + TaskType CleanRoomTaskType `json:"task_type,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + RunDuration *int64 `json:"run_duration,omitempty"` + TaskRunState *cleanRoomTaskRunStateWire `json:"task_run_state,omitempty"` + CollaboratorJobRunInfo *collaboratorJobRunInfoWire `json:"collaborator_job_run_info,omitempty"` + OutputInfo *cleanRoomTaskRun_OutputInfoWire `json:"output_info,omitempty"` + AnalysisDetails *cleanRoomTaskRun_CleanRoomTaskAnalysisDetailsWire `json:"analysis_details,omitempty"` + SharedOutputInfo *cleanRoomTaskRun_OutputInfoWire `json:"shared_output_info,omitempty"` +} + +func cleanRoomTaskRunFromWire(w *cleanRoomTaskRunWire) (*CleanRoomTaskRun, error) { + if w == nil { + return nil, nil + } + taskRunStatePublicValue, err := cleanRoomTaskRunStateFromWire(w.TaskRunState) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomTaskRun.TaskRunState", err) + } + collaboratorJobRunInfoPublicValue, err := collaboratorJobRunInfoFromWire(w.CollaboratorJobRunInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomTaskRun.CollaboratorJobRunInfo", err) + } + outputInfoPublicValue, err := cleanRoomTaskRun_OutputInfoFromWire(w.OutputInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomTaskRun.OutputInfo", err) + } + analysisDetailsPublicValue, err := cleanRoomTaskRun_CleanRoomTaskAnalysisDetailsFromWire(w.AnalysisDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomTaskRun.AnalysisDetails", err) + } + sharedOutputInfoPublicValue, err := cleanRoomTaskRun_OutputInfoFromWire(w.SharedOutputInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomTaskRun.SharedOutputInfo", err) + } + return &CleanRoomTaskRun{ + Name: w.Name, + TaskType: w.TaskType, + StartTime: w.StartTime, + RunDuration: w.RunDuration, + TaskRunState: taskRunStatePublicValue, + CollaboratorJobRunInfo: collaboratorJobRunInfoPublicValue, + OutputInfo: outputInfoPublicValue, + AnalysisDetails: analysisDetailsPublicValue, + SharedOutputInfo: sharedOutputInfoPublicValue, + }, nil +} + +type cleanRoomTaskRun_CleanRoomTaskAnalysisDetailsWire struct { + Etag *string `json:"etag,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` +} + +func cleanRoomTaskRun_CleanRoomTaskAnalysisDetailsFromWire(w *cleanRoomTaskRun_CleanRoomTaskAnalysisDetailsWire) (*CleanRoomTaskRun_CleanRoomTaskAnalysisDetails, error) { + if w == nil { + return nil, nil + } + return &CleanRoomTaskRun_CleanRoomTaskAnalysisDetails{ + Etag: w.Etag, + UpdatedAt: w.UpdatedAt, + }, nil +} + +type cleanRoomTaskRun_OutputInfoWire struct { + OutputSchemaName *string `json:"output_schema_name,omitempty"` + OutputSchemaExpirationTime *int64 `json:"output_schema_expiration_time,omitempty"` +} + +func cleanRoomTaskRun_OutputInfoFromWire(w *cleanRoomTaskRun_OutputInfoWire) (*CleanRoomTaskRun_OutputInfo, error) { + if w == nil { + return nil, nil + } + return &CleanRoomTaskRun_OutputInfo{ + OutputSchemaName: w.OutputSchemaName, + OutputSchemaExpirationTime: w.OutputSchemaExpirationTime, + }, nil +} + +type cleanRoomTaskRunStateWire struct { + LifeCycleState CleanRoomTaskRunLifeCycleState `json:"life_cycle_state,omitempty"` + ResultState CleanRoomTaskRunResultState `json:"result_state,omitempty"` +} + +func cleanRoomTaskRunStateFromWire(w *cleanRoomTaskRunStateWire) (*CleanRoomTaskRunState, error) { + if w == nil { + return nil, nil + } + return &CleanRoomTaskRunState{ + LifeCycleState: w.LifeCycleState, + ResultState: w.ResultState, + }, nil +} + +type collaboratorJobRunInfoWire struct { + CollaboratorJobId *int64 `json:"collaborator_job_id,omitempty"` + CollaboratorJobRunId *int64 `json:"collaborator_job_run_id,omitempty"` + CollaboratorTaskRunId *int64 `json:"collaborator_task_run_id,omitempty"` + CollaboratorWorkspaceId *int64 `json:"collaborator_workspace_id,omitempty"` + CollaboratorAlias *string `json:"collaborator_alias,omitempty"` +} + +func collaboratorJobRunInfoFromWire(w *collaboratorJobRunInfoWire) (*CollaboratorJobRunInfo, error) { + if w == nil { + return nil, nil + } + return &CollaboratorJobRunInfo{ + CollaboratorJobId: w.CollaboratorJobId, + CollaboratorJobRunId: w.CollaboratorJobRunId, + CollaboratorTaskRunId: w.CollaboratorTaskRunId, + CollaboratorWorkspaceId: w.CollaboratorWorkspaceId, + CollaboratorAlias: w.CollaboratorAlias, + }, nil +} + +type columnInfoWire struct { + Name *string `json:"name,omitempty"` + TypeText *string `json:"type_text,omitempty"` + TypeName ColumnTypeName `json:"type_name,omitempty"` + Position *int `json:"position,omitempty"` + TypePrecision *int `json:"type_precision,omitempty"` + TypeScale *int `json:"type_scale,omitempty"` + TypeIntervalType *string `json:"type_interval_type,omitempty"` + TypeJson *string `json:"type_json,omitempty"` + Comment *string `json:"comment,omitempty"` + Nullable *bool `json:"nullable,omitempty"` + PartitionIndex *int `json:"partition_index,omitempty"` + Mask *columnMaskWire `json:"mask,omitempty"` +} + +func columnInfoToWire(v *ColumnInfo) (*columnInfoWire, error) { + if v == nil { + return nil, nil + } + maskWireValue, err := columnMaskToWire(v.Mask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnInfo.Mask", err) + } + return &columnInfoWire{ + Name: v.Name, + TypeText: v.TypeText, + TypeName: v.TypeName, + Position: v.Position, + TypePrecision: v.TypePrecision, + TypeScale: v.TypeScale, + TypeIntervalType: v.TypeIntervalType, + TypeJson: v.TypeJson, + Comment: v.Comment, + Nullable: v.Nullable, + PartitionIndex: v.PartitionIndex, + Mask: maskWireValue, + }, nil +} + +func columnInfoFromWire(w *columnInfoWire) (*ColumnInfo, error) { + if w == nil { + return nil, nil + } + maskPublicValue, err := columnMaskFromWire(w.Mask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnInfo.Mask", err) + } + return &ColumnInfo{ + Name: w.Name, + TypeText: w.TypeText, + TypeName: w.TypeName, + Position: w.Position, + TypePrecision: w.TypePrecision, + TypeScale: w.TypeScale, + TypeIntervalType: w.TypeIntervalType, + TypeJson: w.TypeJson, + Comment: w.Comment, + Nullable: w.Nullable, + PartitionIndex: w.PartitionIndex, + Mask: maskPublicValue, + }, nil +} + +type columnMaskWire struct { + FunctionName *string `json:"function_name,omitempty"` + UsingColumnNames []string `json:"using_column_names,omitempty"` + UsingArguments []policyFunctionArgumentWire `json:"using_arguments,omitempty"` +} + +func columnMaskToWire(v *ColumnMask) (*columnMaskWire, error) { + if v == nil { + return nil, nil + } + usingArgumentsWireValue, err := convertSlice(v.UsingArguments, policyFunctionArgumentToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnMask.UsingArguments", err) + } + return &columnMaskWire{ + FunctionName: v.FunctionName, + UsingColumnNames: v.UsingColumnNames, + UsingArguments: usingArgumentsWireValue, + }, nil +} + +func columnMaskFromWire(w *columnMaskWire) (*ColumnMask, error) { + if w == nil { + return nil, nil + } + usingArgumentsPublicValue, err := convertSlice(w.UsingArguments, policyFunctionArgumentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnMask.UsingArguments", err) + } + return &ColumnMask{ + FunctionName: w.FunctionName, + UsingColumnNames: w.UsingColumnNames, + UsingArguments: usingArgumentsPublicValue, + }, nil +} + +type complianceSecurityProfileWire struct { + IsEnabled *bool `json:"is_enabled,omitempty"` + ComplianceStandards []ComplianceStandard `json:"compliance_standards,omitempty"` +} + +func complianceSecurityProfileToWire(v *ComplianceSecurityProfile) (*complianceSecurityProfileWire, error) { + if v == nil { + return nil, nil + } + return &complianceSecurityProfileWire{ + IsEnabled: v.IsEnabled, + ComplianceStandards: v.ComplianceStandards, + }, nil +} + +func complianceSecurityProfileFromWire(w *complianceSecurityProfileWire) (*ComplianceSecurityProfile, error) { + if w == nil { + return nil, nil + } + return &ComplianceSecurityProfile{ + IsEnabled: w.IsEnabled, + ComplianceStandards: w.ComplianceStandards, + }, nil +} + +type createCleanRoomAssetRequestWire struct { + Asset *cleanRoomAssetWire `json:"asset,omitempty"` +} + +func createCleanRoomAssetRequestToWire(v *CreateCleanRoomAssetRequest) (*createCleanRoomAssetRequestWire, error) { + if v == nil { + return nil, nil + } + assetWireValue, err := cleanRoomAssetToWire(v.Asset) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCleanRoomAssetRequest.Asset", err) + } + return &createCleanRoomAssetRequestWire{ + Asset: assetWireValue, + }, nil +} + +type createCleanRoomAssetReviewRequestWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + Name *string `json:"name,omitempty"` + AssetType CleanRoomAsset_AssetType `json:"asset_type,omitempty"` + NotebookReview *notebookVersionReviewWire `json:"notebook_review,omitempty"` + JarAnalysisReview *jarAnalysisVersionReviewWire `json:"jar_analysis_review,omitempty"` +} + +func createCleanRoomAssetReviewRequestToWire(v *CreateCleanRoomAssetReviewRequest) (*createCleanRoomAssetReviewRequestWire, error) { + if v == nil { + return nil, nil + } + var reviewNotebookReviewWire *notebookVersionReviewWire + var reviewJarAnalysisReviewWire *jarAnalysisVersionReviewWire + switch value := v.Review.(type) { + case nil: + case *CreateCleanRoomAssetReviewRequest_Review_NotebookReview: + if value != nil { + reviewNotebookReviewConverted, err := notebookVersionReviewToWire(&value.NotebookReview) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCleanRoomAssetReviewRequest.Review.NotebookReview", err) + } + reviewNotebookReviewWire = reviewNotebookReviewConverted + } + case *CreateCleanRoomAssetReviewRequest_Review_JarAnalysisReview: + if value != nil { + reviewJarAnalysisReviewConverted, err := jarAnalysisVersionReviewToWire(&value.JarAnalysisReview) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCleanRoomAssetReviewRequest.Review.JarAnalysisReview", err) + } + reviewJarAnalysisReviewWire = reviewJarAnalysisReviewConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreateCleanRoomAssetReviewRequest.Review", value) + } + return &createCleanRoomAssetReviewRequestWire{ + CleanRoomName: v.CleanRoomName, + Name: v.Name, + AssetType: v.AssetType, + NotebookReview: reviewNotebookReviewWire, + JarAnalysisReview: reviewJarAnalysisReviewWire, + }, nil +} + +type createCleanRoomAssetReviewResponseWire struct { + NotebookReviews []cleanRoomNotebookReviewWire `json:"notebook_reviews,omitempty"` + JarAnalysisReviews []cleanRoomJarAnalysisReviewWire `json:"jar_analysis_reviews,omitempty"` + NotebookReviewState CleanRoomNotebookReview_NotebookReviewState `json:"notebook_review_state,omitempty"` + JarAnalysisReviewState CleanRoomJarAnalysisReview_JarAnalysisReviewState `json:"jar_analysis_review_state,omitempty"` +} + +func createCleanRoomAssetReviewResponseFromWire(w *createCleanRoomAssetReviewResponseWire) (*CreateCleanRoomAssetReviewResponse, error) { + if w == nil { + return nil, nil + } + reviewStateMembers := 0 + if w.NotebookReviewState != "" { + reviewStateMembers++ + } + if w.JarAnalysisReviewState != "" { + reviewStateMembers++ + } + if reviewStateMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "CreateCleanRoomAssetReviewResponse.ReviewState") + } + notebookReviewsPublicValue, err := convertSlice(w.NotebookReviews, cleanRoomNotebookReviewFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCleanRoomAssetReviewResponse.NotebookReviews", err) + } + jarAnalysisReviewsPublicValue, err := convertSlice(w.JarAnalysisReviews, cleanRoomJarAnalysisReviewFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCleanRoomAssetReviewResponse.JarAnalysisReviews", err) + } + var reviewStateSelection isCreateCleanRoomAssetReviewResponse_ReviewState + switch { + case w.NotebookReviewState != "": + reviewStateSelection = &CreateCleanRoomAssetReviewResponse_ReviewState_NotebookReviewState{NotebookReviewState: w.NotebookReviewState} + case w.JarAnalysisReviewState != "": + reviewStateSelection = &CreateCleanRoomAssetReviewResponse_ReviewState_JarAnalysisReviewState{JarAnalysisReviewState: w.JarAnalysisReviewState} + } + return &CreateCleanRoomAssetReviewResponse{ + NotebookReviews: notebookReviewsPublicValue, + JarAnalysisReviews: jarAnalysisReviewsPublicValue, + ReviewState: reviewStateSelection, + }, nil +} + +type createCleanRoomAutoApprovalRuleRequestWire struct { + AutoApprovalRule *cleanRoomAutoApprovalRuleWire `json:"auto_approval_rule,omitempty"` +} + +func createCleanRoomAutoApprovalRuleRequestToWire(v *CreateCleanRoomAutoApprovalRuleRequest) (*createCleanRoomAutoApprovalRuleRequestWire, error) { + if v == nil { + return nil, nil + } + autoApprovalRuleWireValue, err := cleanRoomAutoApprovalRuleToWire(v.AutoApprovalRule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCleanRoomAutoApprovalRuleRequest.AutoApprovalRule", err) + } + return &createCleanRoomAutoApprovalRuleRequestWire{ + AutoApprovalRule: autoApprovalRuleWireValue, + }, nil +} + +type createCleanRoomOutputCatalogRequestWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + OutputCatalog *cleanRoomOutputCatalogWire `json:"output_catalog,omitempty"` +} + +func createCleanRoomOutputCatalogRequestToWire(v *CreateCleanRoomOutputCatalogRequest) (*createCleanRoomOutputCatalogRequestWire, error) { + if v == nil { + return nil, nil + } + outputCatalogWireValue, err := cleanRoomOutputCatalogToWire(v.OutputCatalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCleanRoomOutputCatalogRequest.OutputCatalog", err) + } + return &createCleanRoomOutputCatalogRequestWire{ + CleanRoomName: v.CleanRoomName, + OutputCatalog: outputCatalogWireValue, + }, nil +} + +type createCleanRoomOutputCatalogResponseWire struct { + OutputCatalog *cleanRoomOutputCatalogWire `json:"output_catalog,omitempty"` +} + +func createCleanRoomOutputCatalogResponseFromWire(w *createCleanRoomOutputCatalogResponseWire) (*CreateCleanRoomOutputCatalogResponse, error) { + if w == nil { + return nil, nil + } + outputCatalogPublicValue, err := cleanRoomOutputCatalogFromWire(w.OutputCatalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCleanRoomOutputCatalogResponse.OutputCatalog", err) + } + return &CreateCleanRoomOutputCatalogResponse{ + OutputCatalog: outputCatalogPublicValue, + }, nil +} + +type createCleanRoomRequestWire struct { + CleanRoom *cleanRoomWire `json:"clean_room,omitempty"` +} + +func createCleanRoomRequestToWire(v *CreateCleanRoomRequest) (*createCleanRoomRequestWire, error) { + if v == nil { + return nil, nil + } + cleanRoomWireValue, err := cleanRoomToWire(v.CleanRoom) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCleanRoomRequest.CleanRoom", err) + } + return &createCleanRoomRequestWire{ + CleanRoom: cleanRoomWireValue, + }, nil +} + +type egressNetworkPolicyWire struct { + InternetAccess *egressNetworkPolicy_InternetAccessPolicyWire `json:"internet_access,omitempty"` +} + +func egressNetworkPolicyToWire(v *EgressNetworkPolicy) (*egressNetworkPolicyWire, error) { + if v == nil { + return nil, nil + } + internetAccessWireValue, err := egressNetworkPolicy_InternetAccessPolicyToWire(v.InternetAccess) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy.InternetAccess", err) + } + return &egressNetworkPolicyWire{ + InternetAccess: internetAccessWireValue, + }, nil +} + +func egressNetworkPolicyFromWire(w *egressNetworkPolicyWire) (*EgressNetworkPolicy, error) { + if w == nil { + return nil, nil + } + internetAccessPublicValue, err := egressNetworkPolicy_InternetAccessPolicyFromWire(w.InternetAccess) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy.InternetAccess", err) + } + return &EgressNetworkPolicy{ + InternetAccess: internetAccessPublicValue, + }, nil +} + +type egressNetworkPolicy_InternetAccessPolicyWire struct { + RestrictionMode EgressNetworkPolicy_InternetAccessPolicy_RestrictionMode `json:"restriction_mode,omitempty"` + AllowedInternetDestinations []egressNetworkPolicy_InternetAccessPolicy_InternetDestinationWire `json:"allowed_internet_destinations,omitempty"` + AllowedStorageDestinations []egressNetworkPolicy_InternetAccessPolicy_StorageDestinationWire `json:"allowed_storage_destinations,omitempty"` + LogOnlyMode *egressNetworkPolicy_InternetAccessPolicy_LogOnlyModeWire `json:"log_only_mode,omitempty"` +} + +func egressNetworkPolicy_InternetAccessPolicyToWire(v *EgressNetworkPolicy_InternetAccessPolicy) (*egressNetworkPolicy_InternetAccessPolicyWire, error) { + if v == nil { + return nil, nil + } + allowedInternetDestinationsWireValue, err := convertSlice(v.AllowedInternetDestinations, egressNetworkPolicy_InternetAccessPolicy_InternetDestinationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_InternetAccessPolicy.AllowedInternetDestinations", err) + } + allowedStorageDestinationsWireValue, err := convertSlice(v.AllowedStorageDestinations, egressNetworkPolicy_InternetAccessPolicy_StorageDestinationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_InternetAccessPolicy.AllowedStorageDestinations", err) + } + logOnlyModeWireValue, err := egressNetworkPolicy_InternetAccessPolicy_LogOnlyModeToWire(v.LogOnlyMode) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_InternetAccessPolicy.LogOnlyMode", err) + } + return &egressNetworkPolicy_InternetAccessPolicyWire{ + RestrictionMode: v.RestrictionMode, + AllowedInternetDestinations: allowedInternetDestinationsWireValue, + AllowedStorageDestinations: allowedStorageDestinationsWireValue, + LogOnlyMode: logOnlyModeWireValue, + }, nil +} + +func egressNetworkPolicy_InternetAccessPolicyFromWire(w *egressNetworkPolicy_InternetAccessPolicyWire) (*EgressNetworkPolicy_InternetAccessPolicy, error) { + if w == nil { + return nil, nil + } + allowedInternetDestinationsPublicValue, err := convertSlice(w.AllowedInternetDestinations, egressNetworkPolicy_InternetAccessPolicy_InternetDestinationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_InternetAccessPolicy.AllowedInternetDestinations", err) + } + allowedStorageDestinationsPublicValue, err := convertSlice(w.AllowedStorageDestinations, egressNetworkPolicy_InternetAccessPolicy_StorageDestinationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_InternetAccessPolicy.AllowedStorageDestinations", err) + } + logOnlyModePublicValue, err := egressNetworkPolicy_InternetAccessPolicy_LogOnlyModeFromWire(w.LogOnlyMode) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_InternetAccessPolicy.LogOnlyMode", err) + } + return &EgressNetworkPolicy_InternetAccessPolicy{ + RestrictionMode: w.RestrictionMode, + AllowedInternetDestinations: allowedInternetDestinationsPublicValue, + AllowedStorageDestinations: allowedStorageDestinationsPublicValue, + LogOnlyMode: logOnlyModePublicValue, + }, nil +} + +type egressNetworkPolicy_InternetAccessPolicy_InternetDestinationWire struct { + Destination *string `json:"destination,omitempty"` + Type EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationType `json:"type,omitempty"` + Protocol EgressNetworkPolicy_InternetAccessPolicy_InternetDestination_InternetDestinationFilteringProtocol `json:"protocol,omitempty"` +} + +func egressNetworkPolicy_InternetAccessPolicy_InternetDestinationToWire(v *EgressNetworkPolicy_InternetAccessPolicy_InternetDestination) (*egressNetworkPolicy_InternetAccessPolicy_InternetDestinationWire, error) { + if v == nil { + return nil, nil + } + return &egressNetworkPolicy_InternetAccessPolicy_InternetDestinationWire{ + Destination: v.Destination, + Type: v.Type, + Protocol: v.Protocol, + }, nil +} + +func egressNetworkPolicy_InternetAccessPolicy_InternetDestinationFromWire(w *egressNetworkPolicy_InternetAccessPolicy_InternetDestinationWire) (*EgressNetworkPolicy_InternetAccessPolicy_InternetDestination, error) { + if w == nil { + return nil, nil + } + return &EgressNetworkPolicy_InternetAccessPolicy_InternetDestination{ + Destination: w.Destination, + Type: w.Type, + Protocol: w.Protocol, + }, nil +} + +type egressNetworkPolicy_InternetAccessPolicy_LogOnlyModeWire struct { + LogOnlyModeType EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_LogOnlyModeType `json:"log_only_mode_type,omitempty"` + Workloads []EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode_WorkloadType `json:"workloads,omitempty"` +} + +func egressNetworkPolicy_InternetAccessPolicy_LogOnlyModeToWire(v *EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode) (*egressNetworkPolicy_InternetAccessPolicy_LogOnlyModeWire, error) { + if v == nil { + return nil, nil + } + return &egressNetworkPolicy_InternetAccessPolicy_LogOnlyModeWire{ + LogOnlyModeType: v.LogOnlyModeType, + Workloads: v.Workloads, + }, nil +} + +func egressNetworkPolicy_InternetAccessPolicy_LogOnlyModeFromWire(w *egressNetworkPolicy_InternetAccessPolicy_LogOnlyModeWire) (*EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode, error) { + if w == nil { + return nil, nil + } + return &EgressNetworkPolicy_InternetAccessPolicy_LogOnlyMode{ + LogOnlyModeType: w.LogOnlyModeType, + Workloads: w.Workloads, + }, nil +} + +type egressNetworkPolicy_InternetAccessPolicy_StorageDestinationWire struct { + BucketName *string `json:"bucket_name,omitempty"` + Region *string `json:"region,omitempty"` + Type EgressNetworkPolicy_InternetAccessPolicy_StorageDestination_StorageDestinationType `json:"type,omitempty"` + AzureStorageAccount *string `json:"azure_storage_account,omitempty"` + AllowedPaths []string `json:"allowed_paths,omitempty"` + AzureStorageService *string `json:"azure_storage_service,omitempty"` + AzureDnsZone *string `json:"azure_dns_zone,omitempty"` + AzureContainer *string `json:"azure_container,omitempty"` +} + +func egressNetworkPolicy_InternetAccessPolicy_StorageDestinationToWire(v *EgressNetworkPolicy_InternetAccessPolicy_StorageDestination) (*egressNetworkPolicy_InternetAccessPolicy_StorageDestinationWire, error) { + if v == nil { + return nil, nil + } + return &egressNetworkPolicy_InternetAccessPolicy_StorageDestinationWire{ + BucketName: v.BucketName, + Region: v.Region, + Type: v.Type, + AzureStorageAccount: v.AzureStorageAccount, + AllowedPaths: v.AllowedPaths, + AzureStorageService: v.AzureStorageService, + AzureDnsZone: v.AzureDnsZone, + AzureContainer: v.AzureContainer, + }, nil +} + +func egressNetworkPolicy_InternetAccessPolicy_StorageDestinationFromWire(w *egressNetworkPolicy_InternetAccessPolicy_StorageDestinationWire) (*EgressNetworkPolicy_InternetAccessPolicy_StorageDestination, error) { + if w == nil { + return nil, nil + } + return &EgressNetworkPolicy_InternetAccessPolicy_StorageDestination{ + BucketName: w.BucketName, + Region: w.Region, + Type: w.Type, + AzureStorageAccount: w.AzureStorageAccount, + AllowedPaths: w.AllowedPaths, + AzureStorageService: w.AzureStorageService, + AzureDnsZone: w.AzureDnsZone, + AzureContainer: w.AzureContainer, + }, nil +} + +type jarAnalysisVersionReviewWire struct { + Etag *string `json:"etag,omitempty"` + ReviewState CleanRoomJarAnalysisReview_JarAnalysisReviewState `json:"review_state,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func jarAnalysisVersionReviewToWire(v *JarAnalysisVersionReview) (*jarAnalysisVersionReviewWire, error) { + if v == nil { + return nil, nil + } + return &jarAnalysisVersionReviewWire{ + Etag: v.Etag, + ReviewState: v.ReviewState, + Comment: v.Comment, + }, nil +} + +type listCleanRoomAssetRevisionsRequestWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + Name *string `json:"name,omitempty"` + AssetType CleanRoomAsset_AssetType `json:"asset_type,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listCleanRoomAssetRevisionsRequestToWire(v *ListCleanRoomAssetRevisionsRequest) (*listCleanRoomAssetRevisionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCleanRoomAssetRevisionsRequestWire{ + CleanRoomName: v.CleanRoomName, + Name: v.Name, + AssetType: v.AssetType, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listCleanRoomAssetRevisionsResponseWire struct { + Revisions []cleanRoomAssetWire `json:"revisions,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCleanRoomAssetRevisionsResponseFromWire(w *listCleanRoomAssetRevisionsResponseWire) (*ListCleanRoomAssetRevisionsResponse, error) { + if w == nil { + return nil, nil + } + revisionsPublicValue, err := convertSlice(w.Revisions, cleanRoomAssetFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCleanRoomAssetRevisionsResponse.Revisions", err) + } + return &ListCleanRoomAssetRevisionsResponse{ + Revisions: revisionsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listCleanRoomAssetsRequestWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listCleanRoomAssetsRequestToWire(v *ListCleanRoomAssetsRequest) (*listCleanRoomAssetsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCleanRoomAssetsRequestWire{ + CleanRoomName: v.CleanRoomName, + PageToken: v.PageToken, + }, nil +} + +type listCleanRoomAssetsResponseWire struct { + Assets []cleanRoomAssetWire `json:"assets,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCleanRoomAssetsResponseFromWire(w *listCleanRoomAssetsResponseWire) (*ListCleanRoomAssetsResponse, error) { + if w == nil { + return nil, nil + } + assetsPublicValue, err := convertSlice(w.Assets, cleanRoomAssetFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCleanRoomAssetsResponse.Assets", err) + } + return &ListCleanRoomAssetsResponse{ + Assets: assetsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listCleanRoomAutoApprovalRulesRequestWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listCleanRoomAutoApprovalRulesRequestToWire(v *ListCleanRoomAutoApprovalRulesRequest) (*listCleanRoomAutoApprovalRulesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCleanRoomAutoApprovalRulesRequestWire{ + CleanRoomName: v.CleanRoomName, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listCleanRoomAutoApprovalRulesResponseWire struct { + Rules []cleanRoomAutoApprovalRuleWire `json:"rules,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCleanRoomAutoApprovalRulesResponseFromWire(w *listCleanRoomAutoApprovalRulesResponseWire) (*ListCleanRoomAutoApprovalRulesResponse, error) { + if w == nil { + return nil, nil + } + rulesPublicValue, err := convertSlice(w.Rules, cleanRoomAutoApprovalRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCleanRoomAutoApprovalRulesResponse.Rules", err) + } + return &ListCleanRoomAutoApprovalRulesResponse{ + Rules: rulesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listCleanRoomNotebookTaskRunsRequestWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + NotebookName *string `json:"notebook_name,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listCleanRoomNotebookTaskRunsRequestToWire(v *ListCleanRoomNotebookTaskRunsRequest) (*listCleanRoomNotebookTaskRunsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCleanRoomNotebookTaskRunsRequestWire{ + CleanRoomName: v.CleanRoomName, + NotebookName: v.NotebookName, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listCleanRoomNotebookTaskRunsResponseWire struct { + Runs []cleanRoomNotebookTaskRunWire `json:"runs,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCleanRoomNotebookTaskRunsResponseFromWire(w *listCleanRoomNotebookTaskRunsResponseWire) (*ListCleanRoomNotebookTaskRunsResponse, error) { + if w == nil { + return nil, nil + } + runsPublicValue, err := convertSlice(w.Runs, cleanRoomNotebookTaskRunFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCleanRoomNotebookTaskRunsResponse.Runs", err) + } + return &ListCleanRoomNotebookTaskRunsResponse{ + Runs: runsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listCleanRoomTaskRunsRequestWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + Name *string `json:"name,omitempty"` + TaskType CleanRoomTaskType `json:"task_type,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listCleanRoomTaskRunsRequestToWire(v *ListCleanRoomTaskRunsRequest) (*listCleanRoomTaskRunsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCleanRoomTaskRunsRequestWire{ + CleanRoomName: v.CleanRoomName, + Name: v.Name, + TaskType: v.TaskType, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listCleanRoomTaskRunsResponseWire struct { + Runs []cleanRoomTaskRunWire `json:"runs,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCleanRoomTaskRunsResponseFromWire(w *listCleanRoomTaskRunsResponseWire) (*ListCleanRoomTaskRunsResponse, error) { + if w == nil { + return nil, nil + } + runsPublicValue, err := convertSlice(w.Runs, cleanRoomTaskRunFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCleanRoomTaskRunsResponse.Runs", err) + } + return &ListCleanRoomTaskRunsResponse{ + Runs: runsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listCleanRoomsRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listCleanRoomsRequestToWire(v *ListCleanRoomsRequest) (*listCleanRoomsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCleanRoomsRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listCleanRoomsResponseWire struct { + CleanRooms []cleanRoomWire `json:"clean_rooms,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCleanRoomsResponseFromWire(w *listCleanRoomsResponseWire) (*ListCleanRoomsResponse, error) { + if w == nil { + return nil, nil + } + cleanRoomsPublicValue, err := convertSlice(w.CleanRooms, cleanRoomFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCleanRoomsResponse.CleanRooms", err) + } + return &ListCleanRoomsResponse{ + CleanRooms: cleanRoomsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type notebookVersionReviewWire struct { + Etag *string `json:"etag,omitempty"` + ReviewState CleanRoomNotebookReview_NotebookReviewState `json:"review_state,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func notebookVersionReviewToWire(v *NotebookVersionReview) (*notebookVersionReviewWire, error) { + if v == nil { + return nil, nil + } + return ¬ebookVersionReviewWire{ + Etag: v.Etag, + ReviewState: v.ReviewState, + Comment: v.Comment, + }, nil +} + +type partitionSpecification_PartitionWire struct { + Values []partitionSpecification_Partition_PartitionValueWire `json:"values,omitempty"` +} + +func partitionSpecification_PartitionToWire(v *PartitionSpecification_Partition) (*partitionSpecification_PartitionWire, error) { + if v == nil { + return nil, nil + } + valuesWireValue, err := convertSlice(v.Values, partitionSpecification_Partition_PartitionValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PartitionSpecification_Partition.Values", err) + } + return &partitionSpecification_PartitionWire{ + Values: valuesWireValue, + }, nil +} + +func partitionSpecification_PartitionFromWire(w *partitionSpecification_PartitionWire) (*PartitionSpecification_Partition, error) { + if w == nil { + return nil, nil + } + valuesPublicValue, err := convertSlice(w.Values, partitionSpecification_Partition_PartitionValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PartitionSpecification_Partition.Values", err) + } + return &PartitionSpecification_Partition{ + Values: valuesPublicValue, + }, nil +} + +type partitionSpecification_Partition_PartitionValueWire struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` + RecipientPropertyKey *string `json:"recipient_property_key,omitempty"` + Op PartitionSpecification_Partition_PartitionValue_PartitionValueOp `json:"op,omitempty"` +} + +func partitionSpecification_Partition_PartitionValueToWire(v *PartitionSpecification_Partition_PartitionValue) (*partitionSpecification_Partition_PartitionValueWire, error) { + if v == nil { + return nil, nil + } + return &partitionSpecification_Partition_PartitionValueWire{ + Name: v.Name, + Value: v.Value, + RecipientPropertyKey: v.RecipientPropertyKey, + Op: v.Op, + }, nil +} + +func partitionSpecification_Partition_PartitionValueFromWire(w *partitionSpecification_Partition_PartitionValueWire) (*PartitionSpecification_Partition_PartitionValue, error) { + if w == nil { + return nil, nil + } + return &PartitionSpecification_Partition_PartitionValue{ + Name: w.Name, + Value: w.Value, + RecipientPropertyKey: w.RecipientPropertyKey, + Op: w.Op, + }, nil +} + +type policyFunctionArgumentWire struct { + Column *string `json:"column,omitempty"` + Constant *string `json:"constant,omitempty"` +} + +func policyFunctionArgumentToWire(v *PolicyFunctionArgument) (*policyFunctionArgumentWire, error) { + if v == nil { + return nil, nil + } + var argColumnWire *string + var argConstantWire *string + switch value := v.Arg.(type) { + case nil: + case *PolicyFunctionArgument_Arg_Column: + if value != nil { + argColumnWire = new(value.Column) + } + case *PolicyFunctionArgument_Arg_Constant: + if value != nil { + argConstantWire = new(value.Constant) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "PolicyFunctionArgument.Arg", value) + } + return &policyFunctionArgumentWire{ + Column: argColumnWire, + Constant: argConstantWire, + }, nil +} + +func policyFunctionArgumentFromWire(w *policyFunctionArgumentWire) (*PolicyFunctionArgument, error) { + if w == nil { + return nil, nil + } + argMembers := 0 + if w.Column != nil { + argMembers++ + } + if w.Constant != nil { + argMembers++ + } + if argMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PolicyFunctionArgument.Arg") + } + var argSelection isPolicyFunctionArgument_Arg + switch { + case w.Column != nil: + argSelection = &PolicyFunctionArgument_Arg_Column{Column: *w.Column} + case w.Constant != nil: + argSelection = &PolicyFunctionArgument_Arg_Constant{Constant: *w.Constant} + } + return &PolicyFunctionArgument{ + Arg: argSelection, + }, nil +} + +type updateCleanRoomAssetRequestWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + Asset *cleanRoomAssetWire `json:"asset,omitempty"` +} + +func updateCleanRoomAssetRequestToWire(v *UpdateCleanRoomAssetRequest) (*updateCleanRoomAssetRequestWire, error) { + if v == nil { + return nil, nil + } + assetWireValue, err := cleanRoomAssetToWire(v.Asset) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCleanRoomAssetRequest.Asset", err) + } + return &updateCleanRoomAssetRequestWire{ + CleanRoomName: v.CleanRoomName, + Asset: assetWireValue, + }, nil +} + +type updateCleanRoomAutoApprovalRuleRequestWire struct { + AutoApprovalRule *cleanRoomAutoApprovalRuleWire `json:"auto_approval_rule,omitempty"` +} + +func updateCleanRoomAutoApprovalRuleRequestToWire(v *UpdateCleanRoomAutoApprovalRuleRequest) (*updateCleanRoomAutoApprovalRuleRequestWire, error) { + if v == nil { + return nil, nil + } + autoApprovalRuleWireValue, err := cleanRoomAutoApprovalRuleToWire(v.AutoApprovalRule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCleanRoomAutoApprovalRuleRequest.AutoApprovalRule", err) + } + return &updateCleanRoomAutoApprovalRuleRequestWire{ + AutoApprovalRule: autoApprovalRuleWireValue, + }, nil +} + +type updateCleanRoomRequestWire struct { + Name *string `json:"name,omitempty"` + CleanRoom *cleanRoomWire `json:"clean_room,omitempty"` +} + +func updateCleanRoomRequestToWire(v *UpdateCleanRoomRequest) (*updateCleanRoomRequestWire, error) { + if v == nil { + return nil, nil + } + cleanRoomWireValue, err := cleanRoomToWire(v.CleanRoom) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCleanRoomRequest.CleanRoom", err) + } + return &updateCleanRoomRequestWire{ + Name: v.Name, + CleanRoom: cleanRoomWireValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/clusterlibraries/.package.json b/clusterlibraries/.package.json new file mode 100644 index 0000000..529329c --- /dev/null +++ b/clusterlibraries/.package.json @@ -0,0 +1,3 @@ +{ + "package": "clusterlibraries" +} diff --git a/clusterlibraries/CHANGELOG.md b/clusterlibraries/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/clusterlibraries/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/clusterlibraries/README.md b/clusterlibraries/README.md new file mode 100644 index 0000000..fa1aa34 --- /dev/null +++ b/clusterlibraries/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/clusterlibraries + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/clusterlibraries@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/clusterlibraries/v2" + +client, err := clusterlibraries.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/clusterlibraries/go.mod b/clusterlibraries/go.mod new file mode 100644 index 0000000..e3ec4b3 --- /dev/null +++ b/clusterlibraries/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/clusterlibraries + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/clusterlibraries/internal/version.go b/clusterlibraries/internal/version.go new file mode 100644 index 0000000..1996c7b --- /dev/null +++ b/clusterlibraries/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-clusterlibraries" + +const Version = "0.0.1-dev.1" diff --git a/clusterlibraries/v2/client.go b/clusterlibraries/v2/client.go new file mode 100755 index 0000000..ac839c3 --- /dev/null +++ b/clusterlibraries/v2/client.go @@ -0,0 +1,325 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusterlibraries + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/clusterlibraries/internal" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Get the status of all libraries on all clusters. A status is returned for all +// libraries installed on this cluster via the API or the libraries UI. +func (c *internalClient) AllClusterStatuses(ctx context.Context, req *ListAllClusterLibraryStatusesRequest, opts ...call.Option) (*ListAllClusterLibraryStatusesResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/libraries/all-cluster-statuses" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAllClusterLibraryStatusesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAllClusterLibraryStatusesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAllClusterLibraryStatusesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get the status of libraries on a cluster. A status is returned for all +// libraries installed on this cluster via the API or the libraries UI. The +// order of returned libraries is as follows: 1. Libraries set to be installed +// on this cluster, in the order that the libraries were added to the cluster, +// are returned first. 2. Libraries that were previously requested to be +// installed on this cluster or, but are now marked for removal, in no +// particular order, are returned last. +func (c *internalClient) ClusterStatus(ctx context.Context, req *ClusterStatusRequest, opts ...call.Option) (*ClusterLibraryStatuses, error) { + wireReq, err := clusterStatusRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/libraries/cluster-status" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "cluster_id", wireReq.ClusterId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ClusterLibraryStatuses + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp clusterLibraryStatusesWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = clusterLibraryStatusesFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Add libraries to install on a cluster. The installation is asynchronous; it +// happens in the background after the completion of this request. +func (c *internalClient) InstallLibraries(ctx context.Context, req *InstallLibrariesRequest, opts ...call.Option) (*InstallLibrariesResponse, error) { + wireReq, err := installLibrariesRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/libraries/install" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *InstallLibrariesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &InstallLibrariesResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Set libraries to uninstall from a cluster. The libraries won't be uninstalled +// until the cluster is restarted. A request to uninstall a library that is not +// currently installed is ignored. +func (c *internalClient) UninstallLibraries(ctx context.Context, req *UninstallLibrariesRequest, opts ...call.Option) (*UninstallLibrariesResponse, error) { + wireReq, err := uninstallLibrariesRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/libraries/uninstall" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UninstallLibrariesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UninstallLibrariesResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/clusterlibraries/v2/genhelper.go b/clusterlibraries/v2/genhelper.go new file mode 100755 index 0000000..78ecd99 --- /dev/null +++ b/clusterlibraries/v2/genhelper.go @@ -0,0 +1,178 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusterlibraries + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} diff --git a/clusterlibraries/v2/model.go b/clusterlibraries/v2/model.go new file mode 100755 index 0000000..a6f6f2c --- /dev/null +++ b/clusterlibraries/v2/model.go @@ -0,0 +1,199 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusterlibraries + +// The status of a library on a specific cluster. +type LibraryInstallStatus string + +const ( + LibraryInstallStatus_Unspecified LibraryInstallStatus = "" + // Metadata necessary to install the library is being retrieved from the + // provided repository. + // + // For jar and egg libraries, this step is a no-op. + LibraryInstallStatus_Resolving LibraryInstallStatus = "RESOLVING" + // The library is actively being installed, either by adding resources to Spark + // or executing system commands inside the Spark nodes. + LibraryInstallStatus_Installing LibraryInstallStatus = "INSTALLING" + // The library has been successfully installed and can now be used. + LibraryInstallStatus_Installed LibraryInstallStatus = "INSTALLED" + // Some step in installation failed. More information can be found in the + // `messages` field. + LibraryInstallStatus_Failed LibraryInstallStatus = "FAILED" + // The library has been marked for removal. Currently, libraries can only be + // removed when clusters are restarted, so libraries that enter this state will + // remain until the cluster is restarted. + LibraryInstallStatus_UninstallOnRestart LibraryInstallStatus = "UNINSTALL_ON_RESTART" + // Indicates that Library Manager decided to skip installation for this library. + // For example, shared libraries on DBR 7+ are skipped. + LibraryInstallStatus_Skipped LibraryInstallStatus = "SKIPPED" + // Library installation is restored and can be used. + LibraryInstallStatus_Restored LibraryInstallStatus = "RESTORED" +) + +type ClusterLibraryStatuses struct { + // Unique identifier for the cluster. + ClusterId *string + // Status of all libraries on the cluster. + LibraryStatuses []LibraryFullStatus +} + +type ClusterStatusRequest struct { + // Unique identifier of the cluster whose status should be retrieved. + ClusterId *string +} + +type InstallLibrariesRequest struct { + // Unique identifier for the cluster on which to install these libraries. + ClusterId *string + // The libraries to install. + Libraries []Library +} + +type InstallLibrariesResponse struct { +} + +type Library struct { + Lib isLibrary_Lib +} + +type isLibrary_Lib interface { + isLibrary_Lib() +} + +// Library_Lib_Jar selects Jar for Library.Lib. +// URI of the JAR library to install. Supported URIs include Workspace paths, +// Unity Catalog Volumes paths, and S3 URIs. For example: `{ "jar": +// "/Workspace/path/to/library.jar" }`, `{ "jar" : +// "/Volumes/path/to/library.jar" }` or `{ "jar": "s3://my-bucket/library.jar" +// }`. If S3 is used, please make sure the cluster has read access on the +// library. You may need to launch the cluster with an IAM role to access the S3 +// URI. +type Library_Lib_Jar struct { + Jar string +} + +func (*Library_Lib_Jar) isLibrary_Lib() {} + +// Library_Lib_Egg selects Egg for Library.Lib. +// Deprecated. URI of the egg library to install. Installing Python egg files is +// deprecated and is not supported in Databricks Runtime 14.0 and above. +type Library_Lib_Egg struct { + Egg string +} + +func (*Library_Lib_Egg) isLibrary_Lib() {} + +// Library_Lib_Pypi selects Pypi for Library.Lib. +// Specification of a PyPi library to be installed. For example: `{ "package": +// "simplejson" }` +type Library_Lib_Pypi struct { + Pypi PythonPyPiLibrary +} + +func (*Library_Lib_Pypi) isLibrary_Lib() {} + +// Library_Lib_Maven selects Maven for Library.Lib. +// Specification of a maven library to be installed. For example: `{ +// "coordinates": "org.jsoup:jsoup:1.7.2" }` +type Library_Lib_Maven struct { + Maven MavenLibrary +} + +func (*Library_Lib_Maven) isLibrary_Lib() {} + +// Library_Lib_Cran selects Cran for Library.Lib. +// Specification of a CRAN library to be installed as part of the library +type Library_Lib_Cran struct { + Cran RCranLibrary +} + +func (*Library_Lib_Cran) isLibrary_Lib() {} + +// Library_Lib_Whl selects Whl for Library.Lib. +// URI of the wheel library to install. Supported URIs include Workspace paths, +// Unity Catalog Volumes paths, and S3 URIs. For example: `{ "whl": +// "/Workspace/path/to/library.whl" }`, `{ "whl" : +// "/Volumes/path/to/library.whl" }` or `{ "whl": "s3://my-bucket/library.whl" +// }`. If S3 is used, please make sure the cluster has read access on the +// library. You may need to launch the cluster with an IAM role to access the S3 +// URI. +type Library_Lib_Whl struct { + Whl string +} + +func (*Library_Lib_Whl) isLibrary_Lib() {} + +// Library_Lib_Requirements selects Requirements for Library.Lib. +// URI of the requirements.txt file to install. Only Workspace paths and Unity +// Catalog Volumes paths are supported. For example: `{ "requirements": +// "/Workspace/path/to/requirements.txt" }` or `{ "requirements" : +// "/Volumes/path/to/requirements.txt" }` +type Library_Lib_Requirements struct { + Requirements string +} + +func (*Library_Lib_Requirements) isLibrary_Lib() {} + +// The status of the library on a specific cluster.. +type LibraryFullStatus struct { + // Unique identifier for the library. + Library *Library + // Status of installing the library on the cluster. + Status LibraryInstallStatus + // All the info and warning messages that have occurred so far for this library. + Messages []string + // Whether the library was set to be installed on all clusters via the libraries + // UI. + IsLibraryForAllClusters *bool +} + +type ListAllClusterLibraryStatusesRequest struct { +} + +type ListAllClusterLibraryStatusesResponse struct { + // A list of cluster statuses. + Statuses []ClusterLibraryStatuses +} + +type MavenLibrary struct { + // Gradle-style maven coordinates. For example: "org.jsoup:jsoup:1.7.2". + Coordinates *string + // Maven repo to install the Maven package from. If omitted, both Maven Central + // Repository and Spark Packages are searched. + Repo *string + // List of dependences to exclude. For example: `["slf4j:slf4j", + // "*:hadoop-client"]`. + // + // Maven dependency exclusions: + // https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html. + Exclusions []string +} + +type PythonPyPiLibrary struct { + // The name of the pypi package to install. An optional exact version + // specification is also supported. Examples: "simplejson" and + // "simplejson==3.8.0". + Package *string + // The repository where the package can be found. If not specified, the default + // pip index is used. + Repo *string +} + +type RCranLibrary struct { + // The name of the CRAN package to install. + Package *string + // The repository where the package can be found. If not specified, the default + // CRAN repo is used. + Repo *string +} + +type UninstallLibrariesRequest struct { + // Unique identifier for the cluster on which to uninstall these libraries. + ClusterId *string + // The libraries to uninstall. + Libraries []Library +} + +type UninstallLibrariesResponse struct { +} diff --git a/clusterlibraries/v2/wire.go b/clusterlibraries/v2/wire.go new file mode 100755 index 0000000..0ad867e --- /dev/null +++ b/clusterlibraries/v2/wire.go @@ -0,0 +1,350 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusterlibraries + +import ( + "fmt" +) + +type clusterLibraryStatusesWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + LibraryStatuses []libraryFullStatusWire `json:"library_statuses,omitempty"` +} + +func clusterLibraryStatusesFromWire(w *clusterLibraryStatusesWire) (*ClusterLibraryStatuses, error) { + if w == nil { + return nil, nil + } + libraryStatusesPublicValue, err := convertSlice(w.LibraryStatuses, libraryFullStatusFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLibraryStatuses.LibraryStatuses", err) + } + return &ClusterLibraryStatuses{ + ClusterId: w.ClusterId, + LibraryStatuses: libraryStatusesPublicValue, + }, nil +} + +type clusterStatusRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` +} + +func clusterStatusRequestToWire(v *ClusterStatusRequest) (*clusterStatusRequestWire, error) { + if v == nil { + return nil, nil + } + return &clusterStatusRequestWire{ + ClusterId: v.ClusterId, + }, nil +} + +type installLibrariesRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + Libraries []libraryWire `json:"libraries,omitempty"` +} + +func installLibrariesRequestToWire(v *InstallLibrariesRequest) (*installLibrariesRequestWire, error) { + if v == nil { + return nil, nil + } + librariesWireValue, err := convertSlice(v.Libraries, libraryToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstallLibrariesRequest.Libraries", err) + } + return &installLibrariesRequestWire{ + ClusterId: v.ClusterId, + Libraries: librariesWireValue, + }, nil +} + +type libraryWire struct { + Jar *string `json:"jar,omitempty"` + Egg *string `json:"egg,omitempty"` + Pypi *pythonPyPiLibraryWire `json:"pypi,omitempty"` + Maven *mavenLibraryWire `json:"maven,omitempty"` + Cran *rCranLibraryWire `json:"cran,omitempty"` + Whl *string `json:"whl,omitempty"` + Requirements *string `json:"requirements,omitempty"` +} + +func libraryToWire(v *Library) (*libraryWire, error) { + if v == nil { + return nil, nil + } + var libJarWire *string + var libEggWire *string + var libPypiWire *pythonPyPiLibraryWire + var libMavenWire *mavenLibraryWire + var libCranWire *rCranLibraryWire + var libWhlWire *string + var libRequirementsWire *string + switch value := v.Lib.(type) { + case nil: + case *Library_Lib_Jar: + if value != nil { + libJarWire = new(value.Jar) + } + case *Library_Lib_Egg: + if value != nil { + libEggWire = new(value.Egg) + } + case *Library_Lib_Pypi: + if value != nil { + libPypiConverted, err := pythonPyPiLibraryToWire(&value.Pypi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Pypi", err) + } + libPypiWire = libPypiConverted + } + case *Library_Lib_Maven: + if value != nil { + libMavenConverted, err := mavenLibraryToWire(&value.Maven) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Maven", err) + } + libMavenWire = libMavenConverted + } + case *Library_Lib_Cran: + if value != nil { + libCranConverted, err := rCranLibraryToWire(&value.Cran) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Cran", err) + } + libCranWire = libCranConverted + } + case *Library_Lib_Whl: + if value != nil { + libWhlWire = new(value.Whl) + } + case *Library_Lib_Requirements: + if value != nil { + libRequirementsWire = new(value.Requirements) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Library.Lib", value) + } + return &libraryWire{ + Jar: libJarWire, + Egg: libEggWire, + Pypi: libPypiWire, + Maven: libMavenWire, + Cran: libCranWire, + Whl: libWhlWire, + Requirements: libRequirementsWire, + }, nil +} + +func libraryFromWire(w *libraryWire) (*Library, error) { + if w == nil { + return nil, nil + } + libMembers := 0 + if w.Jar != nil { + libMembers++ + } + if w.Egg != nil { + libMembers++ + } + if w.Pypi != nil { + libMembers++ + } + if w.Maven != nil { + libMembers++ + } + if w.Cran != nil { + libMembers++ + } + if w.Whl != nil { + libMembers++ + } + if w.Requirements != nil { + libMembers++ + } + if libMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Library.Lib") + } + var libSelection isLibrary_Lib + switch { + case w.Jar != nil: + libSelection = &Library_Lib_Jar{Jar: *w.Jar} + case w.Egg != nil: + libSelection = &Library_Lib_Egg{Egg: *w.Egg} + case w.Pypi != nil: + libPypiConverted, err := pythonPyPiLibraryFromWire(w.Pypi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Pypi", err) + } + libSelection = &Library_Lib_Pypi{Pypi: *libPypiConverted} + case w.Maven != nil: + libMavenConverted, err := mavenLibraryFromWire(w.Maven) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Maven", err) + } + libSelection = &Library_Lib_Maven{Maven: *libMavenConverted} + case w.Cran != nil: + libCranConverted, err := rCranLibraryFromWire(w.Cran) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Cran", err) + } + libSelection = &Library_Lib_Cran{Cran: *libCranConverted} + case w.Whl != nil: + libSelection = &Library_Lib_Whl{Whl: *w.Whl} + case w.Requirements != nil: + libSelection = &Library_Lib_Requirements{Requirements: *w.Requirements} + } + return &Library{ + Lib: libSelection, + }, nil +} + +type libraryFullStatusWire struct { + Library *libraryWire `json:"library,omitempty"` + Status LibraryInstallStatus `json:"status,omitempty"` + Messages []string `json:"messages,omitempty"` + IsLibraryForAllClusters *bool `json:"is_library_for_all_clusters,omitempty"` +} + +func libraryFullStatusFromWire(w *libraryFullStatusWire) (*LibraryFullStatus, error) { + if w == nil { + return nil, nil + } + libraryPublicValue, err := libraryFromWire(w.Library) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LibraryFullStatus.Library", err) + } + return &LibraryFullStatus{ + Library: libraryPublicValue, + Status: w.Status, + Messages: w.Messages, + IsLibraryForAllClusters: w.IsLibraryForAllClusters, + }, nil +} + +type listAllClusterLibraryStatusesResponseWire struct { + Statuses []clusterLibraryStatusesWire `json:"statuses,omitempty"` +} + +func listAllClusterLibraryStatusesResponseFromWire(w *listAllClusterLibraryStatusesResponseWire) (*ListAllClusterLibraryStatusesResponse, error) { + if w == nil { + return nil, nil + } + statusesPublicValue, err := convertSlice(w.Statuses, clusterLibraryStatusesFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAllClusterLibraryStatusesResponse.Statuses", err) + } + return &ListAllClusterLibraryStatusesResponse{ + Statuses: statusesPublicValue, + }, nil +} + +type mavenLibraryWire struct { + Coordinates *string `json:"coordinates,omitempty"` + Repo *string `json:"repo,omitempty"` + Exclusions []string `json:"exclusions,omitempty"` +} + +func mavenLibraryToWire(v *MavenLibrary) (*mavenLibraryWire, error) { + if v == nil { + return nil, nil + } + return &mavenLibraryWire{ + Coordinates: v.Coordinates, + Repo: v.Repo, + Exclusions: v.Exclusions, + }, nil +} + +func mavenLibraryFromWire(w *mavenLibraryWire) (*MavenLibrary, error) { + if w == nil { + return nil, nil + } + return &MavenLibrary{ + Coordinates: w.Coordinates, + Repo: w.Repo, + Exclusions: w.Exclusions, + }, nil +} + +type pythonPyPiLibraryWire struct { + Package *string `json:"package,omitempty"` + Repo *string `json:"repo,omitempty"` +} + +func pythonPyPiLibraryToWire(v *PythonPyPiLibrary) (*pythonPyPiLibraryWire, error) { + if v == nil { + return nil, nil + } + return &pythonPyPiLibraryWire{ + Package: v.Package, + Repo: v.Repo, + }, nil +} + +func pythonPyPiLibraryFromWire(w *pythonPyPiLibraryWire) (*PythonPyPiLibrary, error) { + if w == nil { + return nil, nil + } + return &PythonPyPiLibrary{ + Package: w.Package, + Repo: w.Repo, + }, nil +} + +type rCranLibraryWire struct { + Package *string `json:"package,omitempty"` + Repo *string `json:"repo,omitempty"` +} + +func rCranLibraryToWire(v *RCranLibrary) (*rCranLibraryWire, error) { + if v == nil { + return nil, nil + } + return &rCranLibraryWire{ + Package: v.Package, + Repo: v.Repo, + }, nil +} + +func rCranLibraryFromWire(w *rCranLibraryWire) (*RCranLibrary, error) { + if w == nil { + return nil, nil + } + return &RCranLibrary{ + Package: w.Package, + Repo: w.Repo, + }, nil +} + +type uninstallLibrariesRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + Libraries []libraryWire `json:"libraries,omitempty"` +} + +func uninstallLibrariesRequestToWire(v *UninstallLibrariesRequest) (*uninstallLibrariesRequestWire, error) { + if v == nil { + return nil, nil + } + librariesWireValue, err := convertSlice(v.Libraries, libraryToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UninstallLibrariesRequest.Libraries", err) + } + return &uninstallLibrariesRequestWire{ + ClusterId: v.ClusterId, + Libraries: librariesWireValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/clusterpolicies/.package.json b/clusterpolicies/.package.json new file mode 100644 index 0000000..2fd9048 --- /dev/null +++ b/clusterpolicies/.package.json @@ -0,0 +1,3 @@ +{ + "package": "clusterpolicies" +} diff --git a/clusterpolicies/CHANGELOG.md b/clusterpolicies/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/clusterpolicies/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/clusterpolicies/README.md b/clusterpolicies/README.md new file mode 100644 index 0000000..0cde167 --- /dev/null +++ b/clusterpolicies/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/clusterpolicies + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/clusterpolicies@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/clusterpolicies/v2" + +client, err := clusterpolicies.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/clusterpolicies/go.mod b/clusterpolicies/go.mod new file mode 100644 index 0000000..3be3a99 --- /dev/null +++ b/clusterpolicies/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/clusterpolicies + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/clusterpolicies/internal/version.go b/clusterpolicies/internal/version.go new file mode 100644 index 0000000..7782184 --- /dev/null +++ b/clusterpolicies/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-clusterpolicies" + +const Version = "0.0.1-dev.1" diff --git a/clusterpolicies/v2/client.go b/clusterpolicies/v2/client.go new file mode 100755 index 0000000..31b9385 --- /dev/null +++ b/clusterpolicies/v2/client.go @@ -0,0 +1,644 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusterpolicies + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/clusterpolicies/internal" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Get details of a cluster policy revision. +func (c *internalClient) GetClusterPolicyRevision(ctx context.Context, req *GetClusterPolicyRevisionRequest, opts ...call.Option) (*ClusterPolicyRevision, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ClusterPolicyRevision + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp clusterPolicyRevisionWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = clusterPolicyRevisionFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists a cluster policy's revisions, ordered from most to least recent. +func (c *internalClient) ListClusterPolicyRevisions(ctx context.Context, req *ListClusterPolicyRevisionsRequest, opts ...call.Option) (*ListClusterPolicyRevisionsResponse, error) { + wireReq, err := listClusterPolicyRevisionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/") + pb.singleSegment(*req.Parent) + pb.literal("/revisions") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListClusterPolicyRevisionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listClusterPolicyRevisionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listClusterPolicyRevisionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListClusterPolicyRevisionsIter returns an iterator that iterates +// over the results of ListClusterPolicyRevisions. +// +// For example: +// +// for item, err := range c.ListClusterPolicyRevisionsIter(ctx, &ListClusterPolicyRevisionsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListClusterPolicyRevisions call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListClusterPolicyRevisions directly. +func (c *internalClient) ListClusterPolicyRevisionsIter(ctx context.Context, req *ListClusterPolicyRevisionsRequest, opts ...call.Option) iter.Seq2[*ClusterPolicyRevision, error] { + return func(yield func(*ClusterPolicyRevision, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListClusterPolicyRevisionsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListClusterPolicyRevisions(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ClusterPolicyRevisions { + if !yield(&resp.ClusterPolicyRevisions[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Rolls back a cluster policy to a previous revision. +func (c *internalClient) RollbackClusterPolicy(ctx context.Context, req *RollbackClusterPolicyRequest, opts ...call.Option) (*ClusterPolicyRevision, error) { + wireReq, err := rollbackClusterPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/") + pb.singleSegment(*req.Name) + pb.literal("/rollback") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ClusterPolicyRevision + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp clusterPolicyRevisionWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = clusterPolicyRevisionFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new policy with prescribed settings. +func (c *internalClient) CreatePolicy(ctx context.Context, req *CreatePolicyRequest, opts ...call.Option) (*CreatePolicyResponse, error) { + wireReq, err := createPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/clusters/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreatePolicyResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createPolicyResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createPolicyResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a policy for a cluster. Clusters governed by this policy can still +// run, but cannot be edited. +func (c *internalClient) DeletePolicy(ctx context.Context, req *DeletePolicyRequest, opts ...call.Option) (*DeletePolicyResponse, error) { + wireReq, err := deletePolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/clusters/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeletePolicyResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeletePolicyResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update an existing policy for cluster. This operation may make some clusters +// governed by the previous policy invalid. +func (c *internalClient) EditPolicy(ctx context.Context, req *EditPolicyRequest, opts ...call.Option) (*EditPolicyResponse, error) { + wireReq, err := editPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/clusters/edit" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EditPolicyResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &EditPolicyResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a cluster policy entity. Creation and editing is available to admins +// only. +func (c *internalClient) GetPolicy(ctx context.Context, req *GetPolicyRequest, opts ...call.Option) (*Policy, error) { + wireReq, err := getPolicyRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/clusters/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "policy_id", wireReq.PolicyId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Policy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp policyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = policyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns a list of policies accessible by the requesting user. +func (c *internalClient) ListPolicies(ctx context.Context, req *ListPoliciesRequest, opts ...call.Option) (*ListPoliciesResponse, error) { + wireReq, err := listPoliciesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/clusters/list" + queryParams := url.Values{} + if wireReq.SortOrder != "" { + if err := addQueryValue(queryParams, "sort_order", wireReq.SortOrder); err != nil { + return nil, err + } + } + if wireReq.SortColumn != "" { + if err := addQueryValue(queryParams, "sort_column", wireReq.SortColumn); err != nil { + return nil, err + } + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPoliciesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listPoliciesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listPoliciesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/clusterpolicies/v2/genhelper.go b/clusterpolicies/v2/genhelper.go new file mode 100755 index 0000000..c772345 --- /dev/null +++ b/clusterpolicies/v2/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusterpolicies + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/clusterpolicies/v2/model.go b/clusterpolicies/v2/model.go new file mode 100755 index 0000000..1dcc3e5 --- /dev/null +++ b/clusterpolicies/v2/model.go @@ -0,0 +1,379 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusterpolicies + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type ListOrder string + +const ( + ListOrder_Unspecified ListOrder = "" + ListOrder_Desc ListOrder = "DESC" + ListOrder_Asc ListOrder = "ASC" +) + +type PolicySortColumn string + +const ( + PolicySortColumn_Unspecified PolicySortColumn = "" + // Sort result list by policy creation time. + PolicySortColumn_PolicyCreationTime PolicySortColumn = "POLICY_CREATION_TIME" + // Sort result list by policy name. + PolicySortColumn_PolicyName PolicySortColumn = "POLICY_NAME" +) + +// Represents a cluster policy revision. +// +// Only the 100 most recent revisions are stored for each cluster policy.. +type ClusterPolicyRevision struct { + // ID of the cluster policy revision. + RevisionId *string + // Time when the cluster policy revision was created. + CreateTime *types.Time + // Settings used to create/edit the policy. + Settings *PolicyOwnAttributes + // Name of the user who edited this policy. + EditUser *string + // Whether this is the current revision. + IsCurrent *bool +} + +type CreatePolicyRequest struct { + // Cluster Policy name requested by the user. This has to be unique. Length must + // be between 1 and 100 characters. + Name *string + // Policy definition document expressed in [Databricks Cluster Policy Definition + // Language]. + // + // [Databricks Cluster Policy Definition Language]: https://docs.databricks.com/administration-guide/clusters/policy-definition.html + Definition *string + // Additional human-readable description of the cluster policy. + Description *string + // ID of the policy family. The cluster policy's policy definition inherits the + // policy family's policy definition. + // + // Cannot be used with `definition`. Use `policy_family_definition_overrides` + // instead to customize the policy definition. + PolicyFamilyId *string + // Policy definition JSON document expressed in [Databricks Policy Definition + // Language]. The JSON document must be passed as a string and cannot be + // embedded in the requests. + // + // You can use this to customize the policy definition inherited from the policy + // family. Policy rules specified here are merged into the inherited policy + // definition. + // + // [Databricks Policy Definition Language]: https://docs.databricks.com/administration-guide/clusters/policy-definition.html + PolicyFamilyDefinitionOverrides *string + // Max number of clusters per user that can be active using this policy. If not + // present, there is no max limit. + MaxClustersPerUser *int64 + // A list of libraries to be installed on the next cluster restart that uses + // this policy. The maximum number of libraries is 500. + Libraries []Library +} + +type CreatePolicyResponse struct { + // Canonical unique identifier for the cluster policy. + PolicyId *string +} + +type DeletePolicyRequest struct { + // The ID of the policy to delete. + PolicyId *string +} + +type DeletePolicyResponse struct { +} + +type EditPolicyRequest struct { + // The ID of the policy to update. + PolicyId *string + // Cluster Policy name requested by the user. This has to be unique. Length must + // be between 1 and 100 characters. + Name *string + // Policy definition document expressed in [Databricks Cluster Policy Definition + // Language]. + // + // [Databricks Cluster Policy Definition Language]: https://docs.databricks.com/administration-guide/clusters/policy-definition.html + Definition *string + // Additional human-readable description of the cluster policy. + Description *string + // ID of the policy family. The cluster policy's policy definition inherits the + // policy family's policy definition. + // + // Cannot be used with `definition`. Use `policy_family_definition_overrides` + // instead to customize the policy definition. + PolicyFamilyId *string + // Policy definition JSON document expressed in [Databricks Policy Definition + // Language]. The JSON document must be passed as a string and cannot be + // embedded in the requests. + // + // You can use this to customize the policy definition inherited from the policy + // family. Policy rules specified here are merged into the inherited policy + // definition. + // + // [Databricks Policy Definition Language]: https://docs.databricks.com/administration-guide/clusters/policy-definition.html + PolicyFamilyDefinitionOverrides *string + // Max number of clusters per user that can be active using this policy. If not + // present, there is no max limit. + MaxClustersPerUser *int64 + // A list of libraries to be installed on the next cluster restart that uses + // this policy. The maximum number of libraries is 500. + Libraries []Library +} + +type EditPolicyResponse struct { +} + +// Request to get a cluster policy revision by ID.. +type GetClusterPolicyRevisionRequest struct { + // The fully qualified resource name of the cluster policy revision. Format: + // cluster-policies/{policy_id}/revisions/{revision_id}. + Name *string +} + +type GetPolicyRequest struct { + // Canonical unique identifier for the Cluster Policy. + PolicyId *string +} + +type Library struct { + Lib isLibrary_Lib +} + +type isLibrary_Lib interface { + isLibrary_Lib() +} + +// Library_Lib_Jar selects Jar for Library.Lib. +// URI of the JAR library to install. Supported URIs include Workspace paths, +// Unity Catalog Volumes paths, and S3 URIs. For example: `{ "jar": +// "/Workspace/path/to/library.jar" }`, `{ "jar" : +// "/Volumes/path/to/library.jar" }` or `{ "jar": "s3://my-bucket/library.jar" +// }`. If S3 is used, please make sure the cluster has read access on the +// library. You may need to launch the cluster with an IAM role to access the S3 +// URI. +type Library_Lib_Jar struct { + Jar string +} + +func (*Library_Lib_Jar) isLibrary_Lib() {} + +// Library_Lib_Egg selects Egg for Library.Lib. +// Deprecated. URI of the egg library to install. Installing Python egg files is +// deprecated and is not supported in Databricks Runtime 14.0 and above. +type Library_Lib_Egg struct { + Egg string +} + +func (*Library_Lib_Egg) isLibrary_Lib() {} + +// Library_Lib_Pypi selects Pypi for Library.Lib. +// Specification of a PyPi library to be installed. For example: `{ "package": +// "simplejson" }` +type Library_Lib_Pypi struct { + Pypi PythonPyPiLibrary +} + +func (*Library_Lib_Pypi) isLibrary_Lib() {} + +// Library_Lib_Maven selects Maven for Library.Lib. +// Specification of a maven library to be installed. For example: `{ +// "coordinates": "org.jsoup:jsoup:1.7.2" }` +type Library_Lib_Maven struct { + Maven MavenLibrary +} + +func (*Library_Lib_Maven) isLibrary_Lib() {} + +// Library_Lib_Cran selects Cran for Library.Lib. +// Specification of a CRAN library to be installed as part of the library +type Library_Lib_Cran struct { + Cran RCranLibrary +} + +func (*Library_Lib_Cran) isLibrary_Lib() {} + +// Library_Lib_Whl selects Whl for Library.Lib. +// URI of the wheel library to install. Supported URIs include Workspace paths, +// Unity Catalog Volumes paths, and S3 URIs. For example: `{ "whl": +// "/Workspace/path/to/library.whl" }`, `{ "whl" : +// "/Volumes/path/to/library.whl" }` or `{ "whl": "s3://my-bucket/library.whl" +// }`. If S3 is used, please make sure the cluster has read access on the +// library. You may need to launch the cluster with an IAM role to access the S3 +// URI. +type Library_Lib_Whl struct { + Whl string +} + +func (*Library_Lib_Whl) isLibrary_Lib() {} + +// Library_Lib_Requirements selects Requirements for Library.Lib. +// URI of the requirements.txt file to install. Only Workspace paths and Unity +// Catalog Volumes paths are supported. For example: `{ "requirements": +// "/Workspace/path/to/requirements.txt" }` or `{ "requirements" : +// "/Volumes/path/to/requirements.txt" }` +type Library_Lib_Requirements struct { + Requirements string +} + +func (*Library_Lib_Requirements) isLibrary_Lib() {} + +// Request to list cluster policy revisions.. +type ListClusterPolicyRevisionsRequest struct { + // The fully qualified resource name of the parent cluster. Format: + // cluster-policies/{policy_id}. + Parent *string + // Maximum number of cluster policy revisions to return per page. + PageSize *int + // Pagination token from a previous list cluster policy revisions request. + PageToken *string +} + +// Response when listing cluster policy revisions.. +type ListClusterPolicyRevisionsResponse struct { + // Cluster policy revisions in the current page. + ClusterPolicyRevisions []ClusterPolicyRevision + // Token for fetching the next page. Empty when there are no more results. + NextPageToken *string +} + +type ListPoliciesRequest struct { + // The order in which the policies get listed. * `DESC` - Sort result list in + // descending order. * `ASC` - Sort result list in ascending order. + SortOrder ListOrder + // The cluster policy attribute to sort by. * `POLICY_CREATION_TIME` - Sort + // result list by policy creation time. * `POLICY_NAME` - Sort result list by + // policy name. + SortColumn PolicySortColumn +} + +type ListPoliciesResponse struct { + // List of policies. + Policies []Policy +} + +type MavenLibrary struct { + // Gradle-style maven coordinates. For example: "org.jsoup:jsoup:1.7.2". + Coordinates *string + // Maven repo to install the Maven package from. If omitted, both Maven Central + // Repository and Spark Packages are searched. + Repo *string + // List of dependences to exclude. For example: `["slf4j:slf4j", + // "*:hadoop-client"]`. + // + // Maven dependency exclusions: + // https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html. + Exclusions []string +} + +// Describes a Cluster Policy entity.. +type Policy struct { + // Canonical unique identifier for the Cluster Policy. + PolicyId *string + // Creator user name. The field won't be included in the response if the user + // has already been deleted. + CreatorUserName *string + // Creation time. The timestamp (in millisecond) when this Cluster Policy was + // created. + CreatedAtTimestamp *int64 + // If true, policy is a default policy created and managed by . + // Default policies cannot be deleted, and their policy families cannot be + // changed. + IsDefault *bool + // Cluster Policy name requested by the user. This has to be unique. Length must + // be between 1 and 100 characters. + Name *string + // Policy definition document expressed in [Databricks Cluster Policy Definition + // Language]. + // + // [Databricks Cluster Policy Definition Language]: https://docs.databricks.com/administration-guide/clusters/policy-definition.html + Definition *string + // Additional human-readable description of the cluster policy. + Description *string + // ID of the policy family. The cluster policy's policy definition inherits the + // policy family's policy definition. + // + // Cannot be used with `definition`. Use `policy_family_definition_overrides` + // instead to customize the policy definition. + PolicyFamilyId *string + // Policy definition JSON document expressed in [Databricks Policy Definition + // Language]. The JSON document must be passed as a string and cannot be + // embedded in the requests. + // + // You can use this to customize the policy definition inherited from the policy + // family. Policy rules specified here are merged into the inherited policy + // definition. + // + // [Databricks Policy Definition Language]: https://docs.databricks.com/administration-guide/clusters/policy-definition.html + PolicyFamilyDefinitionOverrides *string + // Max number of clusters per user that can be active using this policy. If not + // present, there is no max limit. + MaxClustersPerUser *int64 + // A list of libraries to be installed on the next cluster restart that uses + // this policy. The maximum number of libraries is 500. + Libraries []Library +} + +type PolicyOwnAttributes struct { + // Cluster Policy name requested by the user. This has to be unique. Length must + // be between 1 and 100 characters. + Name *string + // Policy definition document expressed in [Databricks Cluster Policy Definition + // Language]. + // + // [Databricks Cluster Policy Definition Language]: https://docs.databricks.com/administration-guide/clusters/policy-definition.html + Definition *string + // Additional human-readable description of the cluster policy. + Description *string + // ID of the policy family. The cluster policy's policy definition inherits the + // policy family's policy definition. + // + // Cannot be used with `definition`. Use `policy_family_definition_overrides` + // instead to customize the policy definition. + PolicyFamilyId *string + // Policy definition JSON document expressed in [Databricks Policy Definition + // Language]. The JSON document must be passed as a string and cannot be + // embedded in the requests. + // + // You can use this to customize the policy definition inherited from the policy + // family. Policy rules specified here are merged into the inherited policy + // definition. + // + // [Databricks Policy Definition Language]: https://docs.databricks.com/administration-guide/clusters/policy-definition.html + PolicyFamilyDefinitionOverrides *string + // Max number of clusters per user that can be active using this policy. If not + // present, there is no max limit. + MaxClustersPerUser *int64 + // A list of libraries to be installed on the next cluster restart that uses + // this policy. The maximum number of libraries is 500. + Libraries []Library +} + +type PythonPyPiLibrary struct { + // The name of the pypi package to install. An optional exact version + // specification is also supported. Examples: "simplejson" and + // "simplejson==3.8.0". + Package *string + // The repository where the package can be found. If not specified, the default + // pip index is used. + Repo *string +} + +type RCranLibrary struct { + // The name of the CRAN package to install. + Package *string + // The repository where the package can be found. If not specified, the default + // CRAN repo is used. + Repo *string +} + +// Request to roll back cluster policy.. +type RollbackClusterPolicyRequest struct { + // The fully qualified resource name of the cluster policy revision. Format: + // cluster-policies/{policy_id}/revisions/{revision_id}. + Name *string +} diff --git a/clusterpolicies/v2/wire.go b/clusterpolicies/v2/wire.go new file mode 100755 index 0000000..78c332f --- /dev/null +++ b/clusterpolicies/v2/wire.go @@ -0,0 +1,513 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusterpolicies + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +type clusterPolicyRevisionWire struct { + RevisionId *string `json:"revision_id,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + Settings *policyOwnAttributesWire `json:"settings,omitempty"` + EditUser *string `json:"edit_user,omitempty"` + IsCurrent *bool `json:"is_current,omitempty"` +} + +func clusterPolicyRevisionFromWire(w *clusterPolicyRevisionWire) (*ClusterPolicyRevision, error) { + if w == nil { + return nil, nil + } + settingsPublicValue, err := policyOwnAttributesFromWire(w.Settings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterPolicyRevision.Settings", err) + } + return &ClusterPolicyRevision{ + RevisionId: w.RevisionId, + CreateTime: w.CreateTime, + Settings: settingsPublicValue, + EditUser: w.EditUser, + IsCurrent: w.IsCurrent, + }, nil +} + +type createPolicyRequestWire struct { + Name *string `json:"name,omitempty"` + Definition *string `json:"definition,omitempty"` + Description *string `json:"description,omitempty"` + PolicyFamilyId *string `json:"policy_family_id,omitempty"` + PolicyFamilyDefinitionOverrides *string `json:"policy_family_definition_overrides,omitempty"` + MaxClustersPerUser *int64 `json:"max_clusters_per_user,omitempty"` + Libraries []libraryWire `json:"libraries,omitempty"` +} + +func createPolicyRequestToWire(v *CreatePolicyRequest) (*createPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + librariesWireValue, err := convertSlice(v.Libraries, libraryToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePolicyRequest.Libraries", err) + } + return &createPolicyRequestWire{ + Name: v.Name, + Definition: v.Definition, + Description: v.Description, + PolicyFamilyId: v.PolicyFamilyId, + PolicyFamilyDefinitionOverrides: v.PolicyFamilyDefinitionOverrides, + MaxClustersPerUser: v.MaxClustersPerUser, + Libraries: librariesWireValue, + }, nil +} + +type createPolicyResponseWire struct { + PolicyId *string `json:"policy_id,omitempty"` +} + +func createPolicyResponseFromWire(w *createPolicyResponseWire) (*CreatePolicyResponse, error) { + if w == nil { + return nil, nil + } + return &CreatePolicyResponse{ + PolicyId: w.PolicyId, + }, nil +} + +type deletePolicyRequestWire struct { + PolicyId *string `json:"policy_id,omitempty"` +} + +func deletePolicyRequestToWire(v *DeletePolicyRequest) (*deletePolicyRequestWire, error) { + if v == nil { + return nil, nil + } + return &deletePolicyRequestWire{ + PolicyId: v.PolicyId, + }, nil +} + +type editPolicyRequestWire struct { + PolicyId *string `json:"policy_id,omitempty"` + Name *string `json:"name,omitempty"` + Definition *string `json:"definition,omitempty"` + Description *string `json:"description,omitempty"` + PolicyFamilyId *string `json:"policy_family_id,omitempty"` + PolicyFamilyDefinitionOverrides *string `json:"policy_family_definition_overrides,omitempty"` + MaxClustersPerUser *int64 `json:"max_clusters_per_user,omitempty"` + Libraries []libraryWire `json:"libraries,omitempty"` +} + +func editPolicyRequestToWire(v *EditPolicyRequest) (*editPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + librariesWireValue, err := convertSlice(v.Libraries, libraryToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPolicyRequest.Libraries", err) + } + return &editPolicyRequestWire{ + PolicyId: v.PolicyId, + Name: v.Name, + Definition: v.Definition, + Description: v.Description, + PolicyFamilyId: v.PolicyFamilyId, + PolicyFamilyDefinitionOverrides: v.PolicyFamilyDefinitionOverrides, + MaxClustersPerUser: v.MaxClustersPerUser, + Libraries: librariesWireValue, + }, nil +} + +type getPolicyRequestWire struct { + PolicyId *string `json:"policy_id,omitempty"` +} + +func getPolicyRequestToWire(v *GetPolicyRequest) (*getPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + return &getPolicyRequestWire{ + PolicyId: v.PolicyId, + }, nil +} + +type libraryWire struct { + Jar *string `json:"jar,omitempty"` + Egg *string `json:"egg,omitempty"` + Pypi *pythonPyPiLibraryWire `json:"pypi,omitempty"` + Maven *mavenLibraryWire `json:"maven,omitempty"` + Cran *rCranLibraryWire `json:"cran,omitempty"` + Whl *string `json:"whl,omitempty"` + Requirements *string `json:"requirements,omitempty"` +} + +func libraryToWire(v *Library) (*libraryWire, error) { + if v == nil { + return nil, nil + } + var libJarWire *string + var libEggWire *string + var libPypiWire *pythonPyPiLibraryWire + var libMavenWire *mavenLibraryWire + var libCranWire *rCranLibraryWire + var libWhlWire *string + var libRequirementsWire *string + switch value := v.Lib.(type) { + case nil: + case *Library_Lib_Jar: + if value != nil { + libJarWire = new(value.Jar) + } + case *Library_Lib_Egg: + if value != nil { + libEggWire = new(value.Egg) + } + case *Library_Lib_Pypi: + if value != nil { + libPypiConverted, err := pythonPyPiLibraryToWire(&value.Pypi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Pypi", err) + } + libPypiWire = libPypiConverted + } + case *Library_Lib_Maven: + if value != nil { + libMavenConverted, err := mavenLibraryToWire(&value.Maven) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Maven", err) + } + libMavenWire = libMavenConverted + } + case *Library_Lib_Cran: + if value != nil { + libCranConverted, err := rCranLibraryToWire(&value.Cran) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Cran", err) + } + libCranWire = libCranConverted + } + case *Library_Lib_Whl: + if value != nil { + libWhlWire = new(value.Whl) + } + case *Library_Lib_Requirements: + if value != nil { + libRequirementsWire = new(value.Requirements) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Library.Lib", value) + } + return &libraryWire{ + Jar: libJarWire, + Egg: libEggWire, + Pypi: libPypiWire, + Maven: libMavenWire, + Cran: libCranWire, + Whl: libWhlWire, + Requirements: libRequirementsWire, + }, nil +} + +func libraryFromWire(w *libraryWire) (*Library, error) { + if w == nil { + return nil, nil + } + libMembers := 0 + if w.Jar != nil { + libMembers++ + } + if w.Egg != nil { + libMembers++ + } + if w.Pypi != nil { + libMembers++ + } + if w.Maven != nil { + libMembers++ + } + if w.Cran != nil { + libMembers++ + } + if w.Whl != nil { + libMembers++ + } + if w.Requirements != nil { + libMembers++ + } + if libMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Library.Lib") + } + var libSelection isLibrary_Lib + switch { + case w.Jar != nil: + libSelection = &Library_Lib_Jar{Jar: *w.Jar} + case w.Egg != nil: + libSelection = &Library_Lib_Egg{Egg: *w.Egg} + case w.Pypi != nil: + libPypiConverted, err := pythonPyPiLibraryFromWire(w.Pypi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Pypi", err) + } + libSelection = &Library_Lib_Pypi{Pypi: *libPypiConverted} + case w.Maven != nil: + libMavenConverted, err := mavenLibraryFromWire(w.Maven) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Maven", err) + } + libSelection = &Library_Lib_Maven{Maven: *libMavenConverted} + case w.Cran != nil: + libCranConverted, err := rCranLibraryFromWire(w.Cran) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Cran", err) + } + libSelection = &Library_Lib_Cran{Cran: *libCranConverted} + case w.Whl != nil: + libSelection = &Library_Lib_Whl{Whl: *w.Whl} + case w.Requirements != nil: + libSelection = &Library_Lib_Requirements{Requirements: *w.Requirements} + } + return &Library{ + Lib: libSelection, + }, nil +} + +type listClusterPolicyRevisionsRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listClusterPolicyRevisionsRequestToWire(v *ListClusterPolicyRevisionsRequest) (*listClusterPolicyRevisionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listClusterPolicyRevisionsRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listClusterPolicyRevisionsResponseWire struct { + ClusterPolicyRevisions []clusterPolicyRevisionWire `json:"cluster_policy_revisions,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listClusterPolicyRevisionsResponseFromWire(w *listClusterPolicyRevisionsResponseWire) (*ListClusterPolicyRevisionsResponse, error) { + if w == nil { + return nil, nil + } + clusterPolicyRevisionsPublicValue, err := convertSlice(w.ClusterPolicyRevisions, clusterPolicyRevisionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListClusterPolicyRevisionsResponse.ClusterPolicyRevisions", err) + } + return &ListClusterPolicyRevisionsResponse{ + ClusterPolicyRevisions: clusterPolicyRevisionsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listPoliciesRequestWire struct { + SortOrder ListOrder `json:"sort_order,omitempty"` + SortColumn PolicySortColumn `json:"sort_column,omitempty"` +} + +func listPoliciesRequestToWire(v *ListPoliciesRequest) (*listPoliciesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listPoliciesRequestWire{ + SortOrder: v.SortOrder, + SortColumn: v.SortColumn, + }, nil +} + +type listPoliciesResponseWire struct { + Policies []policyWire `json:"policies,omitempty"` +} + +func listPoliciesResponseFromWire(w *listPoliciesResponseWire) (*ListPoliciesResponse, error) { + if w == nil { + return nil, nil + } + policiesPublicValue, err := convertSlice(w.Policies, policyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPoliciesResponse.Policies", err) + } + return &ListPoliciesResponse{ + Policies: policiesPublicValue, + }, nil +} + +type mavenLibraryWire struct { + Coordinates *string `json:"coordinates,omitempty"` + Repo *string `json:"repo,omitempty"` + Exclusions []string `json:"exclusions,omitempty"` +} + +func mavenLibraryToWire(v *MavenLibrary) (*mavenLibraryWire, error) { + if v == nil { + return nil, nil + } + return &mavenLibraryWire{ + Coordinates: v.Coordinates, + Repo: v.Repo, + Exclusions: v.Exclusions, + }, nil +} + +func mavenLibraryFromWire(w *mavenLibraryWire) (*MavenLibrary, error) { + if w == nil { + return nil, nil + } + return &MavenLibrary{ + Coordinates: w.Coordinates, + Repo: w.Repo, + Exclusions: w.Exclusions, + }, nil +} + +type policyWire struct { + PolicyId *string `json:"policy_id,omitempty"` + CreatorUserName *string `json:"creator_user_name,omitempty"` + CreatedAtTimestamp *int64 `json:"created_at_timestamp,omitempty"` + IsDefault *bool `json:"is_default,omitempty"` + Name *string `json:"name,omitempty"` + Definition *string `json:"definition,omitempty"` + Description *string `json:"description,omitempty"` + PolicyFamilyId *string `json:"policy_family_id,omitempty"` + PolicyFamilyDefinitionOverrides *string `json:"policy_family_definition_overrides,omitempty"` + MaxClustersPerUser *int64 `json:"max_clusters_per_user,omitempty"` + Libraries []libraryWire `json:"libraries,omitempty"` +} + +func policyFromWire(w *policyWire) (*Policy, error) { + if w == nil { + return nil, nil + } + librariesPublicValue, err := convertSlice(w.Libraries, libraryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Policy.Libraries", err) + } + return &Policy{ + PolicyId: w.PolicyId, + CreatorUserName: w.CreatorUserName, + CreatedAtTimestamp: w.CreatedAtTimestamp, + IsDefault: w.IsDefault, + Name: w.Name, + Definition: w.Definition, + Description: w.Description, + PolicyFamilyId: w.PolicyFamilyId, + PolicyFamilyDefinitionOverrides: w.PolicyFamilyDefinitionOverrides, + MaxClustersPerUser: w.MaxClustersPerUser, + Libraries: librariesPublicValue, + }, nil +} + +type policyOwnAttributesWire struct { + Name *string `json:"name,omitempty"` + Definition *string `json:"definition,omitempty"` + Description *string `json:"description,omitempty"` + PolicyFamilyId *string `json:"policy_family_id,omitempty"` + PolicyFamilyDefinitionOverrides *string `json:"policy_family_definition_overrides,omitempty"` + MaxClustersPerUser *int64 `json:"max_clusters_per_user,omitempty"` + Libraries []libraryWire `json:"libraries,omitempty"` +} + +func policyOwnAttributesFromWire(w *policyOwnAttributesWire) (*PolicyOwnAttributes, error) { + if w == nil { + return nil, nil + } + librariesPublicValue, err := convertSlice(w.Libraries, libraryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PolicyOwnAttributes.Libraries", err) + } + return &PolicyOwnAttributes{ + Name: w.Name, + Definition: w.Definition, + Description: w.Description, + PolicyFamilyId: w.PolicyFamilyId, + PolicyFamilyDefinitionOverrides: w.PolicyFamilyDefinitionOverrides, + MaxClustersPerUser: w.MaxClustersPerUser, + Libraries: librariesPublicValue, + }, nil +} + +type pythonPyPiLibraryWire struct { + Package *string `json:"package,omitempty"` + Repo *string `json:"repo,omitempty"` +} + +func pythonPyPiLibraryToWire(v *PythonPyPiLibrary) (*pythonPyPiLibraryWire, error) { + if v == nil { + return nil, nil + } + return &pythonPyPiLibraryWire{ + Package: v.Package, + Repo: v.Repo, + }, nil +} + +func pythonPyPiLibraryFromWire(w *pythonPyPiLibraryWire) (*PythonPyPiLibrary, error) { + if w == nil { + return nil, nil + } + return &PythonPyPiLibrary{ + Package: w.Package, + Repo: w.Repo, + }, nil +} + +type rCranLibraryWire struct { + Package *string `json:"package,omitempty"` + Repo *string `json:"repo,omitempty"` +} + +func rCranLibraryToWire(v *RCranLibrary) (*rCranLibraryWire, error) { + if v == nil { + return nil, nil + } + return &rCranLibraryWire{ + Package: v.Package, + Repo: v.Repo, + }, nil +} + +func rCranLibraryFromWire(w *rCranLibraryWire) (*RCranLibrary, error) { + if w == nil { + return nil, nil + } + return &RCranLibrary{ + Package: w.Package, + Repo: w.Repo, + }, nil +} + +type rollbackClusterPolicyRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func rollbackClusterPolicyRequestToWire(v *RollbackClusterPolicyRequest) (*rollbackClusterPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + return &rollbackClusterPolicyRequestWire{ + Name: v.Name, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/clusters/.package.json b/clusters/.package.json new file mode 100644 index 0000000..020c2de --- /dev/null +++ b/clusters/.package.json @@ -0,0 +1,3 @@ +{ + "package": "clusters" +} diff --git a/clusters/CHANGELOG.md b/clusters/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/clusters/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/clusters/README.md b/clusters/README.md new file mode 100644 index 0000000..16f3d57 --- /dev/null +++ b/clusters/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/clusters + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/clusters@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/clusters/v2" + +client, err := clusters.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/clusters/go.mod b/clusters/go.mod new file mode 100644 index 0000000..5cc50b5 --- /dev/null +++ b/clusters/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/clusters + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/clusters/internal/version.go b/clusters/internal/version.go new file mode 100644 index 0000000..97c9836 --- /dev/null +++ b/clusters/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-clusters" + +const Version = "0.0.1-dev.1" diff --git a/clusters/v2/client.go b/clusters/v2/client.go new file mode 100755 index 0000000..880a16f --- /dev/null +++ b/clusters/v2/client.go @@ -0,0 +1,2456 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusters + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/clusters/internal" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Retrieves a list of events about the activity of a cluster. This API is +// paginated. If there are more events to read, the response includes all the +// parameters necessary to request the next page of events. +func (c *internalClient) ListEvents(ctx context.Context, req *ListEventsRequest, opts ...call.Option) (*GetEventsResponse, error) { + wireReq, err := listEventsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/events" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetEventsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getEventsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getEventsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListEventsIter returns an iterator that iterates +// over the results of ListEvents. +// +// For example: +// +// for item, err := range c.ListEventsIter(ctx, &ListEventsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListEvents call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListEvents directly. +func (c *internalClient) ListEventsIter(ctx context.Context, req *ListEventsRequest, opts ...call.Option) iter.Seq2[*ClusterEvent, error] { + return func(yield func(*ClusterEvent, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListEventsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListEvents(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Events { + if !yield(&resp.Events[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get details of a cluster revision. +func (c *internalClient) GetClusterRevision(ctx context.Context, req *GetClusterRevisionRequest, opts ...call.Option) (*ClusterRevision, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ClusterRevision + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp clusterRevisionWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = clusterRevisionFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists a cluster's revisions, ordered from most to least recent. +func (c *internalClient) ListClusterRevisions(ctx context.Context, req *ListClusterRevisionsRequest, opts ...call.Option) (*ListClusterRevisionsResponse, error) { + wireReq, err := listClusterRevisionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Parent) + pb.literal("/revisions") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListClusterRevisionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listClusterRevisionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listClusterRevisionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListClusterRevisionsIter returns an iterator that iterates +// over the results of ListClusterRevisions. +// +// For example: +// +// for item, err := range c.ListClusterRevisionsIter(ctx, &ListClusterRevisionsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListClusterRevisions call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListClusterRevisions directly. +func (c *internalClient) ListClusterRevisionsIter(ctx context.Context, req *ListClusterRevisionsRequest, opts ...call.Option) iter.Seq2[*ClusterRevision, error] { + return func(yield func(*ClusterRevision, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListClusterRevisionsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListClusterRevisions(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ClusterRevisions { + if !yield(&resp.ClusterRevisions[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Rolls back a cluster to a previous revision. A cluster can be rolled back if +// it is in a `RUNNING` or `TERMINATED` state. +// +// If a cluster is rolled back while in a `RUNNING` state, it will be restarted +// so that the new attributes can take effect. +// +// If a cluster is rolled back while in a `TERMINATED` state, it will remain +// `TERMINATED`. The next time it is started using the `clusters/start` API, the +// new attributes will take effect. Any attempt to roll back a cluster in any +// other state will be rejected with an `INVALID_PARAMETER_VALUE` error code. +func (c *internalClient) RollbackCluster(ctx context.Context, req *RollbackClusterRequest, opts ...call.Option) (*ClusterRevision, error) { + wireReq, err := rollbackClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + pb.literal("/rollback") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ClusterRevision + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp clusterRevisionWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = clusterRevisionFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Change the owner of the cluster. You must be an admin and the cluster must be +// terminated to perform this operation. The service principal application ID +// can be supplied as an argument to `owner_username`. +func (c *internalClient) ChangeClusterOwner(ctx context.Context, req *ChangeClusterOwnerRequest, opts ...call.Option) (*ChangeClusterOwnerResponse, error) { + wireReq, err := changeClusterOwnerRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/change-owner" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ChangeClusterOwnerResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &ChangeClusterOwnerResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new Spark cluster. This method will acquire new instances from the +// cloud provider if necessary. This method is asynchronous; the returned +// “cluster_id“ can be used to poll the cluster status. When this method +// returns, the cluster will be in a “PENDING“ state. The cluster will be +// usable once it enters a “RUNNING“ state. Note: may not be able +// to acquire some of the requested nodes, due to cloud provider limitations +// (account limits, spot price, etc.) or transient network issues. +// +// If acquires at least 85% of the requested on-demand nodes, +// cluster creation will succeed. Otherwise the cluster will terminate with an +// informative error message. +// +// Rather than authoring the cluster's JSON definition from scratch, Databricks +// recommends filling out the [create compute UI](/compute/configure.html) and +// then copying the generated JSON definition from the UI. +func (c *internalClient) createClusterBase(ctx context.Context, req *CreateClusterRequest, opts ...call.Option) (*CreateClusterResponse, error) { + wireReq, err := createClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createClusterResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createClusterResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new Spark cluster. This method will acquire new instances from the +// cloud provider if necessary. This method is asynchronous; the returned +// “cluster_id“ can be used to poll the cluster status. When this method +// returns, the cluster will be in a “PENDING“ state. The cluster will be +// usable once it enters a “RUNNING“ state. Note: may not be able +// to acquire some of the requested nodes, due to cloud provider limitations +// (account limits, spot price, etc.) or transient network issues. +// +// If acquires at least 85% of the requested on-demand nodes, +// cluster creation will succeed. Otherwise the cluster will terminate with an +// informative error message. +// +// Rather than authoring the cluster's JSON definition from scratch, Databricks +// recommends filling out the [create compute UI](/compute/configure.html) and +// then copying the generated JSON definition from the UI. +func (c *internalClient) CreateCluster(ctx context.Context, req *CreateClusterRequest, opts ...call.Option) (*CreateClusterWaiter, error) { + resp, err := c.createClusterBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.ClusterId == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "ClusterId") + } + return &CreateClusterWaiter{ + poll: c.GetCluster, + clusterId: *resp.ClusterId, + }, nil +} + +// CreateClusterWaiter tracks the state of the operation started by CreateCluster. +type CreateClusterWaiter struct { + poll func(context.Context, *GetClusterRequest, ...call.Option) (*ClusterInfo, error) + clusterId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateClusterWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running, ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateClusterWaiter) Wait(ctx context.Context, opts ...lro.Option) (*ClusterInfo, error) { + var result *ClusterInfo + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running: + result = pollResp + return nil + case ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + message := "(no message)" + if pollResp.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Terminates the Spark cluster with the specified ID. The cluster is removed +// asynchronously. Once the termination has completed, the cluster will be in a +// `TERMINATED` state. If the cluster is already in a `TERMINATING` or +// `TERMINATED` state, nothing will happen. +func (c *internalClient) deleteClusterBase(ctx context.Context, req *DeleteClusterRequest, opts ...call.Option) (*DeleteClusterResponse, error) { + wireReq, err := deleteClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteClusterResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Terminates the Spark cluster with the specified ID. The cluster is removed +// asynchronously. Once the termination has completed, the cluster will be in a +// `TERMINATED` state. If the cluster is already in a `TERMINATING` or +// `TERMINATED` state, nothing will happen. +func (c *internalClient) DeleteCluster(ctx context.Context, req *DeleteClusterRequest, opts ...call.Option) (*DeleteClusterWaiter, error) { + if req.ClusterId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ClusterId") + } + capturedClusterId := *req.ClusterId + _, err := c.deleteClusterBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &DeleteClusterWaiter{ + poll: c.GetCluster, + clusterId: capturedClusterId, + }, nil +} + +// DeleteClusterWaiter tracks the state of the operation started by DeleteCluster. +type DeleteClusterWaiter struct { + poll func(context.Context, *GetClusterRequest, ...call.Option) (*ClusterInfo, error) + clusterId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *DeleteClusterWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Terminated, ClusterState_ClusterState_Error: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *DeleteClusterWaiter) Wait(ctx context.Context, opts ...lro.Option) (*ClusterInfo, error) { + var result *ClusterInfo + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Terminated: + result = pollResp + return nil + case ClusterState_ClusterState_Error: + message := "(no message)" + if pollResp.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Updates the configuration of a cluster to match the provided attributes and +// size. A cluster can be updated if it is in a `RUNNING` or `TERMINATED` state. +// +// If a cluster is updated while in a `RUNNING` state, it will be restarted so +// that the new attributes can take effect. +// +// If a cluster is updated while in a `TERMINATED` state, it will remain +// `TERMINATED`. The next time it is started using the `clusters/start` API, the +// new attributes will take effect. Any attempt to update a cluster in any other +// state will be rejected with an `INVALID_STATE` error code. +// +// Clusters created by the Databricks Jobs service cannot be edited. +func (c *internalClient) editClusterBase(ctx context.Context, req *EditClusterRequest, opts ...call.Option) (*EditClusterResponse, error) { + wireReq, err := editClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/edit" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EditClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &EditClusterResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the configuration of a cluster to match the provided attributes and +// size. A cluster can be updated if it is in a `RUNNING` or `TERMINATED` state. +// +// If a cluster is updated while in a `RUNNING` state, it will be restarted so +// that the new attributes can take effect. +// +// If a cluster is updated while in a `TERMINATED` state, it will remain +// `TERMINATED`. The next time it is started using the `clusters/start` API, the +// new attributes will take effect. Any attempt to update a cluster in any other +// state will be rejected with an `INVALID_STATE` error code. +// +// Clusters created by the Databricks Jobs service cannot be edited. +func (c *internalClient) EditCluster(ctx context.Context, req *EditClusterRequest, opts ...call.Option) (*EditClusterWaiter, error) { + if req.ClusterId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ClusterId") + } + capturedClusterId := *req.ClusterId + _, err := c.editClusterBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &EditClusterWaiter{ + poll: c.GetCluster, + clusterId: capturedClusterId, + }, nil +} + +// EditClusterWaiter tracks the state of the operation started by EditCluster. +type EditClusterWaiter struct { + poll func(context.Context, *GetClusterRequest, ...call.Option) (*ClusterInfo, error) + clusterId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *EditClusterWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running, ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *EditClusterWaiter) Wait(ctx context.Context, opts ...lro.Option) (*ClusterInfo, error) { + var result *ClusterInfo + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running: + result = pollResp + return nil + case ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + message := "(no message)" + if pollResp.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Retrieves the information for a cluster given its identifier. Clusters can be +// described while they are running, or up to 60 days after they are terminated. +func (c *internalClient) GetCluster(ctx context.Context, req *GetClusterRequest, opts ...call.Option) (*ClusterInfo, error) { + wireReq, err := getClusterRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "cluster_id", wireReq.ClusterId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ClusterInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp clusterInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = clusterInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns a list of availability zones where clusters can be created in (For +// example, us-west-2a). These zones can be used to launch a cluster. +func (c *internalClient) ListAvailableZones(ctx context.Context, req *ListAvailableZonesRequest, opts ...call.Option) (*ListAvailableZonesResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/list-zones" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAvailableZonesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAvailableZonesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAvailableZonesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Return information about all pinned and active clusters, and all clusters +// terminated within the last 30 days. Clusters terminated prior to this period +// are not included. +func (c *internalClient) ListClusters(ctx context.Context, req *ListClustersRequest, opts ...call.Option) (*ListClustersResponse, error) { + wireReq, err := listClustersRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/list" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListClustersResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listClustersResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listClustersResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListClustersIter returns an iterator that iterates +// over the results of ListClusters. +// +// For example: +// +// for item, err := range c.ListClustersIter(ctx, &ListClustersRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListClusters call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListClusters directly. +func (c *internalClient) ListClustersIter(ctx context.Context, req *ListClustersRequest, opts ...call.Option) iter.Seq2[*ClusterInfo, error] { + return func(yield func(*ClusterInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListClustersRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListClusters(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Clusters { + if !yield(&resp.Clusters[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Returns a list of supported Spark node types. These node types can be used to +// launch a cluster. +func (c *internalClient) ListNodeTypes(ctx context.Context, req *ListNodeTypesRequest, opts ...call.Option) (*ListNodeTypesResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/list-node-types" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListNodeTypesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listNodeTypesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listNodeTypesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns the list of available Spark versions. These versions can be used to +// launch a cluster. +func (c *internalClient) ListSparkVersions(ctx context.Context, req *GetSparkVersionsRequest, opts ...call.Option) (*GetSparkVersionsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/spark-versions" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetSparkVersionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getSparkVersionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getSparkVersionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Permanently deletes a Spark cluster. This cluster is terminated and resources +// are asynchronously removed. +// +// In addition, users will no longer see permanently deleted clusters in the +// cluster list, and API users can no longer perform any action on permanently +// deleted clusters. +func (c *internalClient) PermanentDeleteCluster(ctx context.Context, req *PermanentDeleteClusterRequest, opts ...call.Option) (*PermanentDeleteClusterResponse, error) { + wireReq, err := permanentDeleteClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/permanent-delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PermanentDeleteClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &PermanentDeleteClusterResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Pinning a cluster ensures that the cluster will always be returned by the +// ListClusters API. Pinning a cluster that is already pinned will have no +// effect. This API can only be called by workspace admins. +func (c *internalClient) PinCluster(ctx context.Context, req *PinClusterRequest, opts ...call.Option) (*PinClusterResponse, error) { + wireReq, err := pinClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/pin" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PinClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &PinClusterResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Resizes a cluster to have a desired number of workers. This will fail unless +// the cluster is in a `RUNNING` state. +func (c *internalClient) resizeClusterBase(ctx context.Context, req *ResizeClusterRequest, opts ...call.Option) (*ResizeClusterResponse, error) { + wireReq, err := resizeClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/resize" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ResizeClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &ResizeClusterResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Resizes a cluster to have a desired number of workers. This will fail unless +// the cluster is in a `RUNNING` state. +func (c *internalClient) ResizeCluster(ctx context.Context, req *ResizeClusterRequest, opts ...call.Option) (*ResizeClusterWaiter, error) { + if req.ClusterId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ClusterId") + } + capturedClusterId := *req.ClusterId + _, err := c.resizeClusterBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &ResizeClusterWaiter{ + poll: c.GetCluster, + clusterId: capturedClusterId, + }, nil +} + +// ResizeClusterWaiter tracks the state of the operation started by ResizeCluster. +type ResizeClusterWaiter struct { + poll func(context.Context, *GetClusterRequest, ...call.Option) (*ClusterInfo, error) + clusterId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *ResizeClusterWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running, ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *ResizeClusterWaiter) Wait(ctx context.Context, opts ...lro.Option) (*ClusterInfo, error) { + var result *ClusterInfo + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running: + result = pollResp + return nil + case ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + message := "(no message)" + if pollResp.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Restarts a Spark cluster with the supplied ID. If the cluster is not +// currently in a `RUNNING` state, nothing will happen. +func (c *internalClient) restartClusterBase(ctx context.Context, req *RestartClusterRequest, opts ...call.Option) (*RestartClusterResponse, error) { + wireReq, err := restartClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/restart" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RestartClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &RestartClusterResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Restarts a Spark cluster with the supplied ID. If the cluster is not +// currently in a `RUNNING` state, nothing will happen. +func (c *internalClient) RestartCluster(ctx context.Context, req *RestartClusterRequest, opts ...call.Option) (*RestartClusterWaiter, error) { + if req.ClusterId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ClusterId") + } + capturedClusterId := *req.ClusterId + _, err := c.restartClusterBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &RestartClusterWaiter{ + poll: c.GetCluster, + clusterId: capturedClusterId, + }, nil +} + +// RestartClusterWaiter tracks the state of the operation started by RestartCluster. +type RestartClusterWaiter struct { + poll func(context.Context, *GetClusterRequest, ...call.Option) (*ClusterInfo, error) + clusterId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *RestartClusterWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running, ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *RestartClusterWaiter) Wait(ctx context.Context, opts ...lro.Option) (*ClusterInfo, error) { + var result *ClusterInfo + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running: + result = pollResp + return nil + case ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + message := "(no message)" + if pollResp.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Starts a terminated Spark cluster with the supplied ID. This works similar to +// `createCluster` except: - The previous cluster id and attributes are +// preserved. - The cluster starts with the last specified cluster size. - If +// the previous cluster was an autoscaling cluster, the current cluster starts +// with the minimum number of nodes. - If the cluster is not currently in a +// “TERMINATED“ state, nothing will happen. - Clusters launched to run a job +// cannot be started. +func (c *internalClient) startClusterBase(ctx context.Context, req *StartClusterRequest, opts ...call.Option) (*StartClusterResponse, error) { + wireReq, err := startClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/start" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StartClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &StartClusterResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Starts a terminated Spark cluster with the supplied ID. This works similar to +// `createCluster` except: - The previous cluster id and attributes are +// preserved. - The cluster starts with the last specified cluster size. - If +// the previous cluster was an autoscaling cluster, the current cluster starts +// with the minimum number of nodes. - If the cluster is not currently in a +// “TERMINATED“ state, nothing will happen. - Clusters launched to run a job +// cannot be started. +func (c *internalClient) StartCluster(ctx context.Context, req *StartClusterRequest, opts ...call.Option) (*StartClusterWaiter, error) { + if req.ClusterId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ClusterId") + } + capturedClusterId := *req.ClusterId + _, err := c.startClusterBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &StartClusterWaiter{ + poll: c.GetCluster, + clusterId: capturedClusterId, + }, nil +} + +// StartClusterWaiter tracks the state of the operation started by StartCluster. +type StartClusterWaiter struct { + poll func(context.Context, *GetClusterRequest, ...call.Option) (*ClusterInfo, error) + clusterId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *StartClusterWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running, ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *StartClusterWaiter) Wait(ctx context.Context, opts ...lro.Option) (*ClusterInfo, error) { + var result *ClusterInfo + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running: + result = pollResp + return nil + case ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + message := "(no message)" + if pollResp.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Unpinning a cluster will allow the cluster to eventually be removed from the +// ListClusters API. Unpinning a cluster that is not pinned will have no effect. +// This API can only be called by workspace admins. +func (c *internalClient) UnpinCluster(ctx context.Context, req *UnpinClusterRequest, opts ...call.Option) (*UnpinClusterResponse, error) { + wireReq, err := unpinClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/unpin" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UnpinClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UnpinClusterResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the configuration of a cluster to match the partial set of attributes +// and size. Denote which fields to update using the `update_mask` field in the +// request body. A cluster can be updated if it is in a `RUNNING` or +// `TERMINATED` state. If a cluster is updated while in a `RUNNING` state, it +// will be restarted so that the new attributes can take effect. If a cluster is +// updated while in a `TERMINATED` state, it will remain `TERMINATED`. The +// updated attributes will take effect the next time the cluster is started +// using the `clusters/start` API. Attempts to update a cluster in any other +// state will be rejected with an `INVALID_STATE` error code. Clusters created +// by the Databricks Jobs service cannot be updated. +func (c *internalClient) updateClusterBase(ctx context.Context, req *UpdateClusterRequest, opts ...call.Option) (*UpdateClusterResponse, error) { + wireReq, err := updateClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/clusters/update" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateClusterResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the configuration of a cluster to match the partial set of attributes +// and size. Denote which fields to update using the `update_mask` field in the +// request body. A cluster can be updated if it is in a `RUNNING` or +// `TERMINATED` state. If a cluster is updated while in a `RUNNING` state, it +// will be restarted so that the new attributes can take effect. If a cluster is +// updated while in a `TERMINATED` state, it will remain `TERMINATED`. The +// updated attributes will take effect the next time the cluster is started +// using the `clusters/start` API. Attempts to update a cluster in any other +// state will be rejected with an `INVALID_STATE` error code. Clusters created +// by the Databricks Jobs service cannot be updated. +func (c *internalClient) UpdateCluster(ctx context.Context, req *UpdateClusterRequest, opts ...call.Option) (*UpdateClusterWaiter, error) { + if req.ClusterId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ClusterId") + } + capturedClusterId := *req.ClusterId + _, err := c.updateClusterBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &UpdateClusterWaiter{ + poll: c.GetCluster, + clusterId: capturedClusterId, + }, nil +} + +// UpdateClusterWaiter tracks the state of the operation started by UpdateCluster. +type UpdateClusterWaiter struct { + poll func(context.Context, *GetClusterRequest, ...call.Option) (*ClusterInfo, error) + clusterId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *UpdateClusterWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running, ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *UpdateClusterWaiter) Wait(ctx context.Context, opts ...lro.Option) (*ClusterInfo, error) { + var result *ClusterInfo + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetClusterRequest{ + ClusterId: &w.clusterId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ClusterState_ClusterState_Running: + result = pollResp + return nil + case ClusterState_ClusterState_Error, ClusterState_ClusterState_Terminated: + message := "(no message)" + if pollResp.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Cancels a pending enforcement on a cluster. After canceling the pending +// enforcement, the cluster will no longer update on the next termination or +// restart. Pending enforcements cannot be canceled when a cluster is in +// `TERMINATING` state. Only workspace admins can cancel pending enforcements. +func (c *internalClient) CancelPendingClusterEnforcement(ctx context.Context, req *CancelPendingClusterEnforcementRequest, opts ...call.Option) (*CancelPendingClusterEnforcementResponse, error) { + wireReq, err := cancelPendingClusterEnforcementRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/clusters:cancelPendingClusterEnforcement" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CancelPendingClusterEnforcementResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &CancelPendingClusterEnforcementResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a cluster to be compliant with the current version of its policy. +// +// If a cluster is updated while in a `TERMINATED` state, it will remain +// `TERMINATED`. The next time the cluster is started, the new attributes will +// take effect. +// +// For clusters in other states, the behavior depends on the `enforce_mode` +// used. +// +// Clusters created by the Databricks Jobs, SDP, or Models services cannot be +// enforced by this API. Instead, use the "Enforce job policy compliance" API to +// enforce policy compliance on jobs. +func (c *internalClient) EnforcePolicyComplianceForCluster(ctx context.Context, req *EnforcePolicyComplianceForClusterRequest, opts ...call.Option) (*EnforcePolicyComplianceForClusterResponse, error) { + wireReq, err := enforcePolicyComplianceForClusterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/clusters/enforce-compliance" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EnforcePolicyComplianceForClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp enforcePolicyComplianceForClusterResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = enforcePolicyComplianceForClusterResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns the policy compliance status of a cluster. Clusters could be out of +// compliance if their policy was updated after the cluster was last edited. +func (c *internalClient) GetPolicyComplianceForCluster(ctx context.Context, req *GetPolicyComplianceForClusterRequest, opts ...call.Option) (*GetPolicyComplianceForClusterResponse, error) { + wireReq, err := getPolicyComplianceForClusterRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/clusters/get-compliance" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "cluster_id", wireReq.ClusterId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPolicyComplianceForClusterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPolicyComplianceForClusterResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPolicyComplianceForClusterResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns the policy compliance status of all clusters that use a given policy. +// Clusters could be out of compliance if their policy was updated after the +// cluster was last edited. +func (c *internalClient) ListClusterComplianceForPolicy(ctx context.Context, req *ListClusterComplianceForPolicyRequest, opts ...call.Option) (*ListClusterComplianceForPolicyResponse, error) { + wireReq, err := listClusterComplianceForPolicyRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/clusters/list-compliance" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "policy_id", wireReq.PolicyId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListClusterComplianceForPolicyResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listClusterComplianceForPolicyResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listClusterComplianceForPolicyResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListClusterComplianceForPolicyIter returns an iterator that iterates +// over the results of ListClusterComplianceForPolicy. +// +// For example: +// +// for item, err := range c.ListClusterComplianceForPolicyIter(ctx, &ListClusterComplianceForPolicyRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListClusterComplianceForPolicy call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListClusterComplianceForPolicy directly. +func (c *internalClient) ListClusterComplianceForPolicyIter(ctx context.Context, req *ListClusterComplianceForPolicyRequest, opts ...call.Option) iter.Seq2[*ClusterCompliance, error] { + return func(yield func(*ClusterCompliance, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListClusterComplianceForPolicyRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListClusterComplianceForPolicy(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Clusters { + if !yield(&resp.Clusters[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} diff --git a/clusters/v2/genhelper.go b/clusters/v2/genhelper.go new file mode 100755 index 0000000..55c4049 --- /dev/null +++ b/clusters/v2/genhelper.go @@ -0,0 +1,243 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusters + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/clusters/v2/model.go b/clusters/v2/model.go new file mode 100755 index 0000000..6de38c9 --- /dev/null +++ b/clusters/v2/model.go @@ -0,0 +1,3425 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusters + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// Availability type used for all subsequent nodes past the `first_on_demand` +// ones. +// +// Note: If `first_on_demand` is zero, this availability type will be used for +// the entire cluster. +type AwsAvailability string + +const ( + AwsAvailability_Unspecified AwsAvailability = "" + // Use spot instances. + AwsAvailability_Spot AwsAvailability = "SPOT" + // Use on-demand instances. + AwsAvailability_OnDemand AwsAvailability = "ON_DEMAND" + // Preferably use spot instances, but fall back to on-demand instances if spot + // instances cannot be acquired (e.g., if AWS spot prices are too high). + AwsAvailability_SpotWithFallback AwsAvailability = "SPOT_WITH_FALLBACK" +) + +// Availability type used for all subsequent nodes past the `first_on_demand` +// ones. Note: If `first_on_demand` is zero, this availability type will be used +// for the entire cluster. +type AzureAvailability string + +const ( + AzureAvailability_Unspecified AzureAvailability = "" + // Use spot instances. + AzureAvailability_SpotAzure AzureAvailability = "SPOT_AZURE" + // Use on-demand instances. + AzureAvailability_OnDemandAzure AzureAvailability = "ON_DEMAND_AZURE" + // Preferably use spot instances, but fall back to on-demand instances if spot + // instances cannot be acquired (e.g., if Azure is out of Quota). + AzureAvailability_SpotWithFallbackAzure AzureAvailability = "SPOT_WITH_FALLBACK_AZURE" +) + +type CloudProviderNodeStatus string + +const ( + CloudProviderNodeStatus_Unspecified CloudProviderNodeStatus = "" + CloudProviderNodeStatus_NotEnabledOnSubscription CloudProviderNodeStatus = "NotEnabledOnSubscription" + CloudProviderNodeStatus_NotAvailableInRegion CloudProviderNodeStatus = "NotAvailableInRegion" +) + +// Possible reasons a cluster might be edited. +type ClusterEditReason string + +const ( + ClusterEditReason_Unspecified ClusterEditReason = "" + // Cluster was initially created. + ClusterEditReason_Creation ClusterEditReason = "CREATION" + // Cluster was manually edited by the user. + ClusterEditReason_ManualEdit ClusterEditReason = "MANUAL_EDIT" + // Cluster was edited as part of a policy enforcement. + ClusterEditReason_PolicyEnforcement ClusterEditReason = "POLICY_ENFORCEMENT" + // Cluster was edited as part of a policy enforcement that was scheduled on the + // next cluster termination / restart. + ClusterEditReason_DeferredPolicyEnforcement ClusterEditReason = "DEFERRED_POLICY_ENFORCEMENT" +) + +// The kind of compute described by this compute specification. +// +// Depending on `kind`, different validations and default values will be +// applied. +// +// Clusters with `kind = CLASSIC_PREVIEW` support the following fields, whereas +// clusters with no specified `kind` do not. * +// [is_single_node](/api/workspace/clusters/create#is_single_node) * +// [use_ml_runtime](/api/workspace/clusters/create#use_ml_runtime) +// +// By using the [simple form], your clusters are automatically using `kind = +// CLASSIC_PREVIEW`. +// +// [simple form]: https://docs.databricks.com/compute/simple-form.html +type ComputeKind string + +const ( + ComputeKind_Unspecified ComputeKind = "" + ComputeKind_ClassicPreview ComputeKind = "CLASSIC_PREVIEW" +) + +// Confidential computing technology for GCP instances. Aligns with gcloud's +// --confidential-compute-type flag and the REST API's +// confidentialInstanceConfig.confidentialInstanceType field. See: +// https://cloud.google.com/confidential-computing/confidential-vm/docs/create-a-confidential-vm-instance +type ConfidentialComputeType string + +const ( + ConfidentialComputeType_Unspecified ConfidentialComputeType = "" + ConfidentialComputeType_ConfidentialComputeTypeNone ConfidentialComputeType = "CONFIDENTIAL_COMPUTE_TYPE_NONE" + ConfidentialComputeType_SevSnp ConfidentialComputeType = "SEV_SNP" +) + +type DataPlaneClusterEventType string + +const ( + DataPlaneClusterEventType_Unspecified DataPlaneClusterEventType = "" + DataPlaneClusterEventType_NodeBlacklisted DataPlaneClusterEventType = "NODE_BLACKLISTED" + DataPlaneClusterEventType_NodeExcludedDecommissioned DataPlaneClusterEventType = "NODE_EXCLUDED_DECOMMISSIONED" +) + +// Data security mode decides what data governance model to use when accessing +// data from a cluster. +// +// * `DATA_SECURITY_MODE_AUTO`: will choose the most appropriate +// access mode depending on your compute configuration. * +// `DATA_SECURITY_MODE_STANDARD`: A secure cluster that can be shared by +// multiple users. Cluster users are fully isolated so that they cannot see each +// other’s data and credentials. Most data governance features are supported +// in this mode. But programming languages and cluster features might be +// limited. * `DATA_SECURITY_MODE_DEDICATED`: A secure cluster that can only be +// exclusively used by a single user specified in `single_user_name`. Most +// programming languages, cluster features and data governance features are +// available in this mode. +// +// The following modes are legacy aliases for the above modes: +// +// * `USER_ISOLATION`: Legacy alias for `DATA_SECURITY_MODE_STANDARD`. * +// `SINGLE_USER`: Legacy alias for `DATA_SECURITY_MODE_DEDICATED`. +// +// The following modes are deprecated starting with Databricks Runtime 15.0 and +// will be removed for future Databricks Runtime versions: +// +// * `LEGACY_TABLE_ACL`: This mode is for users migrating from legacy Table ACL +// clusters. * `LEGACY_PASSTHROUGH`: This mode is for users migrating from +// legacy Passthrough on high concurrency clusters. * `LEGACY_SINGLE_USER`: This +// mode is for users migrating from legacy Passthrough on standard clusters. * +// `LEGACY_SINGLE_USER_STANDARD`: This mode provides a way that doesn’t have +// UC nor passthrough enabled. +type DataSecurityMode string + +const ( + DataSecurityMode_Unspecified DataSecurityMode = "" + // No security isolation for multiple users sharing the cluster. Data governance + // features are not available in this mode. + DataSecurityMode_None DataSecurityMode = "NONE" + // Legacy alias for `DATA_SECURITY_MODE_DEDICATED`. + DataSecurityMode_SingleUser DataSecurityMode = "SINGLE_USER" + // Legacy alias for `DATA_SECURITY_MODE_STANDARD`. + DataSecurityMode_UserIsolation DataSecurityMode = "USER_ISOLATION" + // This mode is for users migrating from legacy Table ACL clusters. + DataSecurityMode_LegacyTableAcl DataSecurityMode = "LEGACY_TABLE_ACL" + // This mode is for users migrating from legacy Passthrough on high concurrency + // clusters. + DataSecurityMode_LegacyPassthrough DataSecurityMode = "LEGACY_PASSTHROUGH" + // This mode is for users migrating from legacy Passthrough on standard + // clusters. + DataSecurityMode_LegacySingleUser DataSecurityMode = "LEGACY_SINGLE_USER" + // This is mode where single user is enforced but no actual security feature + // enabled. + DataSecurityMode_LegacySingleUserStandard DataSecurityMode = "LEGACY_SINGLE_USER_STANDARD" + // A secure cluster that can be shared by multiple users. Cluster users are + // fully isolated so that they cannot see each other's data and credentials. + // Most data governance features are supported in this mode. But programming + // languages and cluster features might be limited. + DataSecurityMode_DataSecurityModeStandard DataSecurityMode = "DATA_SECURITY_MODE_STANDARD" + // A secure cluster that can only be exclusively used by a single user specified + // in `single_user_name`. Most programming languages, cluster features and data + // governance features are available in this mode. + DataSecurityMode_DataSecurityModeDedicated DataSecurityMode = "DATA_SECURITY_MODE_DEDICATED" + // Databricks will choose `DATA_SECURITY_MODE_STANDARD` or + // `DATA_SECURITY_MODE_DEDICATED` depending on the compute configuration. + DataSecurityMode_DataSecurityModeAuto DataSecurityMode = "DATA_SECURITY_MODE_AUTO" +) + +// Controls dependency configuration for the cluster. +// +// * `DEPENDENCY_MODE_AUTO`: will choose the most appropriate +// dependency mode based on your compute configuration. * +// `DEPENDENCY_MODE_ENVIRONMENTS`: Enables a unified dependency management +// experience across classic and serverless, resulting in increased stability +// and performance. Supported only on DBR 19+ in Standard access mode. * +// `DEPENDENCY_MODE_CLUSTER_LIBRARIES`: Legacy mode: dependencies come from +// cluster libraries and init scripts. +type DependencyMode string + +const ( + DependencyMode_Unspecified DependencyMode = "" + DependencyMode_DependencyModeEnvironments DependencyMode = "DEPENDENCY_MODE_ENVIRONMENTS" + DependencyMode_DependencyModeClusterLibraries DependencyMode = "DEPENDENCY_MODE_CLUSTER_LIBRARIES" + DependencyMode_DependencyModeAuto DependencyMode = "DEPENDENCY_MODE_AUTO" +) + +// All EBS volume types that supports. See +// https://aws.amazon.com/ebs/details/ for details. +type EbsVolumeType string + +const ( + EbsVolumeType_Unspecified EbsVolumeType = "" + // Provision extra storage using AWS gp2 EBS volumes. + EbsVolumeType_GeneralPurposeSsd EbsVolumeType = "GENERAL_PURPOSE_SSD" + // Provision extra storage using AWS st1 volumes. + EbsVolumeType_ThroughputOptimizedHdd EbsVolumeType = "THROUGHPUT_OPTIMIZED_HDD" +) + +// This field determines whether the instance pool will contain preemptible VMs, +// on-demand VMs, or preemptible VMs with a fallback to on-demand VMs if the +// former is unavailable. +type GcpAvailability string + +const ( + GcpAvailability_Unspecified GcpAvailability = "" + GcpAvailability_PreemptibleGcp GcpAvailability = "PREEMPTIBLE_GCP" + GcpAvailability_OnDemandGcp GcpAvailability = "ON_DEMAND_GCP" + GcpAvailability_PreemptibleWithFallbackGcp GcpAvailability = "PREEMPTIBLE_WITH_FALLBACK_GCP" +) + +type GetEventsOrder string + +const ( + GetEventsOrder_Unspecified GetEventsOrder = "" + GetEventsOrder_Desc GetEventsOrder = "DESC" + GetEventsOrder_Asc GetEventsOrder = "ASC" +) + +type RuntimeEngine string + +const ( + RuntimeEngine_Unspecified RuntimeEngine = "" + // Use standard engine + RuntimeEngine_Standard RuntimeEngine = "STANDARD" + // Use Photon engine + RuntimeEngine_Photon RuntimeEngine = "PHOTON" +) + +// The status code indicating why the cluster was terminated +type TerminationCode string + +const ( + TerminationCode_Unspecified TerminationCode = "" + // A user terminated the cluster directly. Parameters should include a + // ``username`` field that indicates the specific user who terminated the + // cluster. + TerminationCode_UserRequest TerminationCode = "USER_REQUEST" + // This cluster was launched by a Job, and terminated when the Job completed. + TerminationCode_JobFinished TerminationCode = "JOB_FINISHED" + // This cluster was terminated since it was idle. + TerminationCode_Inactivity TerminationCode = "INACTIVITY" + // The instance that hosted the spark driver was terminated by the cloud + // provider. In AWS, for example, AWS may retire instances and directly shut + // them down. Parameters should include an ``aws_instance_state_reason`` field + // indicating the AWS-provided reason why the instance was terminated. + TerminationCode_CloudProviderShutdown TerminationCode = "CLOUD_PROVIDER_SHUTDOWN" + // Databricks may lose connection to services on the driver instance. One such + // case is when problems arise in cloud networking infrastructure, or when the + // instance itself becomes unhealthy. + TerminationCode_CommunicationLost TerminationCode = "COMMUNICATION_LOST" + // Databricks may hit cloud provider failures when requesting instances to + // launch clusters. For example, AWS limits the number of running instances and + // EBS volumes. If you ask Databricks to launch a cluster that requires + // instances or EBS volumes that exceed your AWS limit, the cluster will fail + // with this status code. Parameters should include one of + // ``aws_api_error_code``, ``aws_instance_state_reason``, or + // ``aws_spot_request_status`` to indicate the AWS-provided reason why + // Databricks could not request the required instances for the cluster. + TerminationCode_CloudProviderLaunchFailure TerminationCode = "CLOUD_PROVIDER_LAUNCH_FAILURE" + // Databricks cannot load and execute a cluster-scoped init script on one of the + // cluster's nodes, or the init script terminates with a non-zero exit code or + // there was a general failure during the loading/executing of init scripts that + // does not pertain to any specific script. + TerminationCode_InitScriptFailure TerminationCode = "INIT_SCRIPT_FAILURE" + // The Spark driver failed to start. Possible reasons may include incompatible + // libraries and initialization scripts that corrupted the Spark container. + TerminationCode_SparkStartupFailure TerminationCode = "SPARK_STARTUP_FAILURE" + // Cannot launch the cluster because the user specified an invalid argument. For + // example, the use might specify an invalid spark version for the cluster. + TerminationCode_InvalidArgument TerminationCode = "INVALID_ARGUMENT" + // While launching this cluster, Databricks failed to complete critical setup + // steps, terminating the cluster. + TerminationCode_UnexpectedLaunchFailure TerminationCode = "UNEXPECTED_LAUNCH_FAILURE" + // Databricks encountered an unexpected error which forced the running cluster + // to be terminated. Please contact Databricks support for additional details. + TerminationCode_InternalError TerminationCode = "INTERNAL_ERROR" + // Databricks was not able to access instances in order to start the cluster. + // This can be a transient networking issue. If the problem persists, this + // usually indicates a networking environment misconfiguration. + TerminationCode_InstanceUnreachable TerminationCode = "INSTANCE_UNREACHABLE" + // Blocked upsize requests for the workspace according to + // https://databricks.atlassian.net/wiki/spaces/UN/pages/934088320/Banning+Workspace+Upsize+Runbook + TerminationCode_RequestRejected TerminationCode = "REQUEST_REJECTED" + // The cluster was terminated because it was running in a trial workspace that + // expired. + TerminationCode_TrialExpired TerminationCode = "TRIAL_EXPIRED" + // The cluster was terminated because no response from the chauffeur could be + // received. We name this "DRIVER_" instead of "CHAUFFEUR_" since chauffeur is + // non-external terminology + TerminationCode_DriverUnreachable TerminationCode = "DRIVER_UNREACHABLE" + // Spark error on startup + TerminationCode_SparkError TerminationCode = "SPARK_ERROR" + // Driver unresponsive + TerminationCode_DriverUnresponsive TerminationCode = "DRIVER_UNRESPONSIVE" + // Metastore component unhealthy + TerminationCode_MetastoreComponentUnhealthy TerminationCode = "METASTORE_COMPONENT_UNHEALTHY" + // DBFS component unhealthy + TerminationCode_DbfsComponentUnhealthy TerminationCode = "DBFS_COMPONENT_UNHEALTHY" + // Execution component unhealthy + TerminationCode_ExecutionComponentUnhealthy TerminationCode = "EXECUTION_COMPONENT_UNHEALTHY" + // Databricks may hit the azure resource manager request limit. Which will keep + // the Azure SDK from issuing any read or write request to Azure resource + // manager. The request limit is applied to each subscription every hour, thus + // retry after an hour or changing to a smaller cluster size might help to + // resolve the issue. Please check the following link for more information: + // https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-request-limits + TerminationCode_AzureResourceManagerThrottling TerminationCode = "AZURE_RESOURCE_MANAGER_THROTTLING" + // Databricks may hit the azure resource provider request limit. Specifically, + // the API request rate to the specific resource type (Compute, Network, etc..) + // can't exceed the limit. Retry might help to resolve the issue. Please check + // the following link for more information: + // https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/ + // troubleshooting-throttling-errors + TerminationCode_AzureResourceProviderThrottling TerminationCode = "AZURE_RESOURCE_PROVIDER_THROTTLING" + // The cluster was terminated due to an error in the network configuration. + TerminationCode_NetworkConfigurationFailure TerminationCode = "NETWORK_CONFIGURATION_FAILURE" + // Databricks encountered an unexpected error while launching containers on + // worker nodes for the cluster, terminating the cluster. + TerminationCode_ContainerLaunchFailure TerminationCode = "CONTAINER_LAUNCH_FAILURE" + // Instance pool backed cluster specific failure + TerminationCode_InstancePoolClusterFailure TerminationCode = "INSTANCE_POOL_CLUSTER_FAILURE" + // Cluster start successfully completed but skipped some instances which were + // slow to launch + TerminationCode_SkippedSlowNodes TerminationCode = "SKIPPED_SLOW_NODES" + // Attach projects failure + TerminationCode_AttachProjectFailure TerminationCode = "ATTACH_PROJECT_FAILURE" + // Attach projects failure + TerminationCode_UpdateInstanceProfileFailure TerminationCode = "UPDATE_INSTANCE_PROFILE_FAILURE" + // Cluster terminated due to database failure + TerminationCode_DatabaseConnectionFailure TerminationCode = "DATABASE_CONNECTION_FAILURE" + // Databricks cannot handle the request at this moment. Please try again later + // and contact Databricks if the problem persists. + TerminationCode_RequestThrottled TerminationCode = "REQUEST_THROTTLED" + // SelfBootstrap failure. Either self-bootstrap fast fail or node daemon ping + // timeout + TerminationCode_SelfBootstrapFailure TerminationCode = "SELF_BOOTSTRAP_FAILURE" + // Databricks cannot load and execute a global init script on one of the + // cluster's nodes, or the init script terminates with a non-zero exit code. + TerminationCode_GlobalInitScriptFailure TerminationCode = "GLOBAL_INIT_SCRIPT_FAILURE" + // Container launch timed out downloading the spark image. This can happen if + // the customer has byo-vpc/vnet and the download of large files is being + // throttled. + TerminationCode_SlowImageDownload TerminationCode = "SLOW_IMAGE_DOWNLOAD" + // Container setup failed due to an invalid Spark image. + TerminationCode_InvalidSparkImage TerminationCode = "INVALID_SPARK_IMAGE" + // If the ngrok tunnel token provisioning fails for any reason, for example + // hitting the max capacity of allowed ngrok tokens. (ES-32083) + TerminationCode_NpipTunnelTokenFailure TerminationCode = "NPIP_TUNNEL_TOKEN_FAILURE" + // Hive Metastore provisioning failue in launch container step + TerminationCode_HiveMetastoreProvisioningFailure TerminationCode = "HIVE_METASTORE_PROVISIONING_FAILURE" + // Occurs when the deployment template we submit to Azure violates their + // requirements. Typical scenarios: - Wrong parameter key/value used - Exceed + // the limit for certain parameter + TerminationCode_AzureInvalidDeploymentTemplate TerminationCode = "AZURE_INVALID_DEPLOYMENT_TEMPLATE" + // The set of un-categorized failure responses from Azure when we launch + // instance resources using deployment template + TerminationCode_AzureUnexpectedDeploymentTemplateFailure TerminationCode = "AZURE_UNEXPECTED_DEPLOYMENT_TEMPLATE_FAILURE" + // Subnet (typically Azure vnet injected) has run out of ip addresses + TerminationCode_SubnetExhaustedFailure TerminationCode = "SUBNET_EXHAUSTED_FAILURE" + // Timeout to ping the nodeDaemon, possible reason: nodeDaemon didn't start + // (configuration issue), network connectivity issue + TerminationCode_BootstrapTimeout TerminationCode = "BOOTSTRAP_TIMEOUT" + // Bootstrap timeout due to script download failure + TerminationCode_StorageDownloadFailure TerminationCode = "STORAGE_DOWNLOAD_FAILURE" + // Bootstrap timeout due to get runbook failure + TerminationCode_ControlPlaneRequestFailure TerminationCode = "CONTROL_PLANE_REQUEST_FAILURE" + // Bootstrap timeout due to Azure Extension Service Failure + TerminationCode_BootstrapTimeoutCloudProviderException TerminationCode = "BOOTSTRAP_TIMEOUT_CLOUD_PROVIDER_EXCEPTION" + // Could not find enough of the requested instance type in the requested AZ. + // Often related to Auto AZ. + TerminationCode_AwsInsufficientInstanceCapacityFailure TerminationCode = "AWS_INSUFFICIENT_INSTANCE_CAPACITY_FAILURE" + // Container setup failure due to docker image pulling failure + TerminationCode_DockerImagePullFailure TerminationCode = "DOCKER_IMAGE_PULL_FAILURE" + // Failures during azure vnet configuration. For example, a workspace with VNet + // injection had incorrect DNS settings that blocked access to worker artifacts. + TerminationCode_AzureVnetConfigurationFailure TerminationCode = "AZURE_VNET_CONFIGURATION_FAILURE" + // Bootstrap failure due to Ngrok tunnel setup timeout or failure. For example, + // if the worker node is unable to reach the Ngrok tunnel domain. + TerminationCode_NpipTunnelSetupFailure TerminationCode = "NPIP_TUNNEL_SETUP_FAILURE" + // Lack authorization for cluster operation. For example, awsApiErrorCode: + // 'AccessDenied' or 'UnauthorizedOperation'. + TerminationCode_AwsAuthorizationFailure TerminationCode = "AWS_AUTHORIZATION_FAILURE" + // request comes form Nephos resource pool auto management + TerminationCode_NephosResourceManagement TerminationCode = "NEPHOS_RESOURCE_MANAGEMENT" + // Container setup failed during container registration to security daemon due + // to STS endpoint connection error. + TerminationCode_StsClientSetupFailure TerminationCode = "STS_CLIENT_SETUP_FAILURE" + // Container setup failed during registration to security daemon due to an + // unspecified error. + TerminationCode_SecurityDaemonRegistrationException TerminationCode = "SECURITY_DAEMON_REGISTRATION_EXCEPTION" + // The maximum request rate permitted by the Amazon EC2 APIs has been exceeded + // for your account. + TerminationCode_AwsRequestLimitExceeded TerminationCode = "AWS_REQUEST_LIMIT_EXCEEDED" + // We don't have enough addresses in the subnet for the instances in the + // request. + TerminationCode_AwsInsufficientFreeAddressesInSubnetFailure TerminationCode = "AWS_INSUFFICIENT_FREE_ADDRESSES_IN_SUBNET_FAILURE" + // The request is not supported (This is a vague error code that can be thrown + // for a lot of reasons.) + TerminationCode_AwsUnsupportedFailure TerminationCode = "AWS_UNSUPPORTED_FAILURE" + // Could not find enough azure resources to fulfill the request. + TerminationCode_AzureQuotaExceededException TerminationCode = "AZURE_QUOTA_EXCEEDED_EXCEPTION" + // NOTE: This is currently used by exceptions with messages that are classified + // as user errors. + TerminationCode_AzureOperationNotAllowedException TerminationCode = "AZURE_OPERATION_NOT_ALLOWED_EXCEPTION" + // Failure when mounting remote NFS to container + TerminationCode_NfsMountFailure TerminationCode = "NFS_MOUNT_FAILURE" + // K8S failed to upscale to acquire new nodes + TerminationCode_K8sAutoscalingFailure TerminationCode = "K8S_AUTOSCALING_FAILURE" + // DBR Cluster launched on K8s (i.e. CMv2) has failed to start up in time + TerminationCode_K8sDbrClusterLaunchTimeout TerminationCode = "K8S_DBR_CLUSTER_LAUNCH_TIMEOUT" + // Container launch failed while downloading the spark image. Catch all for if + // anything goes wrong while downloading and extracting the spark tarball. + TerminationCode_SparkImageDownloadFailure TerminationCode = "SPARK_IMAGE_DOWNLOAD_FAILURE" + // Azure VM Extension failure during instance bootstrap + TerminationCode_AzureVmExtensionFailure TerminationCode = "AZURE_VM_EXTENSION_FAILURE" + // Workspace was cancelled hence deny/terminate the cluster + TerminationCode_WorkspaceCancelledError TerminationCode = "WORKSPACE_CANCELLED_ERROR" + // The spot instance count in an account has exceeded the limit + TerminationCode_AwsMaxSpotInstanceCountExceededFailure TerminationCode = "AWS_MAX_SPOT_INSTANCE_COUNT_EXCEEDED_FAILURE" + // Cluster is terminated because the services are temporarily unavailable. This + // normally happens when CM is restarting and draining execution contexts, or + // IM/Delegate is overloaded, so that it will not be able to retry the instance + // launch request. + TerminationCode_TemporarilyUnavailable TerminationCode = "TEMPORARILY_UNAVAILABLE" + // Bootstrap failure due to error during worker setup, usually due to an issue + // with disk or gpu setup. See SetupCommandBuilder for other possible causes + TerminationCode_WorkerSetupFailure TerminationCode = "WORKER_SETUP_FAILURE" + // Cluster failure due to IP space exhaustion. For example on CMv2, Kubernetes + // will fail to scale up new nodes if the pod IP CIDR block is exhausted. + TerminationCode_IpExhaustionFailure TerminationCode = "IP_EXHAUSTION_FAILURE" + // Could not find enough GCP resources to fulfill the request. TODO: It's very + // unfortunate that we have per-cloud termination reasons while we should have + // cloud-agnostic termination reasons. For example, we should consolidate + // {AZURE_QUOTA_EXCEEDED_EXCEPTION, AWS_REQUEST_LIMIT_EXCEEDED and + // GCP_QUOTA_EXCEEDED}, {AWS_INSUFFICIENT_FREE_ADDRESSES_IN_SUBNET_FAILURE, + // IP_EXHAUSTION_FAILURE}, etc. + TerminationCode_GcpQuotaExceeded TerminationCode = "GCP_QUOTA_EXCEEDED" + // Cloud provider is undergoing a transient resource throttling. This is + // retryable. + TerminationCode_CloudProviderResourceStockout TerminationCode = "CLOUD_PROVIDER_RESOURCE_STOCKOUT" + // The GCP service account associated with the DBR cluster is deleted. + TerminationCode_GcpServiceAccountDeleted TerminationCode = "GCP_SERVICE_ACCOUNT_DELETED" + // Legit cluster termination in Azure caused by customer revoking the key + // permission used for managed-disks encryption + TerminationCode_AzureByokKeyPermissionFailure TerminationCode = "AZURE_BYOK_KEY_PERMISSION_FAILURE" + // Termination because of spot instance terminated by cloud provider + TerminationCode_SpotInstanceTermination TerminationCode = "SPOT_INSTANCE_TERMINATION" + // Termination because of unsupported azure ephemeral os disk setup + TerminationCode_AzureEphemeralDiskFailure TerminationCode = "AZURE_EPHEMERAL_DISK_FAILURE" + // The cluster was terminated because we detected an abusive runtime behavior + // that violated Terms of Service or Acceptable Use Policy. + TerminationCode_AbuseDetected TerminationCode = "ABUSE_DETECTED" + // Failed to pull DBR images due to permission error. + TerminationCode_ImagePullPermissionDenied TerminationCode = "IMAGE_PULL_PERMISSION_DENIED" + // Workspace configuration is in error state due to configuration issue or ACL + // modification by the customer side + TerminationCode_WorkspaceConfigurationError TerminationCode = "WORKSPACE_CONFIGURATION_ERROR" + // Catch all error for all secret resolution issues in cluster launch. This + // should be alerted on, and is considered a server error. This can be split out + // into other cases if there are client errors - for e.g. INVALID_ARGUMENT is + // used for secrets that don't exist and permission issues + TerminationCode_SecretResolutionError TerminationCode = "SECRET_RESOLUTION_ERROR" + // Failure due to an instance being of an unsupported type. This is used when an + // instance in an EC2 fleet is of an unrecognized type, or an invalid type (i.e. + // graviton when we don't want graviton instances). This should be alerted on. + TerminationCode_UnsupportedInstanceType TerminationCode = "UNSUPPORTED_INSTANCE_TYPE" + // Failed during instance bootstrap with error code Cannot convert NVMe-based + // dev id + TerminationCode_CloudProviderDiskSetupFailure TerminationCode = "CLOUD_PROVIDER_DISK_SETUP_FAILURE" + // Exception when setting up instances using ssh bootstrap + TerminationCode_SshBootstrapFailure TerminationCode = "SSH_BOOTSTRAP_FAILURE" + // Failed during instance bootstrap with error code Cannot convert NVMe-based + // dev id + TerminationCode_AwsInaccessibleKmsKeyFailure TerminationCode = "AWS_INACCESSIBLE_KMS_KEY_FAILURE" + // The bootstrapping init-containers in Spark failed or timed out, blocking the + // Spark container from bootstrapping. This is a refinement of + // `SPARK_STARTUP_FAILURE`. (init-containers are a bootstrapping step owned by + // Databricks) + TerminationCode_InitContainerNotFinished TerminationCode = "INIT_CONTAINER_NOT_FINISHED" + // Container launch failed due to storage servers throttling our download of + // spark images. Can happen due to transient spikes of downloads overloading + // storage servers or gradual increase in usage. In the latter case we need to + // increase the number of storage servers in the region to help spread load. + TerminationCode_SparkImageDownloadThrottled TerminationCode = "SPARK_IMAGE_DOWNLOAD_THROTTLED" + // The spark image specified for the cluster was not found when attempting to + // download. Usually due to the customer custom specifying a bad image. + TerminationCode_SparkImageNotFound TerminationCode = "SPARK_IMAGE_NOT_FOUND" + // Indicates that the cloud provider operations performed for the cluster were + // dropped due to an influx in load in the cloud provider and had to be dropped + // from our end to alleviate pressure within the DelegateRpcClient. Please see + // go/cmloadshedding for more. + TerminationCode_ClusterOperationThrottled TerminationCode = "CLUSTER_OPERATION_THROTTLED" + // The error code can be used to indicate a request misses its deadline. Can be + // used for either request timeouts or missed deadlines (i.e. a request is not + // completed as it was processed after its specified deadline) + TerminationCode_ClusterOperationTimeout TerminationCode = "CLUSTER_OPERATION_TIMEOUT" + // This error code is used to terminate long-running Generic compute jobs in + // Serverless Environment as part of the NephosLongRunning watcher running in + // Cluster Monitor Service. + TerminationCode_ServerlessLongRunningTerminated TerminationCode = "SERVERLESS_LONG_RUNNING_TERMINATED" + // This error code is used when the cluster is terminated due to its instances + // fail with partial failure from Azure packed deployments. In Azure, we might + // pack multiple launch requests in one deployment template in order to avoid + // the 800 templates limit on Azure side. If the packed deployment fails + // multiple times, the cluster could be terminated by this + // [[AZURE_PACKED_DEPLOYMENT_PARTIAL_FAILURE]] termination code. + TerminationCode_AzurePackedDeploymentPartialFailure TerminationCode = "AZURE_PACKED_DEPLOYMENT_PARTIAL_FAILURE" + // The instances acquired from a pool in IMv2 do not have a valid worker image + // to be used in the cluster launch. This usually occurs after AMI/VHD upgrades, + // worker branch updates, etc. + TerminationCode_InvalidWorkerImageFailure TerminationCode = "INVALID_WORKER_IMAGE_FAILURE" + // Worker environment version was changed due to workspace network or CMK + // update. + TerminationCode_WorkspaceUpdate TerminationCode = "WORKSPACE_UPDATE" + // The parameter user specified or the user account to create the cluster is + // invalid according to AWS. + TerminationCode_InvalidAwsParameter TerminationCode = "INVALID_AWS_PARAMETER" + // ** Only relevant on k8s dataplanes (i.e. clusters launched with CMv2 - not + // CMv1). + // + // k8s evicted the driver pod due to disk pressure on the driver node. This is + // likely due to a customer job consuming too much disk and so this is + // classified as a customer issue. + TerminationCode_DriverOutOfDisk TerminationCode = "DRIVER_OUT_OF_DISK" + // ** Only relevant on k8s dataplanes (i.e. clusters launched with CMv2 - not + // CMv1). + // + // k8s evicted the driver pod due to memory pressure on the driver node. A + // customer job consuming significant amounts of memory should not be able to + // trigger this as the driver container would OOM first (we set memory limits on + // our pods). Thus this termination reason will be considered a databricks + // issue. + TerminationCode_DriverOutOfMemory TerminationCode = "DRIVER_OUT_OF_MEMORY" + // ** Only relevant on k8s dataplanes (i.e. clusters launched with CMv2 - not + // CMv1). Original driver pod took too long to become ready and timed out. + TerminationCode_DriverLaunchTimeout TerminationCode = "DRIVER_LAUNCH_TIMEOUT" + // ** Only relevant on k8s dataplanes (i.e. clusters launched with CMv2 - not + // CMv1). Unexpected failure during driver pod launch. + TerminationCode_DriverUnexpectedFailure TerminationCode = "DRIVER_UNEXPECTED_FAILURE" + // ** Only relevant on k8s dataplanes (i.e. clusters launched with CMv2 - not + // CMv1). Unexpected new driver pod created + TerminationCode_UnexpectedPodRecreation TerminationCode = "UNEXPECTED_POD_RECREATION" + // Failure due to disabled or inaccessible CMK. + TerminationCode_GcpInaccessibleKmsKeyFailure TerminationCode = "GCP_INACCESSIBLE_KMS_KEY_FAILURE" + // Failure due to missing/incorrect permission setup on CMK. + TerminationCode_GcpKmsKeyPermissionDenied TerminationCode = "GCP_KMS_KEY_PERMISSION_DENIED" + // Driver pod evicted in Nephos + TerminationCode_DriverEviction TerminationCode = "DRIVER_EVICTION" + // User request for termination directly to cloud + TerminationCode_UserInitiatedVmTermination TerminationCode = "USER_INITIATED_VM_TERMINATION" + // GCP Specific IAM API timeout issues during Workload Idenitity (Cluster + // Identity) binding process + TerminationCode_GcpIamTimeout TerminationCode = "GCP_IAM_TIMEOUT" + // Could not find enough AWS resources to fulfill the request + TerminationCode_AwsResourceQuotaExceeded TerminationCode = "AWS_RESOURCE_QUOTA_EXCEEDED" + // Cloud account setup has some error (e.g. pending email verification, blocked) + TerminationCode_CloudAccountSetupFailure TerminationCode = "CLOUD_ACCOUNT_SETUP_FAILURE" + // The specified key pair name does not exist. + TerminationCode_AwsInvalidKeyPair TerminationCode = "AWS_INVALID_KEY_PAIR" + // Driver pod creation failure in nephos + TerminationCode_DriverPodCreationFailure TerminationCode = "DRIVER_POD_CREATION_FAILURE" + // Cluster terminated manually by on-call due to emergency maintenance + TerminationCode_MaintenanceMode TerminationCode = "MAINTENANCE_MODE" + // Nephos internal error due to insufficient provisioned k8s capacity or + // insufficient cloud quota + TerminationCode_InternalCapacityFailure TerminationCode = "INTERNAL_CAPACITY_FAILURE" + // Nephos: could not acquire executor pods from pod pool + TerminationCode_ExecutorPodUnscheduled TerminationCode = "EXECUTOR_POD_UNSCHEDULED" + // Artifact download failed because it was too slow + TerminationCode_StorageDownloadFailureSlow TerminationCode = "STORAGE_DOWNLOAD_FAILURE_SLOW" + // Artifact download failed because it was throttled by the download server + TerminationCode_StorageDownloadFailureThrottled TerminationCode = "STORAGE_DOWNLOAD_FAILURE_THROTTLED" + // The cluster was terminated because the size of the dynamic spark conf + // exceeded the limit. + TerminationCode_DynamicSparkConfSizeExceeded TerminationCode = "DYNAMIC_SPARK_CONF_SIZE_EXCEEDED" + // Failure to update the instance profile for the cluster. + TerminationCode_AwsInstanceProfileUpdateFailure TerminationCode = "AWS_INSTANCE_PROFILE_UPDATE_FAILURE" + // The instance pool did not exist when the cluster was launched. + TerminationCode_InstancePoolNotFound TerminationCode = "INSTANCE_POOL_NOT_FOUND" + // Attempting to launch more instances was rejected as it would exceed the + // pool's max capacity. + TerminationCode_InstancePoolMaxCapacityReached TerminationCode = "INSTANCE_POOL_MAX_CAPACITY_REACHED" + // The KMS key provided is in an incorrect state. + TerminationCode_AwsInvalidKmsKeyState TerminationCode = "AWS_INVALID_KMS_KEY_STATE" + // Insufficient capacity failure from GCE API. + TerminationCode_GcpInsufficientCapacity TerminationCode = "GCP_INSUFFICIENT_CAPACITY" + // Rate quota exceeded for GCP API (e.g. Read requests per minute per region). + TerminationCode_GcpApiRateQuotaExceeded TerminationCode = "GCP_API_RATE_QUOTA_EXCEEDED" + // Resource quota exceeded (e.g. # of n1 vCPUs in a region). + TerminationCode_GcpResourceQuotaExceeded TerminationCode = "GCP_RESOURCE_QUOTA_EXCEEDED" + // Subnet IP space exhausted. + TerminationCode_GcpIpSpaceExhausted TerminationCode = "GCP_IP_SPACE_EXHAUSTED" + // Missing permissions to launch VM with service account. + TerminationCode_GcpServiceAccountAccessDenied TerminationCode = "GCP_SERVICE_ACCOUNT_ACCESS_DENIED" + // VM attempting to launch with non-existent service account. + TerminationCode_GcpServiceAccountNotFound TerminationCode = "GCP_SERVICE_ACCOUNT_NOT_FOUND" + // Forbidden (403) returned by GCP API. + TerminationCode_GcpForbidden TerminationCode = "GCP_FORBIDDEN" + // Not found (404) returned by GCP API. + TerminationCode_GcpNotFound TerminationCode = "GCP_NOT_FOUND" + // Gatekeeper indicated the cluster should be shutdown + TerminationCode_ResourceUsageBlocked TerminationCode = "RESOURCE_USAGE_BLOCKED" + // The data access config of the workspace has changed, and clusters using + // outdated config will be terminated. + TerminationCode_DataAccessConfigChanged TerminationCode = "DATA_ACCESS_CONFIG_CHANGED" + // Failed to fetch internal PAT token required for init script installation from + // WSFS/UC volumes + TerminationCode_AccessTokenFailure TerminationCode = "ACCESS_TOKEN_FAILURE" + // It indicates there is a placement v2 protocol rollout/rollback event for the + // corresponding workspace when processing the placement session on the + // instance-manager side. A retry will fix the issue by switching back to the + // correct placement protocol. + TerminationCode_InvalidInstancePlacementProtocol TerminationCode = "INVALID_INSTANCE_PLACEMENT_PROTOCOL" + // The cluster was terminated as it failed to resolve budget policy. + TerminationCode_BudgetPolicyResolutionFailure TerminationCode = "BUDGET_POLICY_RESOLUTION_FAILURE" + // This customer/error combination is a known issue and is intentionally + // excluded from termination metrics + TerminationCode_InPenaltyBox TerminationCode = "IN_PENALTY_BOX" + // The cluster was terminated when the primary workspace failed over to the + // secondary workspace. This is expected because there is no data plane in the + // secondary workspace. + TerminationCode_DisasterRecoveryReplication TerminationCode = "DISASTER_RECOVERY_REPLICATION" + // A bootstrap timeout that was caused by misconfiguration on the customer's + // side + TerminationCode_BootstrapTimeoutDueToMisconfig TerminationCode = "BOOTSTRAP_TIMEOUT_DUE_TO_MISCONFIG" + // Instance unreachable, but due to misconfiguration on the customer's side + TerminationCode_InstanceUnreachableDueToMisconfig TerminationCode = "INSTANCE_UNREACHABLE_DUE_TO_MISCONFIG" + // Bootstrap timeout due to script download failure, but due to misconfiguration + // on the customer's side + TerminationCode_StorageDownloadFailureDueToMisconfig TerminationCode = "STORAGE_DOWNLOAD_FAILURE_DUE_TO_MISCONFIG" + // CPRF, but due to misconfiguration on the customer's side + TerminationCode_ControlPlaneRequestFailureDueToMisconfig TerminationCode = "CONTROL_PLANE_REQUEST_FAILURE_DUE_TO_MISCONFIG" + // CPLF, but due to misconfiguration on the customer's side + TerminationCode_CloudProviderLaunchFailureDueToMisconfig TerminationCode = "CLOUD_PROVIDER_LAUNCH_FAILURE_DUE_TO_MISCONFIG" + // GCP subnet is in transient "resourceNotReady" state. + TerminationCode_GcpSubnetNotReady TerminationCode = "GCP_SUBNET_NOT_READY" + // The operation on the cloud provider was cancelled. Possibly due to a user + // action. + TerminationCode_CloudOperationCancelled TerminationCode = "CLOUD_OPERATION_CANCELLED" + // If cloud provider indicates instance creation was a success, yet the instance + // is never created. This can happen in certain edge cases like quota exhaustion + // on GCP. We have an open bug here: + // https://partnerissuetracker.corp.google.com/issues/339061883 + TerminationCode_CloudProviderInstanceNotLaunched TerminationCode = "CLOUD_PROVIDER_INSTANCE_NOT_LAUNCHED" + // GCP Databricks VM Machine Image is blocked by customer organization policy. + TerminationCode_GcpTrustedImageProjectsViolated TerminationCode = "GCP_TRUSTED_IMAGE_PROJECTS_VIOLATED" + // cluster terminate can happened when a budget policy limit enforcement + // activated + TerminationCode_BudgetPolicyLimitEnforcementActivated TerminationCode = "BUDGET_POLICY_LIMIT_ENFORCEMENT_ACTIVATED" + TerminationCode_EosSparkImage TerminationCode = "EOS_SPARK_IMAGE" + // Serverless only. There are no eligible K8s for the cluster. + TerminationCode_NoMatchedK8s TerminationCode = "NO_MATCHED_K8S" + // Lazy allocation timeout. Timeout before any internal DBR clusters were + // allocated. + TerminationCode_LazyAllocationTimeout TerminationCode = "LAZY_ALLOCATION_TIMEOUT" + // CMv2 unable to contact chauffeur or node-daemon on the driver node. + TerminationCode_DriverNodeUnreachable TerminationCode = "DRIVER_NODE_UNREACHABLE" + // Dynamic secret generation failed. + TerminationCode_SecretCreationFailure TerminationCode = "SECRET_CREATION_FAILURE" + // Driver or executor pod failed to be scheduled. + TerminationCode_PodSchedulingFailure TerminationCode = "POD_SCHEDULING_FAILURE" + // Driver or executor pod failed to finish assigning. + TerminationCode_PodAssignmentFailure TerminationCode = "POD_ASSIGNMENT_FAILURE" + // Lazy allocation timeout with unknown reason. + TerminationCode_AllocationTimeout TerminationCode = "ALLOCATION_TIMEOUT" + // Lazy allocation timeout. Maps to NoUnallocatedDbrCluster. + TerminationCode_AllocationTimeoutNoUnallocatedClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_UNALLOCATED_CLUSTERS" + // Lazy allocation timeout. Maps to NoMatchedUnallocatedDbrCluster. + TerminationCode_AllocationTimeoutNoMatchedClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_MATCHED_CLUSTERS" + // Lazy allocation timeout. Maps to NoUnallocatedReadyDbrCluster. + TerminationCode_AllocationTimeoutNoReadyClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_READY_CLUSTERS" + // Lazy allocation timeout. Maps to NoMatchedUnallocatedWarmedUpDbrCluster. + TerminationCode_AllocationTimeoutNoWarmedUpClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_WARMED_UP_CLUSTERS" + // Lazy allocation timeout. Maps to NoCandidatesWithNodeDaemonK8sReady. + TerminationCode_AllocationTimeoutNodeDaemonNotReady TerminationCode = "ALLOCATION_TIMEOUT_NODE_DAEMON_NOT_READY" + // Lazy allocation timeout. Maps to NoCandidatesHealthy. + TerminationCode_AllocationTimeoutNoHealthyClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_HEALTHY_CLUSTERS" + // When nephos blocking wait for netvisor setup ready signal, terminated by + // timeout. This error code only applies to clusters with the attribute + // should_block_for_network_readiness: true + TerminationCode_NetvisorSetupTimeout TerminationCode = "NETVISOR_SETUP_TIMEOUT" + // Serverless only. The preselected K8s for the cluster is not eligible. + TerminationCode_NoMatchedK8sTestingTag TerminationCode = "NO_MATCHED_K8S_TESTING_TAG" + // The customer's repeatedly attempting to launch clusters with some + // configuration that the CSP's not able to provide + TerminationCode_CloudProviderResourceStockoutDueToMisconfig TerminationCode = "CLOUD_PROVIDER_RESOURCE_STOCKOUT_DUE_TO_MISCONFIG" + // For the GCP CMv1 Migration, we will terminate all CMv2 based clusters with + // this failure. + TerminationCode_GkeBasedClusterTermination TerminationCode = "GKE_BASED_CLUSTER_TERMINATION" + // Lazy allocation timeout. Maps to NoCandidatesHealthyAndWarmedUp. + TerminationCode_AllocationTimeoutNoHealthyAndWarmedUpClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_HEALTHY_AND_WARMED_UP_CLUSTERS" + // Docker container's OS was not valid. + TerminationCode_DockerInvalidOsException TerminationCode = "DOCKER_INVALID_OS_EXCEPTION" + // Something went wrong during the creation of the docker container. + TerminationCode_DockerContainerCreationException TerminationCode = "DOCKER_CONTAINER_CREATION_EXCEPTION" + // Customer passed in a docker image that's too large for the instance. + TerminationCode_DockerImageTooLargeForInstanceException TerminationCode = "DOCKER_IMAGE_TOO_LARGE_FOR_INSTANCE_EXCEPTION" + // The cluster was terminated because the DNS resolution failed. + TerminationCode_DnsResolutionError TerminationCode = "DNS_RESOLUTION_ERROR" + // Org policy is preventing a GCE API operation from being executed. + TerminationCode_GcpDeniedByOrgPolicy TerminationCode = "GCP_DENIED_BY_ORG_POLICY" + // Customer passed in a secret that they do not have permissions to resolve. + TerminationCode_SecretPermissionDenied TerminationCode = "SECRET_PERMISSION_DENIED" + // Start of network health check generated failures + TerminationCode_NetworkCheckNicFailure TerminationCode = "NETWORK_CHECK_NIC_FAILURE" + TerminationCode_NetworkCheckDnsServerFailure TerminationCode = "NETWORK_CHECK_DNS_SERVER_FAILURE" + TerminationCode_NetworkCheckStorageFailure TerminationCode = "NETWORK_CHECK_STORAGE_FAILURE" + TerminationCode_NetworkCheckMetadataEndpointFailure TerminationCode = "NETWORK_CHECK_METADATA_ENDPOINT_FAILURE" + TerminationCode_NetworkCheckControlPlaneFailure TerminationCode = "NETWORK_CHECK_CONTROL_PLANE_FAILURE" + TerminationCode_NetworkCheckMultipleComponentsFailure TerminationCode = "NETWORK_CHECK_MULTIPLE_COMPONENTS_FAILURE" + // Driver has been down or unresponsive for an extended period of time + TerminationCode_DriverUnhealthy TerminationCode = "DRIVER_UNHEALTHY" + // cluster request is denied due to disallowed usage policy entitlement + TerminationCode_UsagePolicyEntitlementDenied TerminationCode = "USAGE_POLICY_ENTITLEMENT_DENIED" + // Request exceeded MAX_ACTIVE_DBR_PODS_PER_K8S_CLUSTER quota - too many active + // pods on the K8s cluster + TerminationCode_K8sActivePodQuotaExceeded TerminationCode = "K8S_ACTIVE_POD_QUOTA_EXCEEDED" + // Request exceeded MAX_PODS_PER_CLOUD_ACCOUNT quota - subscription/cloud + // account pod limit reached + TerminationCode_CloudAccountPodQuotaExceeded TerminationCode = "CLOUD_ACCOUNT_POD_QUOTA_EXCEEDED" + // Start of network health check generated failures due to misconfiguration + TerminationCode_NetworkCheckNicFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_NIC_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_NetworkCheckDnsServerFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_DNS_SERVER_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_NetworkCheckStorageFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_STORAGE_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_NetworkCheckMetadataEndpointFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_METADATA_ENDPOINT_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_NetworkCheckControlPlaneFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_CONTROL_PLANE_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_NetworkCheckMultipleComponentsFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_MULTIPLE_COMPONENTS_FAILURE_DUE_TO_MISCONFIG" + // CMv2 could not resolve the DBR image for versionless workloads (REPL, + // GENERIC). This typically happens when no spark version is found from the + // channel mapping and the workload is versionless-enabled. + TerminationCode_DbrImageResolutionFailure TerminationCode = "DBR_IMAGE_RESOLUTION_FAILURE" + TerminationCode_ControlPlaneConnectionFailure TerminationCode = "CONTROL_PLANE_CONNECTION_FAILURE" + TerminationCode_ControlPlaneConnectionFailureDueToMisconfig TerminationCode = "CONTROL_PLANE_CONNECTION_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_RateLimited TerminationCode = "RATE_LIMITED" + // The cluster was terminated because mutual TLS port 8443 check failed. + TerminationCode_MtlsPortConnectivityFailure TerminationCode = "MTLS_PORT_CONNECTIVITY_FAILURE" + // The cluster was terminated because hivemetastore connectivity check failed. + TerminationCode_HivemetastoreConnectivityFailure TerminationCode = "HIVEMETASTORE_CONNECTIVITY_FAILURE" +) + +// type of the termination +type TerminationType string + +const ( + TerminationType_Unspecified TerminationType = "" + // Termination succeeded normally + TerminationType_Success TerminationType = "SUCCESS" + // Non-retryable. Client must fix parameters before reattempting the cluster + // creation + TerminationType_ClientError TerminationType = "CLIENT_ERROR" + // Databricks service issue. Clients may retry + TerminationType_ServiceFault TerminationType = "SERVICE_FAULT" + // AWS or Azure infrastructure issue. Clients may retry after the underlying + // cloud issue is resolved + TerminationType_CloudFailure TerminationType = "CLOUD_FAILURE" +) + +type ClusterEventType_ClusterEventType string + +const ( + ClusterEventType_ClusterEventType_Unspecified ClusterEventType_ClusterEventType = "" + // Indicates that the cluster is being created by someone. + ClusterEventType_ClusterEventType_Creating ClusterEventType_ClusterEventType = "CREATING" + // Indicates that the cluster is being started by someone. + ClusterEventType_ClusterEventType_Starting ClusterEventType_ClusterEventType = "STARTING" + // Indicates that the cluster is being started by someone. + ClusterEventType_ClusterEventType_Restarting ClusterEventType_ClusterEventType = "RESTARTING" + // Indicates that the cluster is being terminating. + ClusterEventType_ClusterEventType_Terminating ClusterEventType_ClusterEventType = "TERMINATING" + // Indicates that the cluster has been edited by someone. + ClusterEventType_ClusterEventType_Edited ClusterEventType_ClusterEventType = "EDITED" + // Indicates the cluster finished creating, starting, or restarting. Includes + // the number of nodes in the cluster, and a failure reason if some nodes could + // not be acquired. + ClusterEventType_ClusterEventType_Running ClusterEventType_ClusterEventType = "RUNNING" + // Indicates a change in the target size of the cluster (upsize or downsize). + ClusterEventType_ClusterEventType_Resizing ClusterEventType_ClusterEventType = "RESIZING" + // Indicates that some nodes were lost from the cluster. + ClusterEventType_ClusterEventType_NodesLost ClusterEventType_ClusterEventType = "NODES_LOST" + // Indicates that nodes finished to be added to the cluster. Includes the number + // of nodes in the cluster, and a failure reason if some nodes could not be + // acquired. + ClusterEventType_ClusterEventType_UpsizeCompleted ClusterEventType_ClusterEventType = "UPSIZE_COMPLETED" + // Init Scripts V2 have started executing. Includes the list of Global and + // Cluster scoped init scripts that are about to be fetched & executed. + ClusterEventType_ClusterEventType_InitScriptsStarted ClusterEventType_ClusterEventType = "INIT_SCRIPTS_STARTED" + // Init Scripts V2 have finished executing. + ClusterEventType_ClusterEventType_InitScriptsFinished ClusterEventType_ClusterEventType = "INIT_SCRIPTS_FINISHED" + // Indicates that a disk is low on space, but adding disks would put it over the + // max capacity + ClusterEventType_ClusterEventType_DidNotExpandDisk ClusterEventType_ClusterEventType = "DID_NOT_EXPAND_DISK" + // Indicates that a disk is low on space, and we did expand its disks. + ClusterEventType_ClusterEventType_ExpandedDisk ClusterEventType_ClusterEventType = "EXPANDED_DISK" + // Indicates we failed to expand the disk space + ClusterEventType_ClusterEventType_FailedToExpandDisk ClusterEventType_ClusterEventType = "FAILED_TO_EXPAND_DISK" + // Indicates that driver is up and running + ClusterEventType_ClusterEventType_DriverHealthy ClusterEventType_ClusterEventType = "DRIVER_HEALTHY" + // Indicates that driver is overloaded(one case is when it is GCing) + ClusterEventType_ClusterEventType_DriverNotResponding ClusterEventType_ClusterEventType = "DRIVER_NOT_RESPONDING" + // Indicates that the container that hosts driver and chauffeur is unavailable + ClusterEventType_ClusterEventType_DriverUnavailable ClusterEventType_ClusterEventType = "DRIVER_UNAVAILABLE" + // Indicates that spark context is null or there was a spark exception thrown + // from driver + ClusterEventType_ClusterEventType_SparkException ClusterEventType_ClusterEventType = "SPARK_EXCEPTION" + // Indicates that driver is up but metastore is down + ClusterEventType_ClusterEventType_MetastoreDown ClusterEventType_ClusterEventType = "METASTORE_DOWN" + // Indicates that driver is up but dbfs is down + ClusterEventType_ClusterEventType_DbfsDown ClusterEventType_ClusterEventType = "DBFS_DOWN" + // Autoscaling stat, including wasted instance minutes, reported + ClusterEventType_ClusterEventType_AutoscalingStatsReport ClusterEventType_ClusterEventType = "AUTOSCALING_STATS_REPORT" + // Indicates that a node has been blacklisted. + ClusterEventType_ClusterEventType_NodeBlacklisted ClusterEventType_ClusterEventType = "NODE_BLACKLISTED" + // Indicates the cluster was pinned. + ClusterEventType_ClusterEventType_Pinned ClusterEventType_ClusterEventType = "PINNED" + // Indicates the cluster was unpinned. + ClusterEventType_ClusterEventType_Unpinned ClusterEventType_ClusterEventType = "UNPINNED" + // Indicates that a node has been decommissioned because of exclusion + ClusterEventType_ClusterEventType_NodeExcludedDecommissioned ClusterEventType_ClusterEventType = "NODE_EXCLUDED_DECOMMISSIONED" + // Indicates add node failure + ClusterEventType_ClusterEventType_AddNodesFailed ClusterEventType_ClusterEventType = "ADD_NODES_FAILED" + // Indicates the cluster autoscaling has been retried several times. The waiting + // time has reached the max waiting time. + ClusterEventType_ClusterEventType_AutoscalingBackoff ClusterEventType_ClusterEventType = "AUTOSCALING_BACKOFF" + // Indicates that the cluster is going to be restarted because of the automatic + // worker image update + ClusterEventType_ClusterEventType_AutomaticClusterUpdate ClusterEventType_ClusterEventType = "AUTOMATIC_CLUSTER_UPDATE" + // Indicates there was a failure during autoscaling of a cluster. These are + // failures that we may want to surface to the customer such as: - + // DatabricksServiceException(REQUEST_LIMIT_EXCEEDED) + ClusterEventType_ClusterEventType_AutoscalingFailed ClusterEventType_ClusterEventType = "AUTOSCALING_FAILED" + // Indicates that the cluster was migrated for the GCP CMv1 migration. The + // cluster may be migrated from GKE architecture to GCE or rolled back from GCE + // to GKE. + ClusterEventType_ClusterEventType_ClusterMigrated ClusterEventType_ClusterEventType = "CLUSTER_MIGRATED" + // Indicates that decommission started. + ClusterEventType_ClusterEventType_DecommissionStarted ClusterEventType_ClusterEventType = "DECOMMISSION_STARTED" + // Indicates that decommission ended. + ClusterEventType_ClusterEventType_DecommissionEnded ClusterEventType_ClusterEventType = "DECOMMISSION_ENDED" + // Indicates that a deferred policy enforcement was scheduled. + ClusterEventType_ClusterEventType_DeferredPolicyEnforcementScheduled ClusterEventType_ClusterEventType = "DEFERRED_POLICY_ENFORCEMENT_SCHEDULED" + // Indicates that a deferred policy enforcement failed. + ClusterEventType_ClusterEventType_DeferredPolicyEnforcementFailed ClusterEventType_ClusterEventType = "DEFERRED_POLICY_ENFORCEMENT_FAILED" + // Indicates that the configured UC volume for log delivery is misconfigured + // (permission does not exist or volume is invalid) + ClusterEventType_ClusterEventType_UcVolumeMisconfigured ClusterEventType_ClusterEventType = "UC_VOLUME_MISCONFIGURED" +) + +// The state of a Cluster. The current allowable state transitions are as +// follows: +// +// - `PENDING` -> `RUNNING` - `PENDING` -> `TERMINATING` - `RUNNING` -> +// `RESIZING` - `RUNNING` -> `RESTARTING` - `RUNNING` -> `TERMINATING` - +// `RESTARTING` -> `RUNNING` - `RESTARTING` -> `TERMINATING` - `RESIZING` -> +// `RUNNING` - `RESIZING` -> `TERMINATING` - `TERMINATING` -> `TERMINATED` +type ClusterState_ClusterState string + +const ( + ClusterState_ClusterState_Unspecified ClusterState_ClusterState = "" + // Indicates a cluster that is in progress of being created. + ClusterState_ClusterState_Pending ClusterState_ClusterState = "PENDING" + // Indicates a cluster that has been started and is ready for use. + ClusterState_ClusterState_Running ClusterState_ClusterState = "RUNNING" + // Indicates that a cluster is in the process of restarting. + ClusterState_ClusterState_Restarting ClusterState_ClusterState = "RESTARTING" + // Indicates that a cluster is in the process of adding or removing nodes. + ClusterState_ClusterState_Resizing ClusterState_ClusterState = "RESIZING" + // Indicates that a cluster is in the process of being destroyed. + ClusterState_ClusterState_Terminating ClusterState_ClusterState = "TERMINATING" + // Indicates a cluster which has been successfully destroyed. + ClusterState_ClusterState_Terminated ClusterState_ClusterState = "TERMINATED" + // This state is not used anymore. It was used to indicate a cluster which + // failed to be created. Terminating and Terminated are used instead. + ClusterState_ClusterState_Error ClusterState_ClusterState = "ERROR" + // Indicates a cluster which is an unknown state. A cluster should never be in + // this state. + ClusterState_ClusterState_Unknown ClusterState_ClusterState = "UNKNOWN" +) + +type EnforcePolicyComplianceForClusterRequest_EnforceMode string + +const ( + EnforcePolicyComplianceForClusterRequest_EnforceMode_Unspecified EnforcePolicyComplianceForClusterRequest_EnforceMode = "" + // If the cluster is in the TERMINATED state, edit the cluster immediately. If + // the cluster is in the RUNNING state, edit and restart the cluster. Else, the + // operation fails. + EnforcePolicyComplianceForClusterRequest_EnforceMode_EnforceImmediately EnforcePolicyComplianceForClusterRequest_EnforceMode = "ENFORCE_IMMEDIATELY" + // If the cluster is in the TERMINATED state, edit the cluster immediately. + // Else, the cluster is not edited. Instead, a pending enforcement is scheduled + // to update the cluster when it terminates or restarts. Only workspace admins + // can use this mode. + EnforcePolicyComplianceForClusterRequest_EnforceMode_WaitForTermination EnforcePolicyComplianceForClusterRequest_EnforceMode = "WAIT_FOR_TERMINATION" +) + +type EnforcePolicyComplianceForClusterResponse_EnforceResult string + +const ( + EnforcePolicyComplianceForClusterResponse_EnforceResult_Unspecified EnforcePolicyComplianceForClusterResponse_EnforceResult = "" + // No changes were made to the cluster. + EnforcePolicyComplianceForClusterResponse_EnforceResult_NoChanges EnforcePolicyComplianceForClusterResponse_EnforceResult = "NO_CHANGES" + // Changes were applied to the cluster. + EnforcePolicyComplianceForClusterResponse_EnforceResult_Applied EnforcePolicyComplianceForClusterResponse_EnforceResult = "APPLIED" + // Changes were not applied to the cluster yet. Instead, changes will be applied + // when the cluster terminates or restarts. This is not returned when + // validate_only is true, even if the enforcement would have normally been + // deferred. Instead APPLIED will be returned. + EnforcePolicyComplianceForClusterResponse_EnforceResult_Deferred EnforcePolicyComplianceForClusterResponse_EnforceResult = "DEFERRED" +) + +// Result of attempted script execution +type InitScriptExecutionDetails_InitScriptExecutionStatus string + +const ( + InitScriptExecutionDetails_InitScriptExecutionStatus_Unspecified InitScriptExecutionDetails_InitScriptExecutionStatus = "" + // The script's execution status is unknown + InitScriptExecutionDetails_InitScriptExecutionStatus_Unknown InitScriptExecutionDetails_InitScriptExecutionStatus = "UNKNOWN" + // The NodeDaemon failed to fetch the script + InitScriptExecutionDetails_InitScriptExecutionStatus_FailedFetch InitScriptExecutionDetails_InitScriptExecutionStatus = "FAILED_FETCH" + // The script returned a non-zero exit code after execution + InitScriptExecutionDetails_InitScriptExecutionStatus_FailedExecution InitScriptExecutionDetails_InitScriptExecutionStatus = "FAILED_EXECUTION" + // The script was successfully fetched but was not executed + InitScriptExecutionDetails_InitScriptExecutionStatus_NotExecuted InitScriptExecutionDetails_InitScriptExecutionStatus = "NOT_EXECUTED" + // The NodeDaemon failed to fetch the script, and the script was skippable (i.e. + // skip_if_fetch_fails was true) so it was skipped without triggering any + // errors. + InitScriptExecutionDetails_InitScriptExecutionStatus_Skipped InitScriptExecutionDetails_InitScriptExecutionStatus = "SKIPPED" + // The script was successfully executed + InitScriptExecutionDetails_InitScriptExecutionStatus_Succeeded InitScriptExecutionDetails_InitScriptExecutionStatus = "SUCCEEDED" + // For FUSE mount init scripts (WSFS & Volumes): the fuse mounting was + // unsuccessful + InitScriptExecutionDetails_InitScriptExecutionStatus_FuseMountFailed InitScriptExecutionDetails_InitScriptExecutionStatus = "FUSE_MOUNT_FAILED" +) + +type PendingEnforcement_EnforcementStatus string + +const ( + PendingEnforcement_EnforcementStatus_Unspecified PendingEnforcement_EnforcementStatus = "" + // The pending enforcement will be attempted on the next cluster terminate or + // restart. + PendingEnforcement_EnforcementStatus_Active PendingEnforcement_EnforcementStatus = "ACTIVE" + // The pending enforcement will not be attempted again because we have already + // unsuccessfully attempted to apply the enforce. + PendingEnforcement_EnforcementStatus_Inactive PendingEnforcement_EnforcementStatus = "INACTIVE" +) + +// The cause of a change in target size. +type ResizeCause_ResizeCause string + +const ( + ResizeCause_ResizeCause_Unspecified ResizeCause_ResizeCause = "" + // Automatically resized based on load. + ResizeCause_ResizeCause_Autoscale ResizeCause_ResizeCause = "AUTOSCALE" + // User requested a new size. + ResizeCause_ResizeCause_UserRequest ResizeCause_ResizeCause = "USER_REQUEST" + // Autorecovery monitor resized the cluster after it lost a nodes. + ResizeCause_ResizeCause_Autorecovery ResizeCause_ResizeCause = "AUTORECOVERY" + // Terminate bad nodes and spawn new ones + ResizeCause_ResizeCause_ReplaceBadNodes ResizeCause_ResizeCause = "REPLACE_BAD_NODES" + // V2 autoscaler automatically resized based on load (internal use only, events + // show as AUTOSCALE). + ResizeCause_ResizeCause_AutoscaleV2 ResizeCause_ResizeCause = "AUTOSCALE_V2" + // Automatically resized based on decision from the DBR Autoscaler service. + ResizeCause_ResizeCause_DbrAutoscale ResizeCause_ResizeCause = "DBR_AUTOSCALE" +) + +// A storage location in Adls Gen2. +type Adlsgen2Info struct { + // abfss destination, e.g. + // `abfss://@.dfs.core.windows.net/`. + Destination *string +} + +type AutoScale struct { + // The minimum number of workers to which the cluster can scale down when + // underutilized. It is also the initial number of workers the cluster will have + // after creation. + MinWorkers *int `fieldmask:"min_workers"` + // The maximum number of workers to which the cluster can scale up when + // overloaded. Note that `max_workers` must be strictly greater than + // `min_workers`. + MaxWorkers *int `fieldmask:"max_workers"` +} + +// Attributes set during cluster creation which are related to Amazon Web +// Services.. +type AwsAttributes struct { + // The first `first_on_demand` nodes of the cluster will be placed on on-demand + // instances. If this value is greater than 0, the cluster driver node in + // particular will be placed on an on-demand instance. If this value is greater + // than or equal to the current cluster size, all nodes will be placed on + // on-demand instances. If this value is less than the current cluster size, + // `first_on_demand` nodes will be placed on on-demand instances and the + // remainder will be placed on `availability` instances. Note that this value + // does not affect cluster size and cannot currently be mutated over the + // lifetime of a cluster. + FirstOnDemand *int `fieldmask:"first_on_demand"` + Availability AwsAvailability `fieldmask:"availability"` + // Identifier for the availability zone/datacenter in which the cluster resides. + // This string will be of a form like "us-west-2a". The provided availability + // zone must be in the same region as the deployment. For example, + // "us-west-2a" is not a valid zone id if the deployment resides in + // the "us-east-1" region. This is an optional field at cluster creation, and if + // not specified, the zone "auto" will be used. If the zone specified is "auto", + // will try to place cluster in a zone with high availability, and will retry + // placement in a different AZ if there is not enough capacity. The list of + // available zones as well as the default value can be found by using the `List + // Zones` method. + ZoneId *string `fieldmask:"zone_id"` + // Nodes for this cluster will only be placed on AWS instances with this + // instance profile. If ommitted, nodes will be placed on instances without an + // IAM instance profile. The instance profile must have previously been added to + // the environment by an account administrator. + // + // This feature may only be available to certain customer plans. + InstanceProfileArn *string `fieldmask:"instance_profile_arn"` + // The bid price for AWS spot instances, as a percentage of the corresponding + // instance type's on-demand price. For example, if this field is set to 50, and + // the cluster needs a new `r3.xlarge` spot instance, then the bid price is half + // of the price of on-demand `r3.xlarge` instances. Similarly, if this field is + // set to 200, the bid price is twice the price of on-demand `r3.xlarge` + // instances. If not specified, the default value is 100. When spot instances + // are requested for this cluster, only spot instances whose bid price + // percentage matches this field will be considered. Note that, for safety, we + // enforce this field to be no more than 10000. + SpotBidPricePercent *int `fieldmask:"spot_bid_price_percent"` + // The type of EBS volumes that will be launched with this cluster. + EbsVolumeType EbsVolumeType `fieldmask:"ebs_volume_type"` + // The number of volumes launched for each instance. Users can choose up to 10 + // volumes. This feature is only enabled for supported node types. Legacy node + // types cannot specify custom EBS volumes. For node types with no instance + // store, at least one EBS volume needs to be specified; otherwise, cluster + // creation will fail. + // + // These EBS volumes will be mounted at `/ebs0`, `/ebs1`, and etc. Instance + // store volumes will be mounted at `/local_disk0`, `/local_disk1`, and etc. + // + // If EBS volumes are attached, will configure Spark to use only + // the EBS volumes for scratch storage because heterogenously sized scratch + // devices can lead to inefficient disk utilization. If no EBS volumes are + // attached, will configure Spark to use instance store volumes. + // + // Please note that if EBS volumes are specified, then the Spark configuration + // `spark.local.dir` will be overridden. + EbsVolumeCount *int `fieldmask:"ebs_volume_count"` + // The size of each EBS volume (in GiB) launched for each instance. For general + // purpose SSD, this value must be within the range 100 - 4096. For throughput + // optimized HDD, this value must be within the range 500 - 4096. + EbsVolumeSize *int `fieldmask:"ebs_volume_size"` + // If using gp3 volumes, what IOPS to use for the disk. If this is not set, the + // maximum performance of a gp2 volume with the same volume size will be used. + EbsVolumeIops *int `fieldmask:"ebs_volume_iops"` + // If using gp3 volumes, what throughput to use for the disk. If this is not + // set, the maximum performance of a gp2 volume with the same volume size will + // be used. + EbsVolumeThroughput *int `fieldmask:"ebs_volume_throughput"` +} + +// Attributes set during cluster creation which are related to Microsoft Azure.. +type AzureAttributes struct { + // Defines values necessary to configure and run Azure Log Analytics agent + LogAnalyticsInfo *LogAnalyticsInfo `fieldmask:"log_analytics_info"` + // The first `first_on_demand` nodes of the cluster will be placed on on-demand + // instances. This value should be greater than 0, to make sure the cluster + // driver node is placed on an on-demand instance. If this value is greater than + // or equal to the current cluster size, all nodes will be placed on on-demand + // instances. If this value is less than the current cluster size, + // `first_on_demand` nodes will be placed on on-demand instances and the + // remainder will be placed on `availability` instances. Note that this value + // does not affect cluster size and cannot currently be mutated over the + // lifetime of a cluster. + FirstOnDemand *int `fieldmask:"first_on_demand"` + // Availability type used for all subsequent nodes past the `first_on_demand` + // ones. Note: If `first_on_demand` is zero, this availability type will be used + // for the entire cluster. + Availability AzureAvailability `fieldmask:"availability"` + // The max bid price to be used for Azure spot instances. The Max price for the + // bid cannot be higher than the on-demand price of the instance. If not + // specified, the default value is -1, which specifies that the instance cannot + // be evicted on the basis of price, and only on the basis of availability. + // Further, the value should > 0 or -1. + SpotBidMaxPrice *float64 `fieldmask:"spot_bid_max_price"` + // The Azure capacity reservation group resource ID to use for launching VMs. + // When specified, VMs will be launched using the provided capacity reservation. + // + // Capacity reservations can only be specified when the workspace uses injected + // vnet (i.e. customer defined vnet not managed by databricks). Ensure the + // databricks-login-prod Enterprise Application is granted the following four + // permissions: 1. Microsoft.Compute/capacityReservationGroups/read 2. + // Microsoft.Compute/capacityReservationGroups/deploy/action 3. + // Microsoft.Compute/capacityReservationGroups/capacityReservations/read 4. + // Microsoft.Compute/capacityReservationGroups/capacityReservations/deploy/action + // + // Format: + // `/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/capacityReservationGroups/{capacityReservationGroupName}` + CapacityReservationGroup *string `fieldmask:"capacity_reservation_group"` +} + +// Request to cancel the pending enforcement for a cluster.. +type CancelPendingClusterEnforcementRequest struct { + // The ID of the cluster to cancel the pending enforcement for. + ClusterId *string + // If true and no pending enforcement exists, the request will succeed but no + // action will be taken. + AllowMissing *bool +} + +// Response for canceling the pending enforcement for a cluster. If the cancel +// request succeeds, an empty response object is returned. Otherwise, an error +// response is returned.. +type CancelPendingClusterEnforcementResponse struct { +} + +type ChangeClusterOwnerRequest struct { + ClusterId *string + // New owner of the cluster_id after this RPC. + OwnerUsername *string +} + +type ChangeClusterOwnerResponse struct { +} + +type CloneCluster struct { + // The cluster that is being cloned. + SourceClusterId *string +} + +type CloudProviderNodeInfo struct { + // Status as reported by the cloud provider + Status []CloudProviderNodeStatus +} + +// Common set of attributes set during cluster creation. These attributes cannot +// be changed over the lifetime of a cluster.. +type ClusterAttributes struct { + // Cluster name requested by the user. This doesn't have to be unique. If not + // specified at creation, the cluster name will be an empty string. For job + // clusters, the cluster name is automatically set based on the job and job run + // IDs. + ClusterName *string + // The Spark version of the cluster, e.g. `3.3.x-scala2.11`. A list of available + // Spark versions can be retrieved by using the [clusters/sparkVersions] API + // call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + SparkVersion *string + // An object containing a set of optional, user-specified Spark configuration + // key-value pairs. Users can also pass in a string of extra JVM options to the + // driver and the executors via `spark.driver.extraJavaOptions` and + // `spark.executor.extraJavaOptions` respectively. + SparkConf map[string]string + // Attributes related to clusters running on Amazon Web Services. If not + // specified at cluster creation, a set of default values will be used. + AwsAttributes *AwsAttributes + // Attributes related to clusters running on Microsoft Azure. If not specified + // at cluster creation, a set of default values will be used. + AzureAttributes *AzureAttributes + // Attributes related to clusters running on Google Cloud Platform. If not + // specified at cluster creation, a set of default values will be used. + GcpAttributes *GcpAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // The node type of the Spark driver. Note that this field is optional; if + // unset, the driver node type will be set as the same value as `node_type_id` + // defined above. + // + // This field, along with node_type_id, should not be set if + // virtual_cluster_size is set. If both driver_node_type_id, node_type_id, and + // virtual_cluster_size are specified, driver_node_type_id and node_type_id take + // precedence. + DriverNodeTypeId *string + // Flexible node type configuration for worker nodes. + WorkerNodeTypeFlexibility *NodeTypeFlexibility + // Flexible node type configuration for the driver node. + DriverNodeTypeFlexibility *NodeTypeFlexibility + // SSH public key contents that will be added to each Spark node in this + // cluster. The corresponding private keys can be used to login with the user + // name `ubuntu` on port `2200`. Up to 10 keys can be specified. + SshPublicKeys []string + // Additional tags for cluster resources. will tag all cluster + // resources (e.g., AWS instances and EBS volumes) with these tags in addition + // to `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + // + // - Clusters can only reuse cloud resources if the resources' tags are a subset + // of the cluster tags + CustomTags map[string]string + // The configuration for delivering spark logs to a long-term storage + // destination. Three kinds of destinations (DBFS, S3 and Unity Catalog volumes) + // are supported. Only one destination can be specified for one cluster. If the + // conf is given, the logs will be delivered to the destination every `5 mins`. + // The destination of driver logs is `$destination/$clusterId/driver`, while the + // destination of executor logs is `$destination/$clusterId/executor`. + ClusterLogConf *ClusterLogConf + // An object containing a set of optional, user-specified environment variable + // key-value pairs. Please note that key-value pair of the form (X,Y) will be + // exported as is (i.e., `export X='Y'`) while launching the driver and workers. + // + // In order to specify an additional set of `SPARK_DAEMON_JAVA_OPTS`, we + // recommend appending them to `$SPARK_DAEMON_JAVA_OPTS` as shown in the example + // below. This ensures that all default databricks managed environmental + // variables are included as well. + // + // Example Spark environment variables: `{"SPARK_WORKER_MEMORY": "28000m", + // "SPARK_LOCAL_DIRS": "/local_disk0"}` or `{"SPARK_DAEMON_JAVA_OPTS": + // "$SPARK_DAEMON_JAVA_OPTS -Dspark.shuffle.service.enabled=true"}` + SparkEnvVars map[string]string + // Automatically terminates the cluster after it is inactive for this time in + // minutes. If not set, this cluster will not be automatically terminated. If + // specified, the threshold must be between 10 and 10000 minutes. Users can also + // set this value to 0 to explicitly disable automatic termination. + AutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this cluster will dynamically + // acquire additional disk space when its Spark workers are running low on disk + // space. + EnableElasticDisk *bool + // The configuration for storing init scripts. Any number of destinations can be + // specified. The scripts are executed sequentially in the order provided. If + // `cluster_log_conf` is specified, init script logs are sent to + // `//init_scripts`. + InitScripts []InitScriptInfo + // Custom docker image BYOC + DockerImage *DockerImage + // The optional ID of the instance pool to which the cluster belongs. + InstancePoolId *string + // Single user name if data_security_mode is `SINGLE_USER` + SingleUserName *string + // The ID of the cluster policy used to create the cluster if applicable. + PolicyId *string + // Whether to enable LUKS on cluster VMs' local disks + EnableLocalDiskEncryption *bool + // The optional ID of the instance pool for the driver of the cluster belongs. + // The pool cluster uses the instance pool with id (instance_pool_id) if the + // driver pool is not assigned. + DriverInstancePoolId *string + WorkloadType *WorkloadType + DataSecurityMode DataSecurityMode + // Determines the cluster's runtime engine, either standard or Photon. + // + // This field is not compatible with legacy `spark_version` values that contain + // `-photon-`. Remove `-photon-` from the `spark_version` and set + // `runtime_engine` to `PHOTON`. + // + // If left unspecified, the runtime engine defaults to standard unless the + // spark_version contains -photon-, in which case Photon will be used. + RuntimeEngine RuntimeEngine + Kind ComputeKind + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // `effective_spark_version` is determined by `spark_version` (DBR release), + // this field `use_ml_runtime`, and whether `node_type_id` is gpu node or not. + UseMlRuntime *bool + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // When set to true, will automatically set single node related + // `custom_tags`, `spark_conf`, and `num_workers` + IsSingleNode *bool + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED disks. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED disks. + TotalInitialRemoteDiskSize *int + // Controls dependency configuration for the cluster. + DependencyMode DependencyMode +} + +type ClusterCompliance struct { + // Canonical unique identifier for a cluster. + ClusterId *string + // Whether this cluster is in compliance with the latest version of its policy. + IsCompliant *bool + // An object containing key-value mappings representing the first 200 policy + // validation errors. The keys indicate the path where the policy validation + // error is occurring. The values indicate an error message describing the + // policy validation error. + Violations map[string]string + // Information about the pending enforcement for the cluster. Only present if a + // pending enforcement is scheduled for the cluster. + PendingEnforcement *PendingEnforcement +} + +type ClusterEvent struct { + ClusterId *string + // The timestamp when the event occurred, stored as the number of milliseconds + // since the Unix epoch. If not provided, this will be assigned by the Timeline + // service. + Timestamp *int64 + Type ClusterEventType_ClusterEventType + Details *EventDetails + DataPlaneEventDetails *DataPlaneEventDetails +} + +type ClusterEventType struct { +} + +// Describes all of the metadata about a single Spark cluster in .. +type ClusterInfo struct { + // Canonical identifier for the cluster. This id is retained during cluster + // restarts and resizes, while each new cluster has a globally unique id. + ClusterId *string + // Creator user name. The field won't be included in the response if the user + // has already been deleted. + CreatorUserName *string + // Current state of the cluster. + State ClusterState_ClusterState + // A message associated with the most recent state transition (e.g., the reason + // why the cluster entered a `TERMINATED` state). + StateMessage *string + // Total amount of cluster memory, in megabytes + ClusterMemoryMb *int64 + // Number of CPU cores available for this cluster. Note that this can be + // fractional, e.g. 7.5 cores, since certain node types are configured to share + // cores between Spark nodes on the same instance. + ClusterCores *float32 + // Tags that are added by regardless of any `custom_tags`, + // including: + // + // - Vendor: + // + // - Creator: + // + // - ClusterName: + // + // - ClusterId: + // + // - Name: < internal use> + DefaultTags map[string]string + // Cluster log delivery status. + ClusterLogStatus *LogSyncStatus + // Information about why the cluster was terminated. This field only appears + // when the cluster is in a `TERMINATING` or `TERMINATED` state. + TerminationReason *TerminationReason + // The spec contains a snapshot of the latest user specified settings that were + // used to create/edit the cluster. Note: not included in the response of the + // ListClusters API. + Spec *ClusterInfo_ComputeSpec + // Node on which the Spark driver resides. The driver node contains the Spark + // master and the application that manages the per-notebook Spark + // REPLs. + Driver *SparkInfo_SparkNode + // Nodes on which the Spark executors reside. + Executors []SparkInfo_SparkNode + // A canonical SparkContext identifier. This value *does* change when the Spark + // driver restarts. The pair `(cluster_id, spark_context_id)` is a globally + // unique identifier over all Spark contexts. + SparkContextId *int64 + // Port on which Spark JDBC server is listening, in the driver nod. No service + // will be listeningon on this port in executor nodes. + JdbcPort *int + // Cluster name requested by the user. This doesn't have to be unique. If not + // specified at creation, the cluster name will be an empty string. For job + // clusters, the cluster name is automatically set based on the job and job run + // IDs. + ClusterName *string + // The Spark version of the cluster, e.g. `3.3.x-scala2.11`. A list of available + // Spark versions can be retrieved by using the [clusters/sparkVersions] API + // call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + SparkVersion *string + // An object containing a set of optional, user-specified Spark configuration + // key-value pairs. Users can also pass in a string of extra JVM options to the + // driver and the executors via `spark.driver.extraJavaOptions` and + // `spark.executor.extraJavaOptions` respectively. + SparkConf map[string]string + // Attributes related to clusters running on Amazon Web Services. If not + // specified at cluster creation, a set of default values will be used. + AwsAttributes *AwsAttributes + // Attributes related to clusters running on Microsoft Azure. If not specified + // at cluster creation, a set of default values will be used. + AzureAttributes *AzureAttributes + // Attributes related to clusters running on Google Cloud Platform. If not + // specified at cluster creation, a set of default values will be used. + GcpAttributes *GcpAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // The node type of the Spark driver. Note that this field is optional; if + // unset, the driver node type will be set as the same value as `node_type_id` + // defined above. + // + // This field, along with node_type_id, should not be set if + // virtual_cluster_size is set. If both driver_node_type_id, node_type_id, and + // virtual_cluster_size are specified, driver_node_type_id and node_type_id take + // precedence. + DriverNodeTypeId *string + // Flexible node type configuration for worker nodes. + WorkerNodeTypeFlexibility *NodeTypeFlexibility + // Flexible node type configuration for the driver node. + DriverNodeTypeFlexibility *NodeTypeFlexibility + // SSH public key contents that will be added to each Spark node in this + // cluster. The corresponding private keys can be used to login with the user + // name `ubuntu` on port `2200`. Up to 10 keys can be specified. + SshPublicKeys []string + // Additional tags for cluster resources. will tag all cluster + // resources (e.g., AWS instances and EBS volumes) with these tags in addition + // to `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + // + // - Clusters can only reuse cloud resources if the resources' tags are a subset + // of the cluster tags + CustomTags map[string]string + // The configuration for delivering spark logs to a long-term storage + // destination. Three kinds of destinations (DBFS, S3 and Unity Catalog volumes) + // are supported. Only one destination can be specified for one cluster. If the + // conf is given, the logs will be delivered to the destination every `5 mins`. + // The destination of driver logs is `$destination/$clusterId/driver`, while the + // destination of executor logs is `$destination/$clusterId/executor`. + ClusterLogConf *ClusterLogConf + // An object containing a set of optional, user-specified environment variable + // key-value pairs. Please note that key-value pair of the form (X,Y) will be + // exported as is (i.e., `export X='Y'`) while launching the driver and workers. + // + // In order to specify an additional set of `SPARK_DAEMON_JAVA_OPTS`, we + // recommend appending them to `$SPARK_DAEMON_JAVA_OPTS` as shown in the example + // below. This ensures that all default databricks managed environmental + // variables are included as well. + // + // Example Spark environment variables: `{"SPARK_WORKER_MEMORY": "28000m", + // "SPARK_LOCAL_DIRS": "/local_disk0"}` or `{"SPARK_DAEMON_JAVA_OPTS": + // "$SPARK_DAEMON_JAVA_OPTS -Dspark.shuffle.service.enabled=true"}` + SparkEnvVars map[string]string + // Automatically terminates the cluster after it is inactive for this time in + // minutes. If not set, this cluster will not be automatically terminated. If + // specified, the threshold must be between 10 and 10000 minutes. Users can also + // set this value to 0 to explicitly disable automatic termination. + AutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this cluster will dynamically + // acquire additional disk space when its Spark workers are running low on disk + // space. + EnableElasticDisk *bool + // The configuration for storing init scripts. Any number of destinations can be + // specified. The scripts are executed sequentially in the order provided. If + // `cluster_log_conf` is specified, init script logs are sent to + // `//init_scripts`. + InitScripts []InitScriptInfo + // Custom docker image BYOC + DockerImage *DockerImage + // The optional ID of the instance pool to which the cluster belongs. + InstancePoolId *string + // Single user name if data_security_mode is `SINGLE_USER` + SingleUserName *string + // The ID of the cluster policy used to create the cluster if applicable. + PolicyId *string + // Whether to enable LUKS on cluster VMs' local disks + EnableLocalDiskEncryption *bool + // The optional ID of the instance pool for the driver of the cluster belongs. + // The pool cluster uses the instance pool with id (instance_pool_id) if the + // driver pool is not assigned. + DriverInstancePoolId *string + WorkloadType *WorkloadType + DataSecurityMode DataSecurityMode + // Determines the cluster's runtime engine, either standard or Photon. + // + // This field is not compatible with legacy `spark_version` values that contain + // `-photon-`. Remove `-photon-` from the `spark_version` and set + // `runtime_engine` to `PHOTON`. + // + // If left unspecified, the runtime engine defaults to standard unless the + // spark_version contains -photon-, in which case Photon will be used. + RuntimeEngine RuntimeEngine + Kind ComputeKind + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // `effective_spark_version` is determined by `spark_version` (DBR release), + // this field `use_ml_runtime`, and whether `node_type_id` is gpu node or not. + UseMlRuntime *bool + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // When set to true, will automatically set single node related + // `custom_tags`, `spark_conf`, and `num_workers` + IsSingleNode *bool + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED disks. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED disks. + TotalInitialRemoteDiskSize *int + // Controls dependency configuration for the cluster. + DependencyMode DependencyMode + // Time (in epoch milliseconds) when the cluster creation request was received + // (when the cluster entered a `PENDING` state). + StartTime *int64 + // Time (in epoch milliseconds) when the cluster was terminated, if applicable. + TerminatedTime *int64 + // Time when the cluster driver last lost its state (due to a restart or driver + // failure). + LastStateLossTime *int64 + // the timestamp that the cluster was started/restarted + LastRestartedTime *int64 + Size isClusterInfo_Size +} + +type isClusterInfo_Size interface { + isClusterInfo_Size() +} + +// ClusterInfo_Size_NumWorkers selects NumWorkers for ClusterInfo.Size. +// Number of worker nodes that this cluster should have. A cluster has one Spark +// Driver and `num_workers` Executors for a total of `num_workers` + 1 Spark +// nodes. +// +// Note: When reading the properties of a cluster, this field reflects the +// desired number of workers rather than the actual current number of workers. +// For instance, if a cluster is resized from 5 to 10 workers, this field will +// immediately be updated to reflect the target size of 10 workers, whereas the +// workers listed in `spark_info` will gradually increase from 5 to 10 as the +// new nodes are provisioned. +type ClusterInfo_Size_NumWorkers struct { + NumWorkers int +} + +func (*ClusterInfo_Size_NumWorkers) isClusterInfo_Size() {} + +// ClusterInfo_Size_Autoscale selects Autoscale for ClusterInfo.Size. +// Parameters needed in order to automatically scale clusters up and down based +// on load. Note: autoscaling works best with DB runtime versions 3.0 or later. +type ClusterInfo_Size_Autoscale struct { + Autoscale AutoScale +} + +func (*ClusterInfo_Size_Autoscale) isClusterInfo_Size() {} + +// Contains a snapshot of the latest user specified settings that were used to +// create/edit the cluster.. +type ClusterInfo_ComputeSpec struct { + // When set to true, fixed and default values from the policy will be used for + // fields that are omitted. When set to false, only fixed values from the policy + // will be applied. + ApplyPolicyDefaultValues *bool + // Cluster name requested by the user. This doesn't have to be unique. If not + // specified at creation, the cluster name will be an empty string. For job + // clusters, the cluster name is automatically set based on the job and job run + // IDs. + ClusterName *string + // The Spark version of the cluster, e.g. `3.3.x-scala2.11`. A list of available + // Spark versions can be retrieved by using the [clusters/sparkVersions] API + // call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + SparkVersion *string + // An object containing a set of optional, user-specified Spark configuration + // key-value pairs. Users can also pass in a string of extra JVM options to the + // driver and the executors via `spark.driver.extraJavaOptions` and + // `spark.executor.extraJavaOptions` respectively. + SparkConf map[string]string + // Attributes related to clusters running on Amazon Web Services. If not + // specified at cluster creation, a set of default values will be used. + AwsAttributes *AwsAttributes + // Attributes related to clusters running on Microsoft Azure. If not specified + // at cluster creation, a set of default values will be used. + AzureAttributes *AzureAttributes + // Attributes related to clusters running on Google Cloud Platform. If not + // specified at cluster creation, a set of default values will be used. + GcpAttributes *GcpAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // The node type of the Spark driver. Note that this field is optional; if + // unset, the driver node type will be set as the same value as `node_type_id` + // defined above. + // + // This field, along with node_type_id, should not be set if + // virtual_cluster_size is set. If both driver_node_type_id, node_type_id, and + // virtual_cluster_size are specified, driver_node_type_id and node_type_id take + // precedence. + DriverNodeTypeId *string + // Flexible node type configuration for worker nodes. + WorkerNodeTypeFlexibility *NodeTypeFlexibility + // Flexible node type configuration for the driver node. + DriverNodeTypeFlexibility *NodeTypeFlexibility + // SSH public key contents that will be added to each Spark node in this + // cluster. The corresponding private keys can be used to login with the user + // name `ubuntu` on port `2200`. Up to 10 keys can be specified. + SshPublicKeys []string + // Additional tags for cluster resources. will tag all cluster + // resources (e.g., AWS instances and EBS volumes) with these tags in addition + // to `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + // + // - Clusters can only reuse cloud resources if the resources' tags are a subset + // of the cluster tags + CustomTags map[string]string + // The configuration for delivering spark logs to a long-term storage + // destination. Three kinds of destinations (DBFS, S3 and Unity Catalog volumes) + // are supported. Only one destination can be specified for one cluster. If the + // conf is given, the logs will be delivered to the destination every `5 mins`. + // The destination of driver logs is `$destination/$clusterId/driver`, while the + // destination of executor logs is `$destination/$clusterId/executor`. + ClusterLogConf *ClusterLogConf + // An object containing a set of optional, user-specified environment variable + // key-value pairs. Please note that key-value pair of the form (X,Y) will be + // exported as is (i.e., `export X='Y'`) while launching the driver and workers. + // + // In order to specify an additional set of `SPARK_DAEMON_JAVA_OPTS`, we + // recommend appending them to `$SPARK_DAEMON_JAVA_OPTS` as shown in the example + // below. This ensures that all default databricks managed environmental + // variables are included as well. + // + // Example Spark environment variables: `{"SPARK_WORKER_MEMORY": "28000m", + // "SPARK_LOCAL_DIRS": "/local_disk0"}` or `{"SPARK_DAEMON_JAVA_OPTS": + // "$SPARK_DAEMON_JAVA_OPTS -Dspark.shuffle.service.enabled=true"}` + SparkEnvVars map[string]string + // Automatically terminates the cluster after it is inactive for this time in + // minutes. If not set, this cluster will not be automatically terminated. If + // specified, the threshold must be between 10 and 10000 minutes. Users can also + // set this value to 0 to explicitly disable automatic termination. + AutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this cluster will dynamically + // acquire additional disk space when its Spark workers are running low on disk + // space. + EnableElasticDisk *bool + // The configuration for storing init scripts. Any number of destinations can be + // specified. The scripts are executed sequentially in the order provided. If + // `cluster_log_conf` is specified, init script logs are sent to + // `//init_scripts`. + InitScripts []InitScriptInfo + // Custom docker image BYOC + DockerImage *DockerImage + // The optional ID of the instance pool to which the cluster belongs. + InstancePoolId *string + // Single user name if data_security_mode is `SINGLE_USER` + SingleUserName *string + // The ID of the cluster policy used to create the cluster if applicable. + PolicyId *string + // Whether to enable LUKS on cluster VMs' local disks + EnableLocalDiskEncryption *bool + // The optional ID of the instance pool for the driver of the cluster belongs. + // The pool cluster uses the instance pool with id (instance_pool_id) if the + // driver pool is not assigned. + DriverInstancePoolId *string + WorkloadType *WorkloadType + DataSecurityMode DataSecurityMode + // Determines the cluster's runtime engine, either standard or Photon. + // + // This field is not compatible with legacy `spark_version` values that contain + // `-photon-`. Remove `-photon-` from the `spark_version` and set + // `runtime_engine` to `PHOTON`. + // + // If left unspecified, the runtime engine defaults to standard unless the + // spark_version contains -photon-, in which case Photon will be used. + RuntimeEngine RuntimeEngine + Kind ComputeKind + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // `effective_spark_version` is determined by `spark_version` (DBR release), + // this field `use_ml_runtime`, and whether `node_type_id` is gpu node or not. + UseMlRuntime *bool + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // When set to true, will automatically set single node related + // `custom_tags`, `spark_conf`, and `num_workers` + IsSingleNode *bool + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED disks. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED disks. + TotalInitialRemoteDiskSize *int + // Controls dependency configuration for the cluster. + DependencyMode DependencyMode + Size isClusterInfo_ComputeSpec_Size +} + +type isClusterInfo_ComputeSpec_Size interface { + isClusterInfo_ComputeSpec_Size() +} + +// ClusterInfo_ComputeSpec_Size_NumWorkers selects NumWorkers for ClusterInfo_ComputeSpec.Size. +// Number of worker nodes that this cluster should have. A cluster has one Spark +// Driver and `num_workers` Executors for a total of `num_workers` + 1 Spark +// nodes. +// +// Note: When reading the properties of a cluster, this field reflects the +// desired number of workers rather than the actual current number of workers. +// For instance, if a cluster is resized from 5 to 10 workers, this field will +// immediately be updated to reflect the target size of 10 workers, whereas the +// workers listed in `spark_info` will gradually increase from 5 to 10 as the +// new nodes are provisioned. +type ClusterInfo_ComputeSpec_Size_NumWorkers struct { + NumWorkers int +} + +func (*ClusterInfo_ComputeSpec_Size_NumWorkers) isClusterInfo_ComputeSpec_Size() {} + +// ClusterInfo_ComputeSpec_Size_Autoscale selects Autoscale for ClusterInfo_ComputeSpec.Size. +// Parameters needed in order to automatically scale clusters up and down based +// on load. Note: autoscaling works best with DB runtime versions 3.0 or later. +type ClusterInfo_ComputeSpec_Size_Autoscale struct { + Autoscale AutoScale +} + +func (*ClusterInfo_ComputeSpec_Size_Autoscale) isClusterInfo_ComputeSpec_Size() {} + +// Cluster log delivery config. +type ClusterLogConf struct { + StorageInfo isClusterLogConf_StorageInfo + _ [0]clusterLogConfStorageInfoFieldMaskMetadata `fieldmask_oneof:"StorageInfo"` +} + +type isClusterLogConf_StorageInfo interface { + isClusterLogConf_StorageInfo() +} + +// ClusterLogConf_StorageInfo_Dbfs selects Dbfs for ClusterLogConf.StorageInfo. +// destination needs to be provided. e.g. `{ "dbfs" : { "destination" : +// "dbfs:/home/cluster_log" } }` +type ClusterLogConf_StorageInfo_Dbfs struct { + Dbfs DbfsStorageInfo `fieldmask:"dbfs"` +} + +func (*ClusterLogConf_StorageInfo_Dbfs) isClusterLogConf_StorageInfo() {} + +// ClusterLogConf_StorageInfo_S3 selects S3 for ClusterLogConf.StorageInfo. +// destination and either the region or endpoint need to be provided. e.g. `{ +// "s3": { "destination" : "s3://cluster_log_bucket/prefix", "region" : +// "us-west-2" } }` Cluster iam role is used to access s3, please make sure the +// cluster iam role in `instance_profile_arn` has permission to write data to +// the s3 destination. +type ClusterLogConf_StorageInfo_S3 struct { + S3 S3StorageInfo `fieldmask:"s3"` +} + +func (*ClusterLogConf_StorageInfo_S3) isClusterLogConf_StorageInfo() {} + +// ClusterLogConf_StorageInfo_Volumes selects Volumes for ClusterLogConf.StorageInfo. +// destination needs to be provided, e.g. `{ "volumes": { "destination": +// "/Volumes/catalog/schema/volume/cluster_log" } }` +type ClusterLogConf_StorageInfo_Volumes struct { + Volumes VolumesStorageInfo `fieldmask:"volumes"` +} + +func (*ClusterLogConf_StorageInfo_Volumes) isClusterLogConf_StorageInfo() {} + +type clusterLogConfStorageInfoFieldMaskMetadata struct { + *ClusterLogConf_StorageInfo_Dbfs + *ClusterLogConf_StorageInfo_S3 + *ClusterLogConf_StorageInfo_Volumes +} + +// Represents a cluster revision. +// +// Only the 100 most recent revisions are stored for each cluster.. +type ClusterRevision struct { + // ID of the cluster revision. + RevisionId *string + // Time when the cluster revision was created. + CreateTime *types.Time + // Settings used to create/edit the cluster. + Settings *ClusterInfo_ComputeSpec + // Reason the cluster was edited. + EditReason ClusterEditReason + // Name of the user who edited this cluster. + EditUser *string + // Whether this is the current revision. + IsCurrent *bool +} + +type ClusterSize struct { + Size isClusterSize_Size +} + +type isClusterSize_Size interface { + isClusterSize_Size() +} + +// ClusterSize_Size_NumWorkers selects NumWorkers for ClusterSize.Size. +// Number of worker nodes that this cluster should have. A cluster has one Spark +// Driver and `num_workers` Executors for a total of `num_workers` + 1 Spark +// nodes. +// +// Note: When reading the properties of a cluster, this field reflects the +// desired number of workers rather than the actual current number of workers. +// For instance, if a cluster is resized from 5 to 10 workers, this field will +// immediately be updated to reflect the target size of 10 workers, whereas the +// workers listed in `spark_info` will gradually increase from 5 to 10 as the +// new nodes are provisioned. +type ClusterSize_Size_NumWorkers struct { + NumWorkers int +} + +func (*ClusterSize_Size_NumWorkers) isClusterSize_Size() {} + +// ClusterSize_Size_Autoscale selects Autoscale for ClusterSize.Size. +// Parameters needed in order to automatically scale clusters up and down based +// on load. Note: autoscaling works best with DB runtime versions 3.0 or later. +type ClusterSize_Size_Autoscale struct { + Autoscale AutoScale +} + +func (*ClusterSize_Size_Autoscale) isClusterSize_Size() {} + +type ClusterState struct { +} + +type CreateClusterRequest struct { + // When set to true, fixed and default values from the policy will be used for + // fields that are omitted. When set to false, only fixed values from the policy + // will be applied. + ApplyPolicyDefaultValues *bool + // When specified, this clones libraries from a source cluster during the + // creation of a new cluster. + CloneFrom *CloneCluster + Size isCreateClusterRequest_Size + // Cluster name requested by the user. This doesn't have to be unique. If not + // specified at creation, the cluster name will be an empty string. For job + // clusters, the cluster name is automatically set based on the job and job run + // IDs. + ClusterName *string + // The Spark version of the cluster, e.g. `3.3.x-scala2.11`. A list of available + // Spark versions can be retrieved by using the [clusters/sparkVersions] API + // call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + SparkVersion *string + // An object containing a set of optional, user-specified Spark configuration + // key-value pairs. Users can also pass in a string of extra JVM options to the + // driver and the executors via `spark.driver.extraJavaOptions` and + // `spark.executor.extraJavaOptions` respectively. + SparkConf map[string]string + // Attributes related to clusters running on Amazon Web Services. If not + // specified at cluster creation, a set of default values will be used. + AwsAttributes *AwsAttributes + // Attributes related to clusters running on Microsoft Azure. If not specified + // at cluster creation, a set of default values will be used. + AzureAttributes *AzureAttributes + // Attributes related to clusters running on Google Cloud Platform. If not + // specified at cluster creation, a set of default values will be used. + GcpAttributes *GcpAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // The node type of the Spark driver. Note that this field is optional; if + // unset, the driver node type will be set as the same value as `node_type_id` + // defined above. + // + // This field, along with node_type_id, should not be set if + // virtual_cluster_size is set. If both driver_node_type_id, node_type_id, and + // virtual_cluster_size are specified, driver_node_type_id and node_type_id take + // precedence. + DriverNodeTypeId *string + // Flexible node type configuration for worker nodes. + WorkerNodeTypeFlexibility *NodeTypeFlexibility + // Flexible node type configuration for the driver node. + DriverNodeTypeFlexibility *NodeTypeFlexibility + // SSH public key contents that will be added to each Spark node in this + // cluster. The corresponding private keys can be used to login with the user + // name `ubuntu` on port `2200`. Up to 10 keys can be specified. + SshPublicKeys []string + // Additional tags for cluster resources. will tag all cluster + // resources (e.g., AWS instances and EBS volumes) with these tags in addition + // to `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + // + // - Clusters can only reuse cloud resources if the resources' tags are a subset + // of the cluster tags + CustomTags map[string]string + // The configuration for delivering spark logs to a long-term storage + // destination. Three kinds of destinations (DBFS, S3 and Unity Catalog volumes) + // are supported. Only one destination can be specified for one cluster. If the + // conf is given, the logs will be delivered to the destination every `5 mins`. + // The destination of driver logs is `$destination/$clusterId/driver`, while the + // destination of executor logs is `$destination/$clusterId/executor`. + ClusterLogConf *ClusterLogConf + // An object containing a set of optional, user-specified environment variable + // key-value pairs. Please note that key-value pair of the form (X,Y) will be + // exported as is (i.e., `export X='Y'`) while launching the driver and workers. + // + // In order to specify an additional set of `SPARK_DAEMON_JAVA_OPTS`, we + // recommend appending them to `$SPARK_DAEMON_JAVA_OPTS` as shown in the example + // below. This ensures that all default databricks managed environmental + // variables are included as well. + // + // Example Spark environment variables: `{"SPARK_WORKER_MEMORY": "28000m", + // "SPARK_LOCAL_DIRS": "/local_disk0"}` or `{"SPARK_DAEMON_JAVA_OPTS": + // "$SPARK_DAEMON_JAVA_OPTS -Dspark.shuffle.service.enabled=true"}` + SparkEnvVars map[string]string + // Automatically terminates the cluster after it is inactive for this time in + // minutes. If not set, this cluster will not be automatically terminated. If + // specified, the threshold must be between 10 and 10000 minutes. Users can also + // set this value to 0 to explicitly disable automatic termination. + AutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this cluster will dynamically + // acquire additional disk space when its Spark workers are running low on disk + // space. + EnableElasticDisk *bool + // The configuration for storing init scripts. Any number of destinations can be + // specified. The scripts are executed sequentially in the order provided. If + // `cluster_log_conf` is specified, init script logs are sent to + // `//init_scripts`. + InitScripts []InitScriptInfo + // Custom docker image BYOC + DockerImage *DockerImage + // The optional ID of the instance pool to which the cluster belongs. + InstancePoolId *string + // Single user name if data_security_mode is `SINGLE_USER` + SingleUserName *string + // The ID of the cluster policy used to create the cluster if applicable. + PolicyId *string + // Whether to enable LUKS on cluster VMs' local disks + EnableLocalDiskEncryption *bool + // The optional ID of the instance pool for the driver of the cluster belongs. + // The pool cluster uses the instance pool with id (instance_pool_id) if the + // driver pool is not assigned. + DriverInstancePoolId *string + WorkloadType *WorkloadType + DataSecurityMode DataSecurityMode + // Determines the cluster's runtime engine, either standard or Photon. + // + // This field is not compatible with legacy `spark_version` values that contain + // `-photon-`. Remove `-photon-` from the `spark_version` and set + // `runtime_engine` to `PHOTON`. + // + // If left unspecified, the runtime engine defaults to standard unless the + // spark_version contains -photon-, in which case Photon will be used. + RuntimeEngine RuntimeEngine + Kind ComputeKind + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // `effective_spark_version` is determined by `spark_version` (DBR release), + // this field `use_ml_runtime`, and whether `node_type_id` is gpu node or not. + UseMlRuntime *bool + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // When set to true, will automatically set single node related + // `custom_tags`, `spark_conf`, and `num_workers` + IsSingleNode *bool + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED disks. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED disks. + TotalInitialRemoteDiskSize *int + // Controls dependency configuration for the cluster. + DependencyMode DependencyMode +} + +type isCreateClusterRequest_Size interface { + isCreateClusterRequest_Size() +} + +// CreateClusterRequest_Size_NumWorkers selects NumWorkers for CreateClusterRequest.Size. +// Number of worker nodes that this cluster should have. A cluster has one Spark +// Driver and `num_workers` Executors for a total of `num_workers` + 1 Spark +// nodes. +// +// Note: When reading the properties of a cluster, this field reflects the +// desired number of workers rather than the actual current number of workers. +// For instance, if a cluster is resized from 5 to 10 workers, this field will +// immediately be updated to reflect the target size of 10 workers, whereas the +// workers listed in `spark_info` will gradually increase from 5 to 10 as the +// new nodes are provisioned. +type CreateClusterRequest_Size_NumWorkers struct { + NumWorkers int +} + +func (*CreateClusterRequest_Size_NumWorkers) isCreateClusterRequest_Size() {} + +// CreateClusterRequest_Size_Autoscale selects Autoscale for CreateClusterRequest.Size. +// Parameters needed in order to automatically scale clusters up and down based +// on load. Note: autoscaling works best with DB runtime versions 3.0 or later. +type CreateClusterRequest_Size_Autoscale struct { + Autoscale AutoScale +} + +func (*CreateClusterRequest_Size_Autoscale) isCreateClusterRequest_Size() {} + +type CreateClusterResponse struct { + ClusterId *string +} + +type DataPlaneEventDetails struct { + EventType DataPlaneClusterEventType + Timestamp *int64 + HostId *string + ExecutorFailures *int +} + +// A storage location in DBFS. +type DbfsStorageInfo struct { + // dbfs destination, e.g. `dbfs:/my/path` + Destination *string `fieldmask:"destination"` +} + +type DeleteClusterRequest struct { + // The cluster to be terminated. + ClusterId *string +} + +type DeleteClusterResponse struct { +} + +type DockerBasicAuth struct { + // Name of the user + Username *string `fieldmask:"username"` + // Password of the user + Password *string `fieldmask:"password"` +} + +type DockerImage struct { + // URL of the docker image. + Url *string `fieldmask:"url"` + CredsOneof isDockerImage_CredsOneof + _ [0]dockerImageCredsOneofFieldMaskMetadata `fieldmask_oneof:"CredsOneof"` +} + +type isDockerImage_CredsOneof interface { + isDockerImage_CredsOneof() +} + +// DockerImage_CredsOneof_BasicAuth selects BasicAuth for DockerImage.CredsOneof. +// Basic auth with username and password +type DockerImage_CredsOneof_BasicAuth struct { + BasicAuth DockerBasicAuth `fieldmask:"basic_auth"` +} + +func (*DockerImage_CredsOneof_BasicAuth) isDockerImage_CredsOneof() {} + +type dockerImageCredsOneofFieldMaskMetadata struct { + *DockerImage_CredsOneof_BasicAuth +} + +type EditClusterRequest struct { + // ID of the cluster + ClusterId *string + // When set to true, fixed and default values from the policy will be used for + // fields that are omitted. When set to false, only fixed values from the policy + // will be applied. + ApplyPolicyDefaultValues *bool + Size isEditClusterRequest_Size + // Cluster name requested by the user. This doesn't have to be unique. If not + // specified at creation, the cluster name will be an empty string. For job + // clusters, the cluster name is automatically set based on the job and job run + // IDs. + ClusterName *string + // The Spark version of the cluster, e.g. `3.3.x-scala2.11`. A list of available + // Spark versions can be retrieved by using the [clusters/sparkVersions] API + // call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + SparkVersion *string + // An object containing a set of optional, user-specified Spark configuration + // key-value pairs. Users can also pass in a string of extra JVM options to the + // driver and the executors via `spark.driver.extraJavaOptions` and + // `spark.executor.extraJavaOptions` respectively. + SparkConf map[string]string + // Attributes related to clusters running on Amazon Web Services. If not + // specified at cluster creation, a set of default values will be used. + AwsAttributes *AwsAttributes + // Attributes related to clusters running on Microsoft Azure. If not specified + // at cluster creation, a set of default values will be used. + AzureAttributes *AzureAttributes + // Attributes related to clusters running on Google Cloud Platform. If not + // specified at cluster creation, a set of default values will be used. + GcpAttributes *GcpAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // The node type of the Spark driver. Note that this field is optional; if + // unset, the driver node type will be set as the same value as `node_type_id` + // defined above. + // + // This field, along with node_type_id, should not be set if + // virtual_cluster_size is set. If both driver_node_type_id, node_type_id, and + // virtual_cluster_size are specified, driver_node_type_id and node_type_id take + // precedence. + DriverNodeTypeId *string + // Flexible node type configuration for worker nodes. + WorkerNodeTypeFlexibility *NodeTypeFlexibility + // Flexible node type configuration for the driver node. + DriverNodeTypeFlexibility *NodeTypeFlexibility + // SSH public key contents that will be added to each Spark node in this + // cluster. The corresponding private keys can be used to login with the user + // name `ubuntu` on port `2200`. Up to 10 keys can be specified. + SshPublicKeys []string + // Additional tags for cluster resources. will tag all cluster + // resources (e.g., AWS instances and EBS volumes) with these tags in addition + // to `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + // + // - Clusters can only reuse cloud resources if the resources' tags are a subset + // of the cluster tags + CustomTags map[string]string + // The configuration for delivering spark logs to a long-term storage + // destination. Three kinds of destinations (DBFS, S3 and Unity Catalog volumes) + // are supported. Only one destination can be specified for one cluster. If the + // conf is given, the logs will be delivered to the destination every `5 mins`. + // The destination of driver logs is `$destination/$clusterId/driver`, while the + // destination of executor logs is `$destination/$clusterId/executor`. + ClusterLogConf *ClusterLogConf + // An object containing a set of optional, user-specified environment variable + // key-value pairs. Please note that key-value pair of the form (X,Y) will be + // exported as is (i.e., `export X='Y'`) while launching the driver and workers. + // + // In order to specify an additional set of `SPARK_DAEMON_JAVA_OPTS`, we + // recommend appending them to `$SPARK_DAEMON_JAVA_OPTS` as shown in the example + // below. This ensures that all default databricks managed environmental + // variables are included as well. + // + // Example Spark environment variables: `{"SPARK_WORKER_MEMORY": "28000m", + // "SPARK_LOCAL_DIRS": "/local_disk0"}` or `{"SPARK_DAEMON_JAVA_OPTS": + // "$SPARK_DAEMON_JAVA_OPTS -Dspark.shuffle.service.enabled=true"}` + SparkEnvVars map[string]string + // Automatically terminates the cluster after it is inactive for this time in + // minutes. If not set, this cluster will not be automatically terminated. If + // specified, the threshold must be between 10 and 10000 minutes. Users can also + // set this value to 0 to explicitly disable automatic termination. + AutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this cluster will dynamically + // acquire additional disk space when its Spark workers are running low on disk + // space. + EnableElasticDisk *bool + // The configuration for storing init scripts. Any number of destinations can be + // specified. The scripts are executed sequentially in the order provided. If + // `cluster_log_conf` is specified, init script logs are sent to + // `//init_scripts`. + InitScripts []InitScriptInfo + // Custom docker image BYOC + DockerImage *DockerImage + // The optional ID of the instance pool to which the cluster belongs. + InstancePoolId *string + // Single user name if data_security_mode is `SINGLE_USER` + SingleUserName *string + // The ID of the cluster policy used to create the cluster if applicable. + PolicyId *string + // Whether to enable LUKS on cluster VMs' local disks + EnableLocalDiskEncryption *bool + // The optional ID of the instance pool for the driver of the cluster belongs. + // The pool cluster uses the instance pool with id (instance_pool_id) if the + // driver pool is not assigned. + DriverInstancePoolId *string + WorkloadType *WorkloadType + DataSecurityMode DataSecurityMode + // Determines the cluster's runtime engine, either standard or Photon. + // + // This field is not compatible with legacy `spark_version` values that contain + // `-photon-`. Remove `-photon-` from the `spark_version` and set + // `runtime_engine` to `PHOTON`. + // + // If left unspecified, the runtime engine defaults to standard unless the + // spark_version contains -photon-, in which case Photon will be used. + RuntimeEngine RuntimeEngine + Kind ComputeKind + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // `effective_spark_version` is determined by `spark_version` (DBR release), + // this field `use_ml_runtime`, and whether `node_type_id` is gpu node or not. + UseMlRuntime *bool + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // When set to true, will automatically set single node related + // `custom_tags`, `spark_conf`, and `num_workers` + IsSingleNode *bool + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED disks. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED disks. + TotalInitialRemoteDiskSize *int + // Controls dependency configuration for the cluster. + DependencyMode DependencyMode +} + +type isEditClusterRequest_Size interface { + isEditClusterRequest_Size() +} + +// EditClusterRequest_Size_NumWorkers selects NumWorkers for EditClusterRequest.Size. +// Number of worker nodes that this cluster should have. A cluster has one Spark +// Driver and `num_workers` Executors for a total of `num_workers` + 1 Spark +// nodes. +// +// Note: When reading the properties of a cluster, this field reflects the +// desired number of workers rather than the actual current number of workers. +// For instance, if a cluster is resized from 5 to 10 workers, this field will +// immediately be updated to reflect the target size of 10 workers, whereas the +// workers listed in `spark_info` will gradually increase from 5 to 10 as the +// new nodes are provisioned. +type EditClusterRequest_Size_NumWorkers struct { + NumWorkers int +} + +func (*EditClusterRequest_Size_NumWorkers) isEditClusterRequest_Size() {} + +// EditClusterRequest_Size_Autoscale selects Autoscale for EditClusterRequest.Size. +// Parameters needed in order to automatically scale clusters up and down based +// on load. Note: autoscaling works best with DB runtime versions 3.0 or later. +type EditClusterRequest_Size_Autoscale struct { + Autoscale AutoScale +} + +func (*EditClusterRequest_Size_Autoscale) isEditClusterRequest_Size() {} + +type EditClusterResponse struct { +} + +type EnforcePolicyComplianceForClusterRequest struct { + // The ID of the cluster you want to enforce policy compliance on. + ClusterId *string + // If set, previews the changes that would be made to a cluster to enforce + // compliance but does not update the cluster. + ValidateOnly *bool + // Determines how changes should be made to clusters that are not in + // `TERMINATED` state. + // + // - `ENFORCE_IMMEDIATELY`: If the cluster is in a `RUNNING` state, it will be + // restarted so that the new attributes can take effect. For other states aside + // from `TERMINATED` state, the request will be rejected. - + // `WAIT_FOR_TERMINATION`: The cluster is not immediately edited. Instead, a + // pending enforcement is scheduled to update the cluster when it terminates or + // restarts. When this occurs, `enforce_result` will contain `DEFERRED`. Only + // workspace admins can use this mode. + // + // Regardless of the enforce mode, clusters in `TERMINATED` state are + // immediately edited. + EnforceMode EnforcePolicyComplianceForClusterRequest_EnforceMode +} + +type EnforcePolicyComplianceForClusterResponse struct { + // Whether any changes have been made to the cluster settings for the cluster to + // become compliant with its policy. + HasChanges *bool + // A list of changes that have been made to the cluster settings for the cluster + // to become compliant with its policy. + Changes []EnforcePolicyComplianceForClusterResponse_ClusterSettingsChange + // Describes whether changes have been applied to the cluster. + EnforceResult EnforcePolicyComplianceForClusterResponse_EnforceResult +} + +type EnforcePolicyComplianceForClusterResponse_ClusterSettings struct { + // Cluster name requested by the user. This doesn't have to be unique. If not + // specified at creation, the cluster name will be an empty string. For job + // clusters, the cluster name is automatically set based on the job and job run + // IDs. + ClusterName *string + // The Spark version of the cluster, e.g. `3.3.x-scala2.11`. A list of available + // Spark versions can be retrieved by using the [clusters/sparkVersions] API + // call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + SparkVersion *string + // An object containing a set of optional, user-specified Spark configuration + // key-value pairs. Users can also pass in a string of extra JVM options to the + // driver and the executors via `spark.driver.extraJavaOptions` and + // `spark.executor.extraJavaOptions` respectively. + SparkConf map[string]string + // Attributes related to clusters running on Amazon Web Services. If not + // specified at cluster creation, a set of default values will be used. + AwsAttributes *AwsAttributes + // Attributes related to clusters running on Microsoft Azure. If not specified + // at cluster creation, a set of default values will be used. + AzureAttributes *AzureAttributes + // Attributes related to clusters running on Google Cloud Platform. If not + // specified at cluster creation, a set of default values will be used. + GcpAttributes *GcpAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // The node type of the Spark driver. Note that this field is optional; if + // unset, the driver node type will be set as the same value as `node_type_id` + // defined above. + // + // This field, along with node_type_id, should not be set if + // virtual_cluster_size is set. If both driver_node_type_id, node_type_id, and + // virtual_cluster_size are specified, driver_node_type_id and node_type_id take + // precedence. + DriverNodeTypeId *string + // Flexible node type configuration for worker nodes. + WorkerNodeTypeFlexibility *NodeTypeFlexibility + // Flexible node type configuration for the driver node. + DriverNodeTypeFlexibility *NodeTypeFlexibility + // SSH public key contents that will be added to each Spark node in this + // cluster. The corresponding private keys can be used to login with the user + // name `ubuntu` on port `2200`. Up to 10 keys can be specified. + SshPublicKeys []string + // Additional tags for cluster resources. will tag all cluster + // resources (e.g., AWS instances and EBS volumes) with these tags in addition + // to `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + // + // - Clusters can only reuse cloud resources if the resources' tags are a subset + // of the cluster tags + CustomTags map[string]string + // The configuration for delivering spark logs to a long-term storage + // destination. Three kinds of destinations (DBFS, S3 and Unity Catalog volumes) + // are supported. Only one destination can be specified for one cluster. If the + // conf is given, the logs will be delivered to the destination every `5 mins`. + // The destination of driver logs is `$destination/$clusterId/driver`, while the + // destination of executor logs is `$destination/$clusterId/executor`. + ClusterLogConf *ClusterLogConf + // An object containing a set of optional, user-specified environment variable + // key-value pairs. Please note that key-value pair of the form (X,Y) will be + // exported as is (i.e., `export X='Y'`) while launching the driver and workers. + // + // In order to specify an additional set of `SPARK_DAEMON_JAVA_OPTS`, we + // recommend appending them to `$SPARK_DAEMON_JAVA_OPTS` as shown in the example + // below. This ensures that all default databricks managed environmental + // variables are included as well. + // + // Example Spark environment variables: `{"SPARK_WORKER_MEMORY": "28000m", + // "SPARK_LOCAL_DIRS": "/local_disk0"}` or `{"SPARK_DAEMON_JAVA_OPTS": + // "$SPARK_DAEMON_JAVA_OPTS -Dspark.shuffle.service.enabled=true"}` + SparkEnvVars map[string]string + // Automatically terminates the cluster after it is inactive for this time in + // minutes. If not set, this cluster will not be automatically terminated. If + // specified, the threshold must be between 10 and 10000 minutes. Users can also + // set this value to 0 to explicitly disable automatic termination. + AutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this cluster will dynamically + // acquire additional disk space when its Spark workers are running low on disk + // space. + EnableElasticDisk *bool + // The configuration for storing init scripts. Any number of destinations can be + // specified. The scripts are executed sequentially in the order provided. If + // `cluster_log_conf` is specified, init script logs are sent to + // `//init_scripts`. + InitScripts []InitScriptInfo + // Custom docker image BYOC + DockerImage *DockerImage + // The optional ID of the instance pool to which the cluster belongs. + InstancePoolId *string + // Single user name if data_security_mode is `SINGLE_USER` + SingleUserName *string + // The ID of the cluster policy used to create the cluster if applicable. + PolicyId *string + // Whether to enable LUKS on cluster VMs' local disks + EnableLocalDiskEncryption *bool + // The optional ID of the instance pool for the driver of the cluster belongs. + // The pool cluster uses the instance pool with id (instance_pool_id) if the + // driver pool is not assigned. + DriverInstancePoolId *string + WorkloadType *WorkloadType + DataSecurityMode DataSecurityMode + // Determines the cluster's runtime engine, either standard or Photon. + // + // This field is not compatible with legacy `spark_version` values that contain + // `-photon-`. Remove `-photon-` from the `spark_version` and set + // `runtime_engine` to `PHOTON`. + // + // If left unspecified, the runtime engine defaults to standard unless the + // spark_version contains -photon-, in which case Photon will be used. + RuntimeEngine RuntimeEngine + Kind ComputeKind + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // `effective_spark_version` is determined by `spark_version` (DBR release), + // this field `use_ml_runtime`, and whether `node_type_id` is gpu node or not. + UseMlRuntime *bool + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // When set to true, will automatically set single node related + // `custom_tags`, `spark_conf`, and `num_workers` + IsSingleNode *bool + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED disks. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED disks. + TotalInitialRemoteDiskSize *int + // Controls dependency configuration for the cluster. + DependencyMode DependencyMode + Size isEnforcePolicyComplianceForClusterResponse_ClusterSettings_Size +} + +type isEnforcePolicyComplianceForClusterResponse_ClusterSettings_Size interface { + isEnforcePolicyComplianceForClusterResponse_ClusterSettings_Size() +} + +// EnforcePolicyComplianceForClusterResponse_ClusterSettings_Size_NumWorkers selects NumWorkers for EnforcePolicyComplianceForClusterResponse_ClusterSettings.Size. +// Number of worker nodes that this cluster should have. A cluster has one Spark +// Driver and `num_workers` Executors for a total of `num_workers` + 1 Spark +// nodes. +// +// Note: When reading the properties of a cluster, this field reflects the +// desired number of workers rather than the actual current number of workers. +// For instance, if a cluster is resized from 5 to 10 workers, this field will +// immediately be updated to reflect the target size of 10 workers, whereas the +// workers listed in `spark_info` will gradually increase from 5 to 10 as the +// new nodes are provisioned. +type EnforcePolicyComplianceForClusterResponse_ClusterSettings_Size_NumWorkers struct { + NumWorkers int +} + +func (*EnforcePolicyComplianceForClusterResponse_ClusterSettings_Size_NumWorkers) isEnforcePolicyComplianceForClusterResponse_ClusterSettings_Size() { +} + +// EnforcePolicyComplianceForClusterResponse_ClusterSettings_Size_Autoscale selects Autoscale for EnforcePolicyComplianceForClusterResponse_ClusterSettings.Size. +// Parameters needed in order to automatically scale clusters up and down based +// on load. Note: autoscaling works best with DB runtime versions 3.0 or later. +type EnforcePolicyComplianceForClusterResponse_ClusterSettings_Size_Autoscale struct { + Autoscale AutoScale +} + +func (*EnforcePolicyComplianceForClusterResponse_ClusterSettings_Size_Autoscale) isEnforcePolicyComplianceForClusterResponse_ClusterSettings_Size() { +} + +// Represents a change to the cluster settings required for the cluster to +// become compliant with its policy.. +type EnforcePolicyComplianceForClusterResponse_ClusterSettingsChange struct { + // The field where this change would be made. + Field *string + // The previous value of this field before enforcing policy compliance (either a + // number, a boolean, or a string) converted to a string. This is intended to be + // read by a human. The type of the field can be retrieved by reading the + // settings field in the API response. + PreviousValue *string + // The new value of this field after enforcing policy compliance (either a + // number, a boolean, or a string) converted to a string. This is intended to be + // read by a human. The typed new value of this field can be retrieved by + // reading the settings field in the API response. + NewValue *string +} + +type EventDetails struct { + // The current number of nodes in the cluster. + CurrentNumWorkers *int + // The targeted number of nodes in the cluster. + TargetNumWorkers *int + // The cluster attributes before a cluster was edited. + PreviousAttributes *ClusterAttributes + // * For created clusters, the attributes of the cluster. * For edited clusters, + // the new attributes of the cluster. + Attributes *ClusterAttributes + // The size of the cluster before an edit or resize. + PreviousClusterSize *ClusterSize + // The actual cluster size that was set in the cluster creation or edit. + ClusterSize *ClusterSize + // The cause of a change in target size. + Cause ResizeCause_ResizeCause + // A termination reason: * On a TERMINATED event, this is the reason of the + // termination. * On a RESIZE_COMPLETE event, this indicates the reason that we + // failed to acquire some nodes. + Reason *TerminationReason + // The user that caused the event to occur. (Empty if it was done by the control + // plane.) + User *string + // Previous disk size in bytes + PreviousDiskSize *int64 + // Current disk size in bytes + DiskSize *int64 + FreeSpace *int64 + // Instance Id where the event originated from + InstanceId *string + DidNotExpandReason *string + // More details about the change in driver's state + DriverStateMessage *string + // Unique identifier of the specific job run associated with this cluster event + // * For clusters created for jobs, this will be the same as the cluster name + JobRunName *string + // List of global and cluster init scripts associated with this cluster event. + InitScripts *InitScriptEventDetails + // Whether or not a blocklisted node should be terminated. For ClusterEventType + // NODE_BLACKLISTED. + EnableTerminationForNodeBlocklisted *bool + // The current number of vCPUs in the cluster. + CurrentNumVcpus *int + // The targeted number of vCPUs in the cluster. + TargetNumVcpus *int +} + +// Attributes set during cluster creation which are related to GCP.. +type GcpAttributes struct { + // This field determines whether the spark executors will be scheduled to run on + // preemptible VMs (when set to true) versus standard compute engine VMs (when + // set to false; default). Note: Soon to be deprecated, use the 'availability' + // field instead. + UsePreemptibleExecutors *bool `fieldmask:"use_preemptible_executors"` + // If provided, the cluster will impersonate the google service account when + // accessing gcloud services (like GCS). The google service account must have + // previously been added to the environment by an account + // administrator. + GoogleServiceAccount *string `fieldmask:"google_service_account"` + // Boot disk size in GB + BootDiskSize *int `fieldmask:"boot_disk_size"` + // This field determines whether the spark executors will be scheduled to run on + // preemptible VMs, on-demand VMs, or preemptible VMs with a fallback to + // on-demand VMs if the former is unavailable. + Availability GcpAvailability `fieldmask:"availability"` + // Identifier for the availability zone in which the cluster resides. This can + // be one of the following: - "HA" => High availability, spread nodes across + // availability zones for a deployment region [default]. - "AUTO" + // => picks an availability zone to schedule the cluster on. - A + // GCP availability zone => Pick One of the available zones for (machine type + + // region) from https://cloud.google.com/compute/docs/regions-zones. + ZoneId *string `fieldmask:"zone_id"` + // If provided, each node (workers and driver) in the cluster will have this + // number of local SSDs attached. Each local SSD is 375GB in size. Refer to [GCP + // documentation] for the supported number of local SSDs for each instance type. + // + // [GCP documentation]: https://cloud.google.com/compute/docs/disks/local-ssd#choose_number_local_ssds + LocalSsdCount *int `fieldmask:"local_ssd_count"` + // The first `first_on_demand` nodes of the cluster will be placed on on-demand + // instances. This value should be greater than 0, to make sure the cluster + // driver node is placed on an on-demand instance. If this value is greater than + // or equal to the current cluster size, all nodes will be placed on on-demand + // instances. If this value is less than the current cluster size, + // `first_on_demand` nodes will be placed on on-demand instances and the + // remainder will be placed on `availability` instances. Note that this value + // does not affect cluster size and cannot currently be mutated over the + // lifetime of a cluster. + FirstOnDemand *int `fieldmask:"first_on_demand"` + // The confidential computing technology for this cluster's instances. Currently + // only SEV_SNP is supported, and only on N2D instance types. When not set, no + // confidential computing is applied. + ConfidentialComputeType ConfidentialComputeType `fieldmask:"confidential_compute_type"` +} + +// A storage location in Google Cloud Platform's GCS. +type GcsStorageInfo struct { + // GCS destination/URI, e.g. `gs://my-bucket/some-prefix` + Destination *string +} + +type GetClusterRequest struct { + // The cluster about which to retrieve information. + ClusterId *string +} + +// Request to get a cluster revision by ID.. +type GetClusterRevisionRequest struct { + // The fully qualified resource name of the cluster revision. Format: + // clusters/{cluster_id}/revisions/{revision_id}. + Name *string +} + +type GetEventsResponse struct { + Events []ClusterEvent + // Deprecated: use next_page_token or prev_page_token instead. + // + // The parameters required to retrieve the next page of events. Omitted if there + // are no more events to read. + NextPage *ListEventsRequest + // Deprecated: Returns 0 when request uses page_token. Will start returning zero + // when request uses offset/limit soon. + // + // The total number of events filtered by the start_time, end_time, and + // event_types. + TotalCount *int64 + // This field represents the pagination token to retrieve the next page of + // results. If the value is "", it means no further results for the request. + NextPageToken *string + // This field represents the pagination token to retrieve the previous page of + // results. If the value is "", it means no further results for the request. + PrevPageToken *string +} + +type GetPolicyComplianceForClusterRequest struct { + // The ID of the cluster to get the compliance status + ClusterId *string +} + +type GetPolicyComplianceForClusterResponse struct { + // Whether the cluster is compliant with its policy or not. Clusters could be + // out of compliance if the policy was updated after the cluster was last + // edited. + IsCompliant *bool + // An object containing key-value mappings representing the first 200 policy + // validation errors. The keys indicate the path where the policy validation + // error is occurring. The values indicate an error message describing the + // policy validation error. + Violations map[string]string + // Information about the pending enforcement for the cluster. Only present if a + // pending enforcement is scheduled for the cluster. + PendingEnforcement *PendingEnforcement +} + +// Returns the list of all Spark versions that can be used to create clusters.. +type GetSparkVersionsRequest struct { +} + +type GetSparkVersionsResponse struct { + // All the available Spark versions. + Versions []SparkVersion +} + +type InitScriptEventDetails struct { + // The private ip of the node we are reporting init script execution details for + // (we will select the execution details from only one node rather than + // reporting the execution details from every node to keep these event details + // small) + // + // This should only be defined for the INIT_SCRIPTS_FINISHED event + ReportedForNode *string + // The global init scripts associated with this cluster event. + Global []InitScriptEventDetails_InitScriptInfoAndExecutionDetails + // The cluster scoped init scripts associated with this cluster event. + Cluster []InitScriptEventDetails_InitScriptInfoAndExecutionDetails +} + +type InitScriptEventDetails_InitScriptInfoAndExecutionDetails struct { + StorageInfo isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo + // The current status of the script + Status InitScriptExecutionDetails_InitScriptExecutionStatus + // The number duration of the script execution in seconds + ExecutionDurationSeconds *int + // Additional details regarding errors (such as a file not found message if the + // status is FAILED_FETCH). This field should only be used to provide + // *additional* information to the status field, not duplicate it. + ErrorMessage *string + // The stderr output from the init script execution. Only populated when init + // scripts debug is enabled and script execution fails. + Stderr *string +} + +type isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo interface { + isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo() +} + +// InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Dbfs selects Dbfs for InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo. +// destination needs to be provided. e.g. `{ "dbfs": { "destination" : +// "dbfs:/home/cluster_log" } }` +type InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Dbfs struct { + Dbfs DbfsStorageInfo +} + +func (*InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Dbfs) isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo() { +} + +// InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_S3 selects S3 for InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo. +// destination and either the region or endpoint need to be provided. e.g. `{ +// \"s3\": { \"destination\": \"s3://cluster_log_bucket/prefix\", \"region\": +// \"us-west-2\" } }` Cluster iam role is used to access s3, please make sure +// the cluster iam role in `instance_profile_arn` has permission to write data +// to the s3 destination. +type InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_S3 struct { + S3 S3StorageInfo +} + +func (*InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_S3) isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo() { +} + +// InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_File selects File for InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo. +// destination needs to be provided, e.g. `{ "file": { "destination": +// "file:/my/local/file.sh" } }` +type InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_File struct { + File LocalFileInfo +} + +func (*InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_File) isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo() { +} + +// InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Gcs selects Gcs for InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo. +// destination needs to be provided, e.g. `{ "gcs": { "destination": +// "gs://my-bucket/file.sh" } }` +type InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Gcs struct { + Gcs GcsStorageInfo +} + +func (*InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Gcs) isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo() { +} + +// InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Abfss selects Abfss for InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo. +// destination needs to be provided, e.g. +// `abfss://@.dfs.core.windows.net/` +type InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Abfss struct { + Abfss Adlsgen2Info +} + +func (*InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Abfss) isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo() { +} + +// InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Workspace selects Workspace for InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo. +// destination needs to be provided, e.g. `{ "workspace": { "destination": +// "/cluster-init-scripts/setup-datadog.sh" } }` +type InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Workspace struct { + Workspace WorkspaceStorageInfo +} + +func (*InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Workspace) isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo() { +} + +// InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Volumes selects Volumes for InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo. +// destination needs to be provided. e.g. `{ \"volumes\" : { \"destination\" : +// \"/Volumes/my-init.sh\" } }` +type InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Volumes struct { + Volumes VolumesStorageInfo +} + +func (*InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Volumes) isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo() { +} + +type InitScriptExecutionDetails struct { +} + +// Config for an individual init script. +type InitScriptInfo struct { + StorageInfo isInitScriptInfo_StorageInfo +} + +type isInitScriptInfo_StorageInfo interface { + isInitScriptInfo_StorageInfo() +} + +// InitScriptInfo_StorageInfo_Dbfs selects Dbfs for InitScriptInfo.StorageInfo. +// destination needs to be provided. e.g. `{ "dbfs": { "destination" : +// "dbfs:/home/cluster_log" } }` +type InitScriptInfo_StorageInfo_Dbfs struct { + Dbfs DbfsStorageInfo +} + +func (*InitScriptInfo_StorageInfo_Dbfs) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_S3 selects S3 for InitScriptInfo.StorageInfo. +// destination and either the region or endpoint need to be provided. e.g. `{ +// \"s3\": { \"destination\": \"s3://cluster_log_bucket/prefix\", \"region\": +// \"us-west-2\" } }` Cluster iam role is used to access s3, please make sure +// the cluster iam role in `instance_profile_arn` has permission to write data +// to the s3 destination. +type InitScriptInfo_StorageInfo_S3 struct { + S3 S3StorageInfo +} + +func (*InitScriptInfo_StorageInfo_S3) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_File selects File for InitScriptInfo.StorageInfo. +// destination needs to be provided, e.g. `{ "file": { "destination": +// "file:/my/local/file.sh" } }` +type InitScriptInfo_StorageInfo_File struct { + File LocalFileInfo +} + +func (*InitScriptInfo_StorageInfo_File) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_Gcs selects Gcs for InitScriptInfo.StorageInfo. +// destination needs to be provided, e.g. `{ "gcs": { "destination": +// "gs://my-bucket/file.sh" } }` +type InitScriptInfo_StorageInfo_Gcs struct { + Gcs GcsStorageInfo +} + +func (*InitScriptInfo_StorageInfo_Gcs) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_Abfss selects Abfss for InitScriptInfo.StorageInfo. +// destination needs to be provided, e.g. +// `abfss://@.dfs.core.windows.net/` +type InitScriptInfo_StorageInfo_Abfss struct { + Abfss Adlsgen2Info +} + +func (*InitScriptInfo_StorageInfo_Abfss) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_Workspace selects Workspace for InitScriptInfo.StorageInfo. +// destination needs to be provided, e.g. `{ "workspace": { "destination": +// "/cluster-init-scripts/setup-datadog.sh" } }` +type InitScriptInfo_StorageInfo_Workspace struct { + Workspace WorkspaceStorageInfo +} + +func (*InitScriptInfo_StorageInfo_Workspace) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_Volumes selects Volumes for InitScriptInfo.StorageInfo. +// destination needs to be provided. e.g. `{ \"volumes\" : { \"destination\" : +// \"/Volumes/my-init.sh\" } }` +type InitScriptInfo_StorageInfo_Volumes struct { + Volumes VolumesStorageInfo +} + +func (*InitScriptInfo_StorageInfo_Volumes) isInitScriptInfo_StorageInfo() {} + +type ListAvailableZonesRequest struct { +} + +type ListAvailableZonesResponse struct { + // The list of available zones (e.g., ['us-west-2c', 'us-east-2']). + Zones []string + // The availability zone if no ``zone_id`` is provided in the cluster creation + // request. + DefaultZone *string +} + +type ListClusterComplianceForPolicyRequest struct { + // Canonical unique identifier for the cluster policy. + PolicyId *string + // A page token that can be used to navigate to the next page or previous page + // as returned by `next_page_token` or `prev_page_token`. + PageToken *string + // Use this field to specify the maximum number of results to be returned by the + // server. The server may further constrain the maximum number of results + // returned in a single page. + PageSize *int +} + +type ListClusterComplianceForPolicyResponse struct { + // A list of clusters and their policy compliance statuses. + Clusters []ClusterCompliance + // This field represents the pagination token to retrieve the next page of + // results. If the value is "", it means no further results for the request. + NextPageToken *string + // This field represents the pagination token to retrieve the previous page of + // results. If the value is "", it means no further results for the request. + PrevPageToken *string +} + +// Request to list cluster revisions.. +type ListClusterRevisionsRequest struct { + // The fully qualified resource name of the parent cluster. Format: + // clusters/{cluster_id}. + Parent *string + // Maximum number of cluster revisions to return per page. + PageSize *int + // Pagination token from a previous list cluster revisions request. + PageToken *string +} + +// Response when listing cluster revisions.. +type ListClusterRevisionsResponse struct { + // Cluster revisions in the current page. + ClusterRevisions []ClusterRevision + // Token for fetching the next page. Empty when there are no more results. + NextPageToken *string +} + +type ListClustersRequest struct { + // Use next_page_token or prev_page_token returned from the previous request to + // list the next or previous page of clusters respectively. + PageToken *string + // Use this field to specify the maximum number of results to be returned by the + // server. The server may further constrain the maximum number of results + // returned in a single page. + PageSize *int +} + +type ListClustersResponse struct { + Clusters []ClusterInfo + // This field represents the pagination token to retrieve the next page of + // results. If the value is "", it means no further results for the request. + NextPageToken *string + // This field represents the pagination token to retrieve the previous page of + // results. If the value is "", it means no further results for the request. + PrevPageToken *string +} + +type ListEventsRequest struct { + // The ID of the cluster to retrieve events about. + ClusterId *string + // The start time in epoch milliseconds. If empty, returns events starting from + // the beginning of time. + StartTime *int64 + // The end time in epoch milliseconds. If empty, returns events up to the + // current time. + EndTime *int64 + // The order to list events in; either "ASC" or "DESC". Defaults to "DESC". + Order GetEventsOrder + // An optional set of event types to filter on. If empty, all event types are + // returned. + EventTypes []ClusterEventType_ClusterEventType + // Deprecated: use page_token in combination with page_size instead. + // + // The offset in the result set. Defaults to 0 (no offset). When an offset is + // specified and the results are requested in descending order, the end_time + // field is required. + Offset *int64 + // Deprecated: use page_token in combination with page_size instead. + // + // The maximum number of events to include in a page of events. Defaults to 50, + // and maximum allowed value is 500. + Limit *int64 + // Use next_page_token or prev_page_token returned from the previous request to + // list the next or previous page of events respectively. If page_token is + // empty, the first page is returned. + PageToken *string + // The maximum number of events to include in a page of events. The server may + // further constrain the maximum number of results returned in a single page. If + // the page_size is empty or 0, the server will decide the number of results to + // be returned. The field has to be in the range [0,500]. If the value is + // outside the range, the server enforces 0 or 500. + PageSize *int +} + +type ListNodeTypesRequest struct { +} + +type ListNodeTypesResponse struct { + // The list of available Spark node types. + NodeTypes []NodeType +} + +type LocalFileInfo struct { + // local file destination, e.g. `file:/my/local/file.sh` + Destination *string +} + +type LogAnalyticsInfo struct { + LogAnalyticsWorkspaceId *string `fieldmask:"log_analytics_workspace_id"` + LogAnalyticsPrimaryKey *string `fieldmask:"log_analytics_primary_key"` +} + +// The log delivery status. +type LogSyncStatus struct { + // The timestamp of last attempt. If the last attempt fails, `last_exception` + // will contain the exception in the last attempt. + LastAttempted *int64 + // The exception thrown in the last attempt, it would be null (omitted in the + // response) if there is no exception in last attempted. + LastException *string +} + +// This structure embodies the machine type that hosts spark containers Note: +// this should be an internal data structure for now It is defined in proto in +// case we want to send it over the wire in the future (which is likely). +type NodeInstanceType struct { + // Unique identifier across instance types + InstanceTypeId *string + // Number of local disks that are present on this instance. + LocalDisks *int + // Size of the individual local disks attached to this instance (i.e. per local + // disk). + LocalDiskSizeGb *int + // Size of the individual local nvme disks attached to this instance (i.e. per + // local disk). + LocalNvmeDiskSizeGb *int + // Number of local nvme disks that are present on this instance. + LocalNvmeDisks *int +} + +// A description of a Spark node type including both the dimensions of the node +// and the instance type on which it will be hosted.. +type NodeType struct { + // Unique identifier for this node type. + NodeTypeId *string + // Memory (in MB) available for this node type. + MemoryMb *int + // Number of CPU cores available for this node type. Note that this can be + // fractional, e.g., 2.5 cores, if the number of cores on a machine instance is + // not divisible by the number of Spark nodes on that machine. + NumCores *float32 + // A string description associated with this node type, e.g., "r3.xlarge". + Description *string + // An identifier for the type of hardware that this node runs on, e.g., + // "r3.2xlarge" in AWS. + InstanceTypeId *string + // Whether the node type is deprecated. Non-deprecated node types offer greater + // performance. + IsDeprecated *bool + // A descriptive category for this node type. Examples include "Memory + // Optimized" and "Compute Optimized". + Category *string + // Whether this node type support EBS volumes. EBS volumes is disabled for node + // types that we could place multiple corresponding containers on the same + // hosting instance. + SupportEbsVolumes *bool + // Whether this node type support cluster tags. + SupportClusterTags *bool + // Number of GPUs available for this node type. + NumGpus *int + // The NodeInstanceType object corresponding to instance_type_id + NodeInstanceType *NodeInstanceType + // Whether this node is hidden from presentation in the UI. + IsHidden *bool + // Whether this node type supports port forwarding. + SupportPortForwarding *bool + // An optional hint at the display order of node types in the UI. Within a node + // type category, lowest numbers come first. + DisplayOrder *int + // Whether this node comes with IO cache enabled by default. + IsIoCacheEnabled *bool + // A collection of node type info reported by the cloud provider + NodeInfo *CloudProviderNodeInfo + PhotonWorkerCapable *bool + PhotonDriverCapable *bool + // AWS specific, whether this instance supports encryption in transit, used for + // hipaa and pci workloads. + IsEncryptedInTransit *bool + // Whether this is an Arm-based instance. + IsGraviton *bool +} + +// Configuration for flexible node types, allowing fallback to alternate node +// types during cluster launch and upscale.. +type NodeTypeFlexibility struct { + // A list of node type IDs to use as fallbacks when the primary node type is + // unavailable. + AlternateNodeTypeIds []string `fieldmask:"alternate_node_type_ids"` +} + +// Represents a pending enforcement on a cluster, which contains the changes to +// make to the cluster configuration when the cluster is next terminated or +// restarted.. +type PendingEnforcement struct { + // The new configuration to apply upon cluster termination or restart. + TargetSpec *EnforcePolicyComplianceForClusterResponse_ClusterSettings + // The time the pending enforcement was initiated. + InitiateTime *types.Time + // Whether the pending enforcement will be applied. A pending enforcement begins + // in `ACTIVE` state. If the enforcement fails to apply too many times, the + // state transitions to `INACTIVE`. Afterwards, the enforcement must be + // re-scheduled to become `ACTIVE` again. + EnforcementStatus PendingEnforcement_EnforcementStatus + // A list of changes that will be made to the cluster configuration when the + // pending enforcement is applied. + TargetChanges []EnforcePolicyComplianceForClusterResponse_ClusterSettingsChange + // The user who initiated the pending enforcement. + InitiatorUser *string +} + +type PermanentDeleteClusterRequest struct { + // The cluster to be deleted. + ClusterId *string +} + +type PermanentDeleteClusterResponse struct { +} + +type PinClusterRequest struct { + ClusterId *string +} + +type PinClusterResponse struct { +} + +type ResizeCause struct { +} + +type ResizeClusterRequest struct { + // The cluster to be resized. + ClusterId *string + Size isResizeClusterRequest_Size +} + +type isResizeClusterRequest_Size interface { + isResizeClusterRequest_Size() +} + +// ResizeClusterRequest_Size_NumWorkers selects NumWorkers for ResizeClusterRequest.Size. +// Number of worker nodes that this cluster should have. A cluster has one Spark +// Driver and `num_workers` Executors for a total of `num_workers` + 1 Spark +// nodes. +// +// Note: When reading the properties of a cluster, this field reflects the +// desired number of workers rather than the actual current number of workers. +// For instance, if a cluster is resized from 5 to 10 workers, this field will +// immediately be updated to reflect the target size of 10 workers, whereas the +// workers listed in `spark_info` will gradually increase from 5 to 10 as the +// new nodes are provisioned. +type ResizeClusterRequest_Size_NumWorkers struct { + NumWorkers int +} + +func (*ResizeClusterRequest_Size_NumWorkers) isResizeClusterRequest_Size() {} + +// ResizeClusterRequest_Size_Autoscale selects Autoscale for ResizeClusterRequest.Size. +// Parameters needed in order to automatically scale clusters up and down based +// on load. Note: autoscaling works best with DB runtime versions 3.0 or later. +type ResizeClusterRequest_Size_Autoscale struct { + Autoscale AutoScale +} + +func (*ResizeClusterRequest_Size_Autoscale) isResizeClusterRequest_Size() {} + +type ResizeClusterResponse struct { +} + +type RestartClusterRequest struct { + // The cluster to be started. + ClusterId *string + RestartUser *string +} + +type RestartClusterResponse struct { +} + +// Request to roll back cluster.. +type RollbackClusterRequest struct { + // The fully qualified resource name of the cluster revision. Format: + // clusters/{cluster_id}/revisions/{revision_id}. + Name *string +} + +// A storage location in Amazon S3. +type S3StorageInfo struct { + // S3 destination, e.g. `s3://my-bucket/some-prefix` Note that logs will be + // delivered using cluster iam role, please make sure you set cluster iam role + // and the role has write access to the destination. Please also note that you + // cannot use AWS keys to deliver logs. + Destination *string `fieldmask:"destination"` + // S3 region, e.g. `us-west-2`. Either region or endpoint needs to be set. If + // both are set, endpoint will be used. + Region *string `fieldmask:"region"` + // S3 endpoint, e.g. `https://s3-us-west-2.amazonaws.com`. Either region or + // endpoint needs to be set. If both are set, endpoint will be used. + Endpoint *string `fieldmask:"endpoint"` + // (Optional) Flag to enable server side encryption, `false` by default. + EnableEncryption *bool `fieldmask:"enable_encryption"` + // (Optional) The encryption type, it could be `sse-s3` or `sse-kms`. It will be + // used only when encryption is enabled and the default type is `sse-s3`. + EncryptionType *string `fieldmask:"encryption_type"` + // (Optional) Kms key which will be used if encryption is enabled and encryption + // type is set to `sse-kms`. + KmsKey *string `fieldmask:"kms_key"` + // (Optional) Set canned access control list for the logs, e.g. + // `bucket-owner-full-control`. If `canned_cal` is set, please make sure the + // cluster iam role has `s3:PutObjectAcl` permission on the destination bucket + // and prefix. The full list of possible canned acl can be found at + // http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl. + // Please also note that by default only the object owner gets full controls. If + // you are using cross account role for writing data, you may want to set + // `bucket-owner-full-control` to make bucket owner able to read the logs. + CannedAcl *string `fieldmask:"canned_acl"` +} + +// Provides information about Spark running inside a cluster. This is used in +// both the [[ClusterInfo]] for Cluster APIs and persisted cluster proto.. +type SparkInfo struct { +} + +// Describes a specific Spark driver or executor.. +type SparkInfo_SparkNode struct { + // Private IP address (typically a 10.x.x.x address) of the Spark node. Note + // that this is different from the private IP address of the host instance. + PrivateIp *string + // Public DNS address of this node. This address can be used to access the Spark + // JDBC server on the driver node. To communicate with the JDBC server, traffic + // must be manually authorized by adding security group rules to the + // "worker-unmanaged" security group via the AWS console. + PublicDns *string + // Globally unique identifier for this node. + NodeId *string + // Globally unique identifier for the host instance from the cloud provider. + InstanceId *string + // The timestamp (in millisecond) when the Spark node is launched. + StartTimestamp *int64 + // Attributes specific to AWS for a Spark node. + NodeAwsAttributes *SparkInfo_SparkNode_SparkNodeAwsAttributes + // The private IP address of the host instance. + HostPrivateIp *string +} + +// Attributes specific to AWS for a Spark node.. +type SparkInfo_SparkNode_SparkNodeAwsAttributes struct { + // Whether this node is on an Amazon spot instance. + IsSpot *bool +} + +type SparkVersion struct { + // Spark version key, for example "2.1.x-scala2.11". This is the value which + // should be provided as the "spark_version" when creating a new cluster. Note + // that the exact Spark version may change over time for a "wildcard" version + // (i.e., "2.1.x-scala2.11" is a "wildcard" version) with minor bug fixes. + Key *string + // A descriptive name for this Spark version, for example "Spark 2.1". + Name *string +} + +type StartClusterRequest struct { + // The cluster to be started. + ClusterId *string +} + +type StartClusterResponse struct { +} + +type TerminationReason struct { + // status code indicating why the cluster was terminated + Code TerminationCode + // type of the termination + Type TerminationType + // list of parameters that provide additional information about why the cluster + // was terminated + Parameters map[string]string +} + +type UnpinClusterRequest struct { + ClusterId *string +} + +type UnpinClusterResponse struct { +} + +type UpdateClusterRequest struct { + // ID of the cluster. + ClusterId *string + // The cluster to be updated. + Cluster *UpdateClusterRequest_UpdateClusterResource + // Used to specify which cluster attributes and size fields to update. See + // https://google.aip.dev/161 for more details. + UpdateMask *types.FieldMask[UpdateClusterRequest_UpdateClusterResource] +} + +type UpdateClusterRequest_UpdateClusterResource struct { + Size isUpdateClusterRequest_UpdateClusterResource_Size + // Cluster name requested by the user. This doesn't have to be unique. If not + // specified at creation, the cluster name will be an empty string. For job + // clusters, the cluster name is automatically set based on the job and job run + // IDs. + ClusterName *string `fieldmask:"cluster_name"` + // The Spark version of the cluster, e.g. `3.3.x-scala2.11`. A list of available + // Spark versions can be retrieved by using the [clusters/sparkVersions] API + // call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + SparkVersion *string `fieldmask:"spark_version"` + // An object containing a set of optional, user-specified Spark configuration + // key-value pairs. Users can also pass in a string of extra JVM options to the + // driver and the executors via `spark.driver.extraJavaOptions` and + // `spark.executor.extraJavaOptions` respectively. + SparkConf map[string]string `fieldmask:"spark_conf"` + // Attributes related to clusters running on Amazon Web Services. If not + // specified at cluster creation, a set of default values will be used. + AwsAttributes *AwsAttributes `fieldmask:"aws_attributes"` + // Attributes related to clusters running on Microsoft Azure. If not specified + // at cluster creation, a set of default values will be used. + AzureAttributes *AzureAttributes `fieldmask:"azure_attributes"` + // Attributes related to clusters running on Google Cloud Platform. If not + // specified at cluster creation, a set of default values will be used. + GcpAttributes *GcpAttributes `fieldmask:"gcp_attributes"` + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string `fieldmask:"node_type_id"` + // The node type of the Spark driver. Note that this field is optional; if + // unset, the driver node type will be set as the same value as `node_type_id` + // defined above. + // + // This field, along with node_type_id, should not be set if + // virtual_cluster_size is set. If both driver_node_type_id, node_type_id, and + // virtual_cluster_size are specified, driver_node_type_id and node_type_id take + // precedence. + DriverNodeTypeId *string `fieldmask:"driver_node_type_id"` + // Flexible node type configuration for worker nodes. + WorkerNodeTypeFlexibility *NodeTypeFlexibility `fieldmask:"worker_node_type_flexibility"` + // Flexible node type configuration for the driver node. + DriverNodeTypeFlexibility *NodeTypeFlexibility `fieldmask:"driver_node_type_flexibility"` + // SSH public key contents that will be added to each Spark node in this + // cluster. The corresponding private keys can be used to login with the user + // name `ubuntu` on port `2200`. Up to 10 keys can be specified. + SshPublicKeys []string `fieldmask:"ssh_public_keys"` + // Additional tags for cluster resources. will tag all cluster + // resources (e.g., AWS instances and EBS volumes) with these tags in addition + // to `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + // + // - Clusters can only reuse cloud resources if the resources' tags are a subset + // of the cluster tags + CustomTags map[string]string `fieldmask:"custom_tags"` + // The configuration for delivering spark logs to a long-term storage + // destination. Three kinds of destinations (DBFS, S3 and Unity Catalog volumes) + // are supported. Only one destination can be specified for one cluster. If the + // conf is given, the logs will be delivered to the destination every `5 mins`. + // The destination of driver logs is `$destination/$clusterId/driver`, while the + // destination of executor logs is `$destination/$clusterId/executor`. + ClusterLogConf *ClusterLogConf `fieldmask:"cluster_log_conf"` + // An object containing a set of optional, user-specified environment variable + // key-value pairs. Please note that key-value pair of the form (X,Y) will be + // exported as is (i.e., `export X='Y'`) while launching the driver and workers. + // + // In order to specify an additional set of `SPARK_DAEMON_JAVA_OPTS`, we + // recommend appending them to `$SPARK_DAEMON_JAVA_OPTS` as shown in the example + // below. This ensures that all default databricks managed environmental + // variables are included as well. + // + // Example Spark environment variables: `{"SPARK_WORKER_MEMORY": "28000m", + // "SPARK_LOCAL_DIRS": "/local_disk0"}` or `{"SPARK_DAEMON_JAVA_OPTS": + // "$SPARK_DAEMON_JAVA_OPTS -Dspark.shuffle.service.enabled=true"}` + SparkEnvVars map[string]string `fieldmask:"spark_env_vars"` + // Automatically terminates the cluster after it is inactive for this time in + // minutes. If not set, this cluster will not be automatically terminated. If + // specified, the threshold must be between 10 and 10000 minutes. Users can also + // set this value to 0 to explicitly disable automatic termination. + AutoterminationMinutes *int `fieldmask:"autotermination_minutes"` + // Autoscaling Local Storage: when enabled, this cluster will dynamically + // acquire additional disk space when its Spark workers are running low on disk + // space. + EnableElasticDisk *bool `fieldmask:"enable_elastic_disk"` + // The configuration for storing init scripts. Any number of destinations can be + // specified. The scripts are executed sequentially in the order provided. If + // `cluster_log_conf` is specified, init script logs are sent to + // `//init_scripts`. + InitScripts []InitScriptInfo `fieldmask:"init_scripts"` + // Custom docker image BYOC + DockerImage *DockerImage `fieldmask:"docker_image"` + // The optional ID of the instance pool to which the cluster belongs. + InstancePoolId *string `fieldmask:"instance_pool_id"` + // Single user name if data_security_mode is `SINGLE_USER` + SingleUserName *string `fieldmask:"single_user_name"` + // The ID of the cluster policy used to create the cluster if applicable. + PolicyId *string `fieldmask:"policy_id"` + // Whether to enable LUKS on cluster VMs' local disks + EnableLocalDiskEncryption *bool `fieldmask:"enable_local_disk_encryption"` + // The optional ID of the instance pool for the driver of the cluster belongs. + // The pool cluster uses the instance pool with id (instance_pool_id) if the + // driver pool is not assigned. + DriverInstancePoolId *string `fieldmask:"driver_instance_pool_id"` + WorkloadType *WorkloadType `fieldmask:"workload_type"` + DataSecurityMode DataSecurityMode `fieldmask:"data_security_mode"` + // Determines the cluster's runtime engine, either standard or Photon. + // + // This field is not compatible with legacy `spark_version` values that contain + // `-photon-`. Remove `-photon-` from the `spark_version` and set + // `runtime_engine` to `PHOTON`. + // + // If left unspecified, the runtime engine defaults to standard unless the + // spark_version contains -photon-, in which case Photon will be used. + RuntimeEngine RuntimeEngine `fieldmask:"runtime_engine"` + Kind ComputeKind `fieldmask:"kind"` + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // `effective_spark_version` is determined by `spark_version` (DBR release), + // this field `use_ml_runtime`, and whether `node_type_id` is gpu node or not. + UseMlRuntime *bool `fieldmask:"use_ml_runtime"` + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // When set to true, will automatically set single node related + // `custom_tags`, `spark_conf`, and `num_workers` + IsSingleNode *bool `fieldmask:"is_single_node"` + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED disks. + RemoteDiskThroughput *int `fieldmask:"remote_disk_throughput"` + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED disks. + TotalInitialRemoteDiskSize *int `fieldmask:"total_initial_remote_disk_size"` + // Controls dependency configuration for the cluster. + DependencyMode DependencyMode `fieldmask:"dependency_mode"` + _ [0]updateClusterRequest_UpdateClusterResourceSizeFieldMaskMetadata `fieldmask_oneof:"Size"` +} + +type isUpdateClusterRequest_UpdateClusterResource_Size interface { + isUpdateClusterRequest_UpdateClusterResource_Size() +} + +// UpdateClusterRequest_UpdateClusterResource_Size_NumWorkers selects NumWorkers for UpdateClusterRequest_UpdateClusterResource.Size. +// Number of worker nodes that this cluster should have. A cluster has one Spark +// Driver and `num_workers` Executors for a total of `num_workers` + 1 Spark +// nodes. +// +// Note: When reading the properties of a cluster, this field reflects the +// desired number of workers rather than the actual current number of workers. +// For instance, if a cluster is resized from 5 to 10 workers, this field will +// immediately be updated to reflect the target size of 10 workers, whereas the +// workers listed in `spark_info` will gradually increase from 5 to 10 as the +// new nodes are provisioned. +type UpdateClusterRequest_UpdateClusterResource_Size_NumWorkers struct { + NumWorkers int `fieldmask:"num_workers"` +} + +func (*UpdateClusterRequest_UpdateClusterResource_Size_NumWorkers) isUpdateClusterRequest_UpdateClusterResource_Size() { +} + +// UpdateClusterRequest_UpdateClusterResource_Size_Autoscale selects Autoscale for UpdateClusterRequest_UpdateClusterResource.Size. +// Parameters needed in order to automatically scale clusters up and down based +// on load. Note: autoscaling works best with DB runtime versions 3.0 or later. +type UpdateClusterRequest_UpdateClusterResource_Size_Autoscale struct { + Autoscale AutoScale `fieldmask:"autoscale"` +} + +func (*UpdateClusterRequest_UpdateClusterResource_Size_Autoscale) isUpdateClusterRequest_UpdateClusterResource_Size() { +} + +type updateClusterRequest_UpdateClusterResourceSizeFieldMaskMetadata struct { + *UpdateClusterRequest_UpdateClusterResource_Size_NumWorkers + *UpdateClusterRequest_UpdateClusterResource_Size_Autoscale +} + +type UpdateClusterResponse struct { +} + +// A storage location back by UC Volumes.. +type VolumesStorageInfo struct { + // UC Volumes destination, e.g. + // `/Volumes/catalog/schema/vol1/init-scripts/setup-datadog.sh` or + // `dbfs:/Volumes/catalog/schema/vol1/init-scripts/setup-datadog.sh` + Destination *string `fieldmask:"destination"` +} + +// Cluster Attributes showing for clusters workload types.. +type WorkloadType struct { + // defined what type of clients can use the cluster. E.g. Notebooks, Jobs + Clients *WorkloadType_ClientsTypes `fieldmask:"clients"` +} + +type WorkloadType_ClientsTypes struct { + // With notebooks set, this cluster can be used for notebooks + Notebooks *bool `fieldmask:"notebooks"` + // With jobs set, the cluster can be used for jobs + Jobs *bool `fieldmask:"jobs"` +} + +// A storage location in Workspace Filesystem (WSFS). +type WorkspaceStorageInfo struct { + // wsfs destination, e.g. `workspace:/cluster-init-scripts/setup-datadog.sh` + Destination *string +} diff --git a/clusters/v2/wire.go b/clusters/v2/wire.go new file mode 100755 index 0000000..488f309 --- /dev/null +++ b/clusters/v2/wire.go @@ -0,0 +1,2880 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package clusters + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type adlsgen2InfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func adlsgen2InfoToWire(v *Adlsgen2Info) (*adlsgen2InfoWire, error) { + if v == nil { + return nil, nil + } + return &adlsgen2InfoWire{ + Destination: v.Destination, + }, nil +} + +func adlsgen2InfoFromWire(w *adlsgen2InfoWire) (*Adlsgen2Info, error) { + if w == nil { + return nil, nil + } + return &Adlsgen2Info{ + Destination: w.Destination, + }, nil +} + +type autoScaleWire struct { + MinWorkers *int `json:"min_workers,omitempty"` + MaxWorkers *int `json:"max_workers,omitempty"` +} + +func autoScaleToWire(v *AutoScale) (*autoScaleWire, error) { + if v == nil { + return nil, nil + } + return &autoScaleWire{ + MinWorkers: v.MinWorkers, + MaxWorkers: v.MaxWorkers, + }, nil +} + +func autoScaleFromWire(w *autoScaleWire) (*AutoScale, error) { + if w == nil { + return nil, nil + } + return &AutoScale{ + MinWorkers: w.MinWorkers, + MaxWorkers: w.MaxWorkers, + }, nil +} + +type awsAttributesWire struct { + FirstOnDemand *int `json:"first_on_demand,omitempty"` + Availability AwsAvailability `json:"availability,omitempty"` + ZoneId *string `json:"zone_id,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + SpotBidPricePercent *int `json:"spot_bid_price_percent,omitempty"` + EbsVolumeType EbsVolumeType `json:"ebs_volume_type,omitempty"` + EbsVolumeCount *int `json:"ebs_volume_count,omitempty"` + EbsVolumeSize *int `json:"ebs_volume_size,omitempty"` + EbsVolumeIops *int `json:"ebs_volume_iops,omitempty"` + EbsVolumeThroughput *int `json:"ebs_volume_throughput,omitempty"` +} + +func awsAttributesToWire(v *AwsAttributes) (*awsAttributesWire, error) { + if v == nil { + return nil, nil + } + return &awsAttributesWire{ + FirstOnDemand: v.FirstOnDemand, + Availability: v.Availability, + ZoneId: v.ZoneId, + InstanceProfileArn: v.InstanceProfileArn, + SpotBidPricePercent: v.SpotBidPricePercent, + EbsVolumeType: v.EbsVolumeType, + EbsVolumeCount: v.EbsVolumeCount, + EbsVolumeSize: v.EbsVolumeSize, + EbsVolumeIops: v.EbsVolumeIops, + EbsVolumeThroughput: v.EbsVolumeThroughput, + }, nil +} + +func awsAttributesFromWire(w *awsAttributesWire) (*AwsAttributes, error) { + if w == nil { + return nil, nil + } + return &AwsAttributes{ + FirstOnDemand: w.FirstOnDemand, + Availability: w.Availability, + ZoneId: w.ZoneId, + InstanceProfileArn: w.InstanceProfileArn, + SpotBidPricePercent: w.SpotBidPricePercent, + EbsVolumeType: w.EbsVolumeType, + EbsVolumeCount: w.EbsVolumeCount, + EbsVolumeSize: w.EbsVolumeSize, + EbsVolumeIops: w.EbsVolumeIops, + EbsVolumeThroughput: w.EbsVolumeThroughput, + }, nil +} + +type azureAttributesWire struct { + LogAnalyticsInfo *logAnalyticsInfoWire `json:"log_analytics_info,omitempty"` + FirstOnDemand *int `json:"first_on_demand,omitempty"` + Availability AzureAvailability `json:"availability,omitempty"` + SpotBidMaxPrice *float64 `json:"spot_bid_max_price,omitempty"` + CapacityReservationGroup *string `json:"capacity_reservation_group,omitempty"` +} + +func azureAttributesToWire(v *AzureAttributes) (*azureAttributesWire, error) { + if v == nil { + return nil, nil + } + logAnalyticsInfoWireValue, err := logAnalyticsInfoToWire(v.LogAnalyticsInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AzureAttributes.LogAnalyticsInfo", err) + } + return &azureAttributesWire{ + LogAnalyticsInfo: logAnalyticsInfoWireValue, + FirstOnDemand: v.FirstOnDemand, + Availability: v.Availability, + SpotBidMaxPrice: v.SpotBidMaxPrice, + CapacityReservationGroup: v.CapacityReservationGroup, + }, nil +} + +func azureAttributesFromWire(w *azureAttributesWire) (*AzureAttributes, error) { + if w == nil { + return nil, nil + } + logAnalyticsInfoPublicValue, err := logAnalyticsInfoFromWire(w.LogAnalyticsInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AzureAttributes.LogAnalyticsInfo", err) + } + return &AzureAttributes{ + LogAnalyticsInfo: logAnalyticsInfoPublicValue, + FirstOnDemand: w.FirstOnDemand, + Availability: w.Availability, + SpotBidMaxPrice: w.SpotBidMaxPrice, + CapacityReservationGroup: w.CapacityReservationGroup, + }, nil +} + +type cancelPendingClusterEnforcementRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + AllowMissing *bool `json:"allow_missing,omitempty"` +} + +func cancelPendingClusterEnforcementRequestToWire(v *CancelPendingClusterEnforcementRequest) (*cancelPendingClusterEnforcementRequestWire, error) { + if v == nil { + return nil, nil + } + return &cancelPendingClusterEnforcementRequestWire{ + ClusterId: v.ClusterId, + AllowMissing: v.AllowMissing, + }, nil +} + +type changeClusterOwnerRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + OwnerUsername *string `json:"owner_username,omitempty"` +} + +func changeClusterOwnerRequestToWire(v *ChangeClusterOwnerRequest) (*changeClusterOwnerRequestWire, error) { + if v == nil { + return nil, nil + } + return &changeClusterOwnerRequestWire{ + ClusterId: v.ClusterId, + OwnerUsername: v.OwnerUsername, + }, nil +} + +type cloneClusterWire struct { + SourceClusterId *string `json:"source_cluster_id,omitempty"` +} + +func cloneClusterToWire(v *CloneCluster) (*cloneClusterWire, error) { + if v == nil { + return nil, nil + } + return &cloneClusterWire{ + SourceClusterId: v.SourceClusterId, + }, nil +} + +type cloudProviderNodeInfoWire struct { + Status []CloudProviderNodeStatus `json:"status,omitempty"` +} + +func cloudProviderNodeInfoFromWire(w *cloudProviderNodeInfoWire) (*CloudProviderNodeInfo, error) { + if w == nil { + return nil, nil + } + return &CloudProviderNodeInfo{ + Status: w.Status, + }, nil +} + +type clusterAttributesWire struct { + ClusterName *string `json:"cluster_name,omitempty"` + SparkVersion *string `json:"spark_version,omitempty"` + SparkConf map[string]string `json:"spark_conf,omitempty"` + AwsAttributes *awsAttributesWire `json:"aws_attributes,omitempty"` + AzureAttributes *azureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *gcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + DriverNodeTypeId *string `json:"driver_node_type_id,omitempty"` + WorkerNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"worker_node_type_flexibility,omitempty"` + DriverNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"driver_node_type_flexibility,omitempty"` + SshPublicKeys []string `json:"ssh_public_keys,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + ClusterLogConf *clusterLogConfWire `json:"cluster_log_conf,omitempty"` + SparkEnvVars map[string]string `json:"spark_env_vars,omitempty"` + AutoterminationMinutes *int `json:"autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + InitScripts []initScriptInfoWire `json:"init_scripts,omitempty"` + DockerImage *dockerImageWire `json:"docker_image,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + SingleUserName *string `json:"single_user_name,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + EnableLocalDiskEncryption *bool `json:"enable_local_disk_encryption,omitempty"` + DriverInstancePoolId *string `json:"driver_instance_pool_id,omitempty"` + WorkloadType *workloadTypeWire `json:"workload_type,omitempty"` + DataSecurityMode DataSecurityMode `json:"data_security_mode,omitempty"` + RuntimeEngine RuntimeEngine `json:"runtime_engine,omitempty"` + Kind ComputeKind `json:"kind,omitempty"` + UseMlRuntime *bool `json:"use_ml_runtime,omitempty"` + IsSingleNode *bool `json:"is_single_node,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` + DependencyMode DependencyMode `json:"dependency_mode,omitempty"` +} + +func clusterAttributesFromWire(w *clusterAttributesWire) (*ClusterAttributes, error) { + if w == nil { + return nil, nil + } + awsAttributesPublicValue, err := awsAttributesFromWire(w.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAttributes.AwsAttributes", err) + } + azureAttributesPublicValue, err := azureAttributesFromWire(w.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAttributes.AzureAttributes", err) + } + gcpAttributesPublicValue, err := gcpAttributesFromWire(w.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAttributes.GcpAttributes", err) + } + workerNodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.WorkerNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAttributes.WorkerNodeTypeFlexibility", err) + } + driverNodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.DriverNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAttributes.DriverNodeTypeFlexibility", err) + } + clusterLogConfPublicValue, err := clusterLogConfFromWire(w.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAttributes.ClusterLogConf", err) + } + initScriptsPublicValue, err := convertSlice(w.InitScripts, initScriptInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAttributes.InitScripts", err) + } + dockerImagePublicValue, err := dockerImageFromWire(w.DockerImage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAttributes.DockerImage", err) + } + workloadTypePublicValue, err := workloadTypeFromWire(w.WorkloadType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAttributes.WorkloadType", err) + } + return &ClusterAttributes{ + ClusterName: w.ClusterName, + SparkVersion: w.SparkVersion, + SparkConf: w.SparkConf, + AwsAttributes: awsAttributesPublicValue, + AzureAttributes: azureAttributesPublicValue, + GcpAttributes: gcpAttributesPublicValue, + NodeTypeId: w.NodeTypeId, + DriverNodeTypeId: w.DriverNodeTypeId, + WorkerNodeTypeFlexibility: workerNodeTypeFlexibilityPublicValue, + DriverNodeTypeFlexibility: driverNodeTypeFlexibilityPublicValue, + SshPublicKeys: w.SshPublicKeys, + CustomTags: w.CustomTags, + ClusterLogConf: clusterLogConfPublicValue, + SparkEnvVars: w.SparkEnvVars, + AutoterminationMinutes: w.AutoterminationMinutes, + EnableElasticDisk: w.EnableElasticDisk, + InitScripts: initScriptsPublicValue, + DockerImage: dockerImagePublicValue, + InstancePoolId: w.InstancePoolId, + SingleUserName: w.SingleUserName, + PolicyId: w.PolicyId, + EnableLocalDiskEncryption: w.EnableLocalDiskEncryption, + DriverInstancePoolId: w.DriverInstancePoolId, + WorkloadType: workloadTypePublicValue, + DataSecurityMode: w.DataSecurityMode, + RuntimeEngine: w.RuntimeEngine, + Kind: w.Kind, + UseMlRuntime: w.UseMlRuntime, + IsSingleNode: w.IsSingleNode, + RemoteDiskThroughput: w.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: w.TotalInitialRemoteDiskSize, + DependencyMode: w.DependencyMode, + }, nil +} + +type clusterComplianceWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + IsCompliant *bool `json:"is_compliant,omitempty"` + Violations map[string]string `json:"violations,omitempty"` + PendingEnforcement *pendingEnforcementWire `json:"pending_enforcement,omitempty"` +} + +func clusterComplianceFromWire(w *clusterComplianceWire) (*ClusterCompliance, error) { + if w == nil { + return nil, nil + } + pendingEnforcementPublicValue, err := pendingEnforcementFromWire(w.PendingEnforcement) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterCompliance.PendingEnforcement", err) + } + return &ClusterCompliance{ + ClusterId: w.ClusterId, + IsCompliant: w.IsCompliant, + Violations: w.Violations, + PendingEnforcement: pendingEnforcementPublicValue, + }, nil +} + +type clusterEventWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + Timestamp *int64 `json:"timestamp,omitempty"` + Type ClusterEventType_ClusterEventType `json:"type,omitempty"` + Details *eventDetailsWire `json:"details,omitempty"` + DataPlaneEventDetails *dataPlaneEventDetailsWire `json:"data_plane_event_details,omitempty"` +} + +func clusterEventFromWire(w *clusterEventWire) (*ClusterEvent, error) { + if w == nil { + return nil, nil + } + detailsPublicValue, err := eventDetailsFromWire(w.Details) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterEvent.Details", err) + } + dataPlaneEventDetailsPublicValue, err := dataPlaneEventDetailsFromWire(w.DataPlaneEventDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterEvent.DataPlaneEventDetails", err) + } + return &ClusterEvent{ + ClusterId: w.ClusterId, + Timestamp: w.Timestamp, + Type: w.Type, + Details: detailsPublicValue, + DataPlaneEventDetails: dataPlaneEventDetailsPublicValue, + }, nil +} + +type clusterInfoWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + CreatorUserName *string `json:"creator_user_name,omitempty"` + State ClusterState_ClusterState `json:"state,omitempty"` + StateMessage *string `json:"state_message,omitempty"` + ClusterMemoryMb *int64 `json:"cluster_memory_mb,omitempty"` + ClusterCores *float32 `json:"cluster_cores,omitempty"` + DefaultTags map[string]string `json:"default_tags,omitempty"` + ClusterLogStatus *logSyncStatusWire `json:"cluster_log_status,omitempty"` + TerminationReason *terminationReasonWire `json:"termination_reason,omitempty"` + Spec *clusterInfo_ComputeSpecWire `json:"spec,omitempty"` + Driver *sparkInfo_SparkNodeWire `json:"driver,omitempty"` + Executors []sparkInfo_SparkNodeWire `json:"executors,omitempty"` + SparkContextId *int64 `json:"spark_context_id,omitempty"` + JdbcPort *int `json:"jdbc_port,omitempty"` + ClusterName *string `json:"cluster_name,omitempty"` + SparkVersion *string `json:"spark_version,omitempty"` + SparkConf map[string]string `json:"spark_conf,omitempty"` + AwsAttributes *awsAttributesWire `json:"aws_attributes,omitempty"` + AzureAttributes *azureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *gcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + DriverNodeTypeId *string `json:"driver_node_type_id,omitempty"` + WorkerNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"worker_node_type_flexibility,omitempty"` + DriverNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"driver_node_type_flexibility,omitempty"` + SshPublicKeys []string `json:"ssh_public_keys,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + ClusterLogConf *clusterLogConfWire `json:"cluster_log_conf,omitempty"` + SparkEnvVars map[string]string `json:"spark_env_vars,omitempty"` + AutoterminationMinutes *int `json:"autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + InitScripts []initScriptInfoWire `json:"init_scripts,omitempty"` + DockerImage *dockerImageWire `json:"docker_image,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + SingleUserName *string `json:"single_user_name,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + EnableLocalDiskEncryption *bool `json:"enable_local_disk_encryption,omitempty"` + DriverInstancePoolId *string `json:"driver_instance_pool_id,omitempty"` + WorkloadType *workloadTypeWire `json:"workload_type,omitempty"` + DataSecurityMode DataSecurityMode `json:"data_security_mode,omitempty"` + RuntimeEngine RuntimeEngine `json:"runtime_engine,omitempty"` + Kind ComputeKind `json:"kind,omitempty"` + UseMlRuntime *bool `json:"use_ml_runtime,omitempty"` + IsSingleNode *bool `json:"is_single_node,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` + DependencyMode DependencyMode `json:"dependency_mode,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + TerminatedTime *int64 `json:"terminated_time,omitempty"` + LastStateLossTime *int64 `json:"last_state_loss_time,omitempty"` + LastRestartedTime *int64 `json:"last_restarted_time,omitempty"` + NumWorkers *int `json:"num_workers,omitempty"` + Autoscale *autoScaleWire `json:"autoscale,omitempty"` +} + +func clusterInfoFromWire(w *clusterInfoWire) (*ClusterInfo, error) { + if w == nil { + return nil, nil + } + sizeMembers := 0 + if w.NumWorkers != nil { + sizeMembers++ + } + if w.Autoscale != nil { + sizeMembers++ + } + if sizeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ClusterInfo.Size") + } + clusterLogStatusPublicValue, err := logSyncStatusFromWire(w.ClusterLogStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.ClusterLogStatus", err) + } + terminationReasonPublicValue, err := terminationReasonFromWire(w.TerminationReason) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.TerminationReason", err) + } + specPublicValue, err := clusterInfo_ComputeSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.Spec", err) + } + driverPublicValue, err := sparkInfo_SparkNodeFromWire(w.Driver) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.Driver", err) + } + executorsPublicValue, err := convertSlice(w.Executors, sparkInfo_SparkNodeFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.Executors", err) + } + awsAttributesPublicValue, err := awsAttributesFromWire(w.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.AwsAttributes", err) + } + azureAttributesPublicValue, err := azureAttributesFromWire(w.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.AzureAttributes", err) + } + gcpAttributesPublicValue, err := gcpAttributesFromWire(w.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.GcpAttributes", err) + } + workerNodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.WorkerNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.WorkerNodeTypeFlexibility", err) + } + driverNodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.DriverNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.DriverNodeTypeFlexibility", err) + } + clusterLogConfPublicValue, err := clusterLogConfFromWire(w.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.ClusterLogConf", err) + } + initScriptsPublicValue, err := convertSlice(w.InitScripts, initScriptInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.InitScripts", err) + } + dockerImagePublicValue, err := dockerImageFromWire(w.DockerImage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.DockerImage", err) + } + workloadTypePublicValue, err := workloadTypeFromWire(w.WorkloadType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.WorkloadType", err) + } + var sizeSelection isClusterInfo_Size + switch { + case w.NumWorkers != nil: + sizeSelection = &ClusterInfo_Size_NumWorkers{NumWorkers: *w.NumWorkers} + case w.Autoscale != nil: + sizeAutoscaleConverted, err := autoScaleFromWire(w.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo.Size.Autoscale", err) + } + sizeSelection = &ClusterInfo_Size_Autoscale{Autoscale: *sizeAutoscaleConverted} + } + return &ClusterInfo{ + ClusterId: w.ClusterId, + CreatorUserName: w.CreatorUserName, + State: w.State, + StateMessage: w.StateMessage, + ClusterMemoryMb: w.ClusterMemoryMb, + ClusterCores: w.ClusterCores, + DefaultTags: w.DefaultTags, + ClusterLogStatus: clusterLogStatusPublicValue, + TerminationReason: terminationReasonPublicValue, + Spec: specPublicValue, + Driver: driverPublicValue, + Executors: executorsPublicValue, + SparkContextId: w.SparkContextId, + JdbcPort: w.JdbcPort, + ClusterName: w.ClusterName, + SparkVersion: w.SparkVersion, + SparkConf: w.SparkConf, + AwsAttributes: awsAttributesPublicValue, + AzureAttributes: azureAttributesPublicValue, + GcpAttributes: gcpAttributesPublicValue, + NodeTypeId: w.NodeTypeId, + DriverNodeTypeId: w.DriverNodeTypeId, + WorkerNodeTypeFlexibility: workerNodeTypeFlexibilityPublicValue, + DriverNodeTypeFlexibility: driverNodeTypeFlexibilityPublicValue, + SshPublicKeys: w.SshPublicKeys, + CustomTags: w.CustomTags, + ClusterLogConf: clusterLogConfPublicValue, + SparkEnvVars: w.SparkEnvVars, + AutoterminationMinutes: w.AutoterminationMinutes, + EnableElasticDisk: w.EnableElasticDisk, + InitScripts: initScriptsPublicValue, + DockerImage: dockerImagePublicValue, + InstancePoolId: w.InstancePoolId, + SingleUserName: w.SingleUserName, + PolicyId: w.PolicyId, + EnableLocalDiskEncryption: w.EnableLocalDiskEncryption, + DriverInstancePoolId: w.DriverInstancePoolId, + WorkloadType: workloadTypePublicValue, + DataSecurityMode: w.DataSecurityMode, + RuntimeEngine: w.RuntimeEngine, + Kind: w.Kind, + UseMlRuntime: w.UseMlRuntime, + IsSingleNode: w.IsSingleNode, + RemoteDiskThroughput: w.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: w.TotalInitialRemoteDiskSize, + DependencyMode: w.DependencyMode, + StartTime: w.StartTime, + TerminatedTime: w.TerminatedTime, + LastStateLossTime: w.LastStateLossTime, + LastRestartedTime: w.LastRestartedTime, + Size: sizeSelection, + }, nil +} + +type clusterInfo_ComputeSpecWire struct { + ApplyPolicyDefaultValues *bool `json:"apply_policy_default_values,omitempty"` + ClusterName *string `json:"cluster_name,omitempty"` + SparkVersion *string `json:"spark_version,omitempty"` + SparkConf map[string]string `json:"spark_conf,omitempty"` + AwsAttributes *awsAttributesWire `json:"aws_attributes,omitempty"` + AzureAttributes *azureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *gcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + DriverNodeTypeId *string `json:"driver_node_type_id,omitempty"` + WorkerNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"worker_node_type_flexibility,omitempty"` + DriverNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"driver_node_type_flexibility,omitempty"` + SshPublicKeys []string `json:"ssh_public_keys,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + ClusterLogConf *clusterLogConfWire `json:"cluster_log_conf,omitempty"` + SparkEnvVars map[string]string `json:"spark_env_vars,omitempty"` + AutoterminationMinutes *int `json:"autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + InitScripts []initScriptInfoWire `json:"init_scripts,omitempty"` + DockerImage *dockerImageWire `json:"docker_image,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + SingleUserName *string `json:"single_user_name,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + EnableLocalDiskEncryption *bool `json:"enable_local_disk_encryption,omitempty"` + DriverInstancePoolId *string `json:"driver_instance_pool_id,omitempty"` + WorkloadType *workloadTypeWire `json:"workload_type,omitempty"` + DataSecurityMode DataSecurityMode `json:"data_security_mode,omitempty"` + RuntimeEngine RuntimeEngine `json:"runtime_engine,omitempty"` + Kind ComputeKind `json:"kind,omitempty"` + UseMlRuntime *bool `json:"use_ml_runtime,omitempty"` + IsSingleNode *bool `json:"is_single_node,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` + DependencyMode DependencyMode `json:"dependency_mode,omitempty"` + NumWorkers *int `json:"num_workers,omitempty"` + Autoscale *autoScaleWire `json:"autoscale,omitempty"` +} + +func clusterInfo_ComputeSpecFromWire(w *clusterInfo_ComputeSpecWire) (*ClusterInfo_ComputeSpec, error) { + if w == nil { + return nil, nil + } + sizeMembers := 0 + if w.NumWorkers != nil { + sizeMembers++ + } + if w.Autoscale != nil { + sizeMembers++ + } + if sizeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ClusterInfo_ComputeSpec.Size") + } + awsAttributesPublicValue, err := awsAttributesFromWire(w.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo_ComputeSpec.AwsAttributes", err) + } + azureAttributesPublicValue, err := azureAttributesFromWire(w.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo_ComputeSpec.AzureAttributes", err) + } + gcpAttributesPublicValue, err := gcpAttributesFromWire(w.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo_ComputeSpec.GcpAttributes", err) + } + workerNodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.WorkerNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo_ComputeSpec.WorkerNodeTypeFlexibility", err) + } + driverNodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.DriverNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo_ComputeSpec.DriverNodeTypeFlexibility", err) + } + clusterLogConfPublicValue, err := clusterLogConfFromWire(w.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo_ComputeSpec.ClusterLogConf", err) + } + initScriptsPublicValue, err := convertSlice(w.InitScripts, initScriptInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo_ComputeSpec.InitScripts", err) + } + dockerImagePublicValue, err := dockerImageFromWire(w.DockerImage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo_ComputeSpec.DockerImage", err) + } + workloadTypePublicValue, err := workloadTypeFromWire(w.WorkloadType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo_ComputeSpec.WorkloadType", err) + } + var sizeSelection isClusterInfo_ComputeSpec_Size + switch { + case w.NumWorkers != nil: + sizeSelection = &ClusterInfo_ComputeSpec_Size_NumWorkers{NumWorkers: *w.NumWorkers} + case w.Autoscale != nil: + sizeAutoscaleConverted, err := autoScaleFromWire(w.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterInfo_ComputeSpec.Size.Autoscale", err) + } + sizeSelection = &ClusterInfo_ComputeSpec_Size_Autoscale{Autoscale: *sizeAutoscaleConverted} + } + return &ClusterInfo_ComputeSpec{ + ApplyPolicyDefaultValues: w.ApplyPolicyDefaultValues, + ClusterName: w.ClusterName, + SparkVersion: w.SparkVersion, + SparkConf: w.SparkConf, + AwsAttributes: awsAttributesPublicValue, + AzureAttributes: azureAttributesPublicValue, + GcpAttributes: gcpAttributesPublicValue, + NodeTypeId: w.NodeTypeId, + DriverNodeTypeId: w.DriverNodeTypeId, + WorkerNodeTypeFlexibility: workerNodeTypeFlexibilityPublicValue, + DriverNodeTypeFlexibility: driverNodeTypeFlexibilityPublicValue, + SshPublicKeys: w.SshPublicKeys, + CustomTags: w.CustomTags, + ClusterLogConf: clusterLogConfPublicValue, + SparkEnvVars: w.SparkEnvVars, + AutoterminationMinutes: w.AutoterminationMinutes, + EnableElasticDisk: w.EnableElasticDisk, + InitScripts: initScriptsPublicValue, + DockerImage: dockerImagePublicValue, + InstancePoolId: w.InstancePoolId, + SingleUserName: w.SingleUserName, + PolicyId: w.PolicyId, + EnableLocalDiskEncryption: w.EnableLocalDiskEncryption, + DriverInstancePoolId: w.DriverInstancePoolId, + WorkloadType: workloadTypePublicValue, + DataSecurityMode: w.DataSecurityMode, + RuntimeEngine: w.RuntimeEngine, + Kind: w.Kind, + UseMlRuntime: w.UseMlRuntime, + IsSingleNode: w.IsSingleNode, + RemoteDiskThroughput: w.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: w.TotalInitialRemoteDiskSize, + DependencyMode: w.DependencyMode, + Size: sizeSelection, + }, nil +} + +type clusterLogConfWire struct { + Dbfs *dbfsStorageInfoWire `json:"dbfs,omitempty"` + S3 *s3StorageInfoWire `json:"s3,omitempty"` + Volumes *volumesStorageInfoWire `json:"volumes,omitempty"` +} + +func clusterLogConfToWire(v *ClusterLogConf) (*clusterLogConfWire, error) { + if v == nil { + return nil, nil + } + var storageInfoDbfsWire *dbfsStorageInfoWire + var storageInfoS3Wire *s3StorageInfoWire + var storageInfoVolumesWire *volumesStorageInfoWire + switch value := v.StorageInfo.(type) { + case nil: + case *ClusterLogConf_StorageInfo_Dbfs: + if value != nil { + storageInfoDbfsConverted, err := dbfsStorageInfoToWire(&value.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.Dbfs", err) + } + storageInfoDbfsWire = storageInfoDbfsConverted + } + case *ClusterLogConf_StorageInfo_S3: + if value != nil { + storageInfoS3Converted, err := s3StorageInfoToWire(&value.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.S3", err) + } + storageInfoS3Wire = storageInfoS3Converted + } + case *ClusterLogConf_StorageInfo_Volumes: + if value != nil { + storageInfoVolumesConverted, err := volumesStorageInfoToWire(&value.Volumes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.Volumes", err) + } + storageInfoVolumesWire = storageInfoVolumesConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ClusterLogConf.StorageInfo", value) + } + return &clusterLogConfWire{ + Dbfs: storageInfoDbfsWire, + S3: storageInfoS3Wire, + Volumes: storageInfoVolumesWire, + }, nil +} + +func clusterLogConfFromWire(w *clusterLogConfWire) (*ClusterLogConf, error) { + if w == nil { + return nil, nil + } + storageInfoMembers := 0 + if w.Dbfs != nil { + storageInfoMembers++ + } + if w.S3 != nil { + storageInfoMembers++ + } + if w.Volumes != nil { + storageInfoMembers++ + } + if storageInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ClusterLogConf.StorageInfo") + } + var storageInfoSelection isClusterLogConf_StorageInfo + switch { + case w.Dbfs != nil: + storageInfoDbfsConverted, err := dbfsStorageInfoFromWire(w.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.Dbfs", err) + } + storageInfoSelection = &ClusterLogConf_StorageInfo_Dbfs{Dbfs: *storageInfoDbfsConverted} + case w.S3 != nil: + storageInfoS3Converted, err := s3StorageInfoFromWire(w.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.S3", err) + } + storageInfoSelection = &ClusterLogConf_StorageInfo_S3{S3: *storageInfoS3Converted} + case w.Volumes != nil: + storageInfoVolumesConverted, err := volumesStorageInfoFromWire(w.Volumes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.Volumes", err) + } + storageInfoSelection = &ClusterLogConf_StorageInfo_Volumes{Volumes: *storageInfoVolumesConverted} + } + return &ClusterLogConf{ + StorageInfo: storageInfoSelection, + }, nil +} + +type clusterRevisionWire struct { + RevisionId *string `json:"revision_id,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + Settings *clusterInfo_ComputeSpecWire `json:"settings,omitempty"` + EditReason ClusterEditReason `json:"edit_reason,omitempty"` + EditUser *string `json:"edit_user,omitempty"` + IsCurrent *bool `json:"is_current,omitempty"` +} + +func clusterRevisionFromWire(w *clusterRevisionWire) (*ClusterRevision, error) { + if w == nil { + return nil, nil + } + settingsPublicValue, err := clusterInfo_ComputeSpecFromWire(w.Settings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterRevision.Settings", err) + } + return &ClusterRevision{ + RevisionId: w.RevisionId, + CreateTime: w.CreateTime, + Settings: settingsPublicValue, + EditReason: w.EditReason, + EditUser: w.EditUser, + IsCurrent: w.IsCurrent, + }, nil +} + +type clusterSizeWire struct { + NumWorkers *int `json:"num_workers,omitempty"` + Autoscale *autoScaleWire `json:"autoscale,omitempty"` +} + +func clusterSizeFromWire(w *clusterSizeWire) (*ClusterSize, error) { + if w == nil { + return nil, nil + } + sizeMembers := 0 + if w.NumWorkers != nil { + sizeMembers++ + } + if w.Autoscale != nil { + sizeMembers++ + } + if sizeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ClusterSize.Size") + } + var sizeSelection isClusterSize_Size + switch { + case w.NumWorkers != nil: + sizeSelection = &ClusterSize_Size_NumWorkers{NumWorkers: *w.NumWorkers} + case w.Autoscale != nil: + sizeAutoscaleConverted, err := autoScaleFromWire(w.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSize.Size.Autoscale", err) + } + sizeSelection = &ClusterSize_Size_Autoscale{Autoscale: *sizeAutoscaleConverted} + } + return &ClusterSize{ + Size: sizeSelection, + }, nil +} + +type createClusterRequestWire struct { + ApplyPolicyDefaultValues *bool `json:"apply_policy_default_values,omitempty"` + CloneFrom *cloneClusterWire `json:"clone_from,omitempty"` + NumWorkers *int `json:"num_workers,omitempty"` + Autoscale *autoScaleWire `json:"autoscale,omitempty"` + ClusterName *string `json:"cluster_name,omitempty"` + SparkVersion *string `json:"spark_version,omitempty"` + SparkConf map[string]string `json:"spark_conf,omitempty"` + AwsAttributes *awsAttributesWire `json:"aws_attributes,omitempty"` + AzureAttributes *azureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *gcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + DriverNodeTypeId *string `json:"driver_node_type_id,omitempty"` + WorkerNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"worker_node_type_flexibility,omitempty"` + DriverNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"driver_node_type_flexibility,omitempty"` + SshPublicKeys []string `json:"ssh_public_keys,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + ClusterLogConf *clusterLogConfWire `json:"cluster_log_conf,omitempty"` + SparkEnvVars map[string]string `json:"spark_env_vars,omitempty"` + AutoterminationMinutes *int `json:"autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + InitScripts []initScriptInfoWire `json:"init_scripts,omitempty"` + DockerImage *dockerImageWire `json:"docker_image,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + SingleUserName *string `json:"single_user_name,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + EnableLocalDiskEncryption *bool `json:"enable_local_disk_encryption,omitempty"` + DriverInstancePoolId *string `json:"driver_instance_pool_id,omitempty"` + WorkloadType *workloadTypeWire `json:"workload_type,omitempty"` + DataSecurityMode DataSecurityMode `json:"data_security_mode,omitempty"` + RuntimeEngine RuntimeEngine `json:"runtime_engine,omitempty"` + Kind ComputeKind `json:"kind,omitempty"` + UseMlRuntime *bool `json:"use_ml_runtime,omitempty"` + IsSingleNode *bool `json:"is_single_node,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` + DependencyMode DependencyMode `json:"dependency_mode,omitempty"` +} + +func createClusterRequestToWire(v *CreateClusterRequest) (*createClusterRequestWire, error) { + if v == nil { + return nil, nil + } + cloneFromWireValue, err := cloneClusterToWire(v.CloneFrom) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.CloneFrom", err) + } + awsAttributesWireValue, err := awsAttributesToWire(v.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.AwsAttributes", err) + } + azureAttributesWireValue, err := azureAttributesToWire(v.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.AzureAttributes", err) + } + gcpAttributesWireValue, err := gcpAttributesToWire(v.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.GcpAttributes", err) + } + workerNodeTypeFlexibilityWireValue, err := nodeTypeFlexibilityToWire(v.WorkerNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.WorkerNodeTypeFlexibility", err) + } + driverNodeTypeFlexibilityWireValue, err := nodeTypeFlexibilityToWire(v.DriverNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.DriverNodeTypeFlexibility", err) + } + clusterLogConfWireValue, err := clusterLogConfToWire(v.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.ClusterLogConf", err) + } + initScriptsWireValue, err := convertSlice(v.InitScripts, initScriptInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.InitScripts", err) + } + dockerImageWireValue, err := dockerImageToWire(v.DockerImage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.DockerImage", err) + } + workloadTypeWireValue, err := workloadTypeToWire(v.WorkloadType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.WorkloadType", err) + } + var sizeNumWorkersWire *int + var sizeAutoscaleWire *autoScaleWire + switch value := v.Size.(type) { + case nil: + case *CreateClusterRequest_Size_NumWorkers: + if value != nil { + sizeNumWorkersWire = new(value.NumWorkers) + } + case *CreateClusterRequest_Size_Autoscale: + if value != nil { + sizeAutoscaleConverted, err := autoScaleToWire(&value.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateClusterRequest.Size.Autoscale", err) + } + sizeAutoscaleWire = sizeAutoscaleConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreateClusterRequest.Size", value) + } + return &createClusterRequestWire{ + ApplyPolicyDefaultValues: v.ApplyPolicyDefaultValues, + CloneFrom: cloneFromWireValue, + NumWorkers: sizeNumWorkersWire, + Autoscale: sizeAutoscaleWire, + ClusterName: v.ClusterName, + SparkVersion: v.SparkVersion, + SparkConf: v.SparkConf, + AwsAttributes: awsAttributesWireValue, + AzureAttributes: azureAttributesWireValue, + GcpAttributes: gcpAttributesWireValue, + NodeTypeId: v.NodeTypeId, + DriverNodeTypeId: v.DriverNodeTypeId, + WorkerNodeTypeFlexibility: workerNodeTypeFlexibilityWireValue, + DriverNodeTypeFlexibility: driverNodeTypeFlexibilityWireValue, + SshPublicKeys: v.SshPublicKeys, + CustomTags: v.CustomTags, + ClusterLogConf: clusterLogConfWireValue, + SparkEnvVars: v.SparkEnvVars, + AutoterminationMinutes: v.AutoterminationMinutes, + EnableElasticDisk: v.EnableElasticDisk, + InitScripts: initScriptsWireValue, + DockerImage: dockerImageWireValue, + InstancePoolId: v.InstancePoolId, + SingleUserName: v.SingleUserName, + PolicyId: v.PolicyId, + EnableLocalDiskEncryption: v.EnableLocalDiskEncryption, + DriverInstancePoolId: v.DriverInstancePoolId, + WorkloadType: workloadTypeWireValue, + DataSecurityMode: v.DataSecurityMode, + RuntimeEngine: v.RuntimeEngine, + Kind: v.Kind, + UseMlRuntime: v.UseMlRuntime, + IsSingleNode: v.IsSingleNode, + RemoteDiskThroughput: v.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: v.TotalInitialRemoteDiskSize, + DependencyMode: v.DependencyMode, + }, nil +} + +type createClusterResponseWire struct { + ClusterId *string `json:"cluster_id,omitempty"` +} + +func createClusterResponseFromWire(w *createClusterResponseWire) (*CreateClusterResponse, error) { + if w == nil { + return nil, nil + } + return &CreateClusterResponse{ + ClusterId: w.ClusterId, + }, nil +} + +type dataPlaneEventDetailsWire struct { + EventType DataPlaneClusterEventType `json:"event_type,omitempty"` + Timestamp *int64 `json:"timestamp,omitempty"` + HostId *string `json:"host_id,omitempty"` + ExecutorFailures *int `json:"executor_failures,omitempty"` +} + +func dataPlaneEventDetailsFromWire(w *dataPlaneEventDetailsWire) (*DataPlaneEventDetails, error) { + if w == nil { + return nil, nil + } + return &DataPlaneEventDetails{ + EventType: w.EventType, + Timestamp: w.Timestamp, + HostId: w.HostId, + ExecutorFailures: w.ExecutorFailures, + }, nil +} + +type dbfsStorageInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func dbfsStorageInfoToWire(v *DbfsStorageInfo) (*dbfsStorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &dbfsStorageInfoWire{ + Destination: v.Destination, + }, nil +} + +func dbfsStorageInfoFromWire(w *dbfsStorageInfoWire) (*DbfsStorageInfo, error) { + if w == nil { + return nil, nil + } + return &DbfsStorageInfo{ + Destination: w.Destination, + }, nil +} + +type deleteClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` +} + +func deleteClusterRequestToWire(v *DeleteClusterRequest) (*deleteClusterRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteClusterRequestWire{ + ClusterId: v.ClusterId, + }, nil +} + +type dockerBasicAuthWire struct { + Username *string `json:"username,omitempty"` + Password *string `json:"password,omitempty"` +} + +func dockerBasicAuthToWire(v *DockerBasicAuth) (*dockerBasicAuthWire, error) { + if v == nil { + return nil, nil + } + return &dockerBasicAuthWire{ + Username: v.Username, + Password: v.Password, + }, nil +} + +func dockerBasicAuthFromWire(w *dockerBasicAuthWire) (*DockerBasicAuth, error) { + if w == nil { + return nil, nil + } + return &DockerBasicAuth{ + Username: w.Username, + Password: w.Password, + }, nil +} + +type dockerImageWire struct { + Url *string `json:"url,omitempty"` + BasicAuth *dockerBasicAuthWire `json:"basic_auth,omitempty"` +} + +func dockerImageToWire(v *DockerImage) (*dockerImageWire, error) { + if v == nil { + return nil, nil + } + var credsOneofBasicAuthWire *dockerBasicAuthWire + switch value := v.CredsOneof.(type) { + case nil: + case *DockerImage_CredsOneof_BasicAuth: + if value != nil { + credsOneofBasicAuthConverted, err := dockerBasicAuthToWire(&value.BasicAuth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DockerImage.CredsOneof.BasicAuth", err) + } + credsOneofBasicAuthWire = credsOneofBasicAuthConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "DockerImage.CredsOneof", value) + } + return &dockerImageWire{ + Url: v.Url, + BasicAuth: credsOneofBasicAuthWire, + }, nil +} + +func dockerImageFromWire(w *dockerImageWire) (*DockerImage, error) { + if w == nil { + return nil, nil + } + credsOneofMembers := 0 + if w.BasicAuth != nil { + credsOneofMembers++ + } + if credsOneofMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "DockerImage.CredsOneof") + } + var credsOneofSelection isDockerImage_CredsOneof + switch { + case w.BasicAuth != nil: + credsOneofBasicAuthConverted, err := dockerBasicAuthFromWire(w.BasicAuth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DockerImage.CredsOneof.BasicAuth", err) + } + credsOneofSelection = &DockerImage_CredsOneof_BasicAuth{BasicAuth: *credsOneofBasicAuthConverted} + } + return &DockerImage{ + Url: w.Url, + CredsOneof: credsOneofSelection, + }, nil +} + +type editClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + ApplyPolicyDefaultValues *bool `json:"apply_policy_default_values,omitempty"` + NumWorkers *int `json:"num_workers,omitempty"` + Autoscale *autoScaleWire `json:"autoscale,omitempty"` + ClusterName *string `json:"cluster_name,omitempty"` + SparkVersion *string `json:"spark_version,omitempty"` + SparkConf map[string]string `json:"spark_conf,omitempty"` + AwsAttributes *awsAttributesWire `json:"aws_attributes,omitempty"` + AzureAttributes *azureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *gcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + DriverNodeTypeId *string `json:"driver_node_type_id,omitempty"` + WorkerNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"worker_node_type_flexibility,omitempty"` + DriverNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"driver_node_type_flexibility,omitempty"` + SshPublicKeys []string `json:"ssh_public_keys,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + ClusterLogConf *clusterLogConfWire `json:"cluster_log_conf,omitempty"` + SparkEnvVars map[string]string `json:"spark_env_vars,omitempty"` + AutoterminationMinutes *int `json:"autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + InitScripts []initScriptInfoWire `json:"init_scripts,omitempty"` + DockerImage *dockerImageWire `json:"docker_image,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + SingleUserName *string `json:"single_user_name,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + EnableLocalDiskEncryption *bool `json:"enable_local_disk_encryption,omitempty"` + DriverInstancePoolId *string `json:"driver_instance_pool_id,omitempty"` + WorkloadType *workloadTypeWire `json:"workload_type,omitempty"` + DataSecurityMode DataSecurityMode `json:"data_security_mode,omitempty"` + RuntimeEngine RuntimeEngine `json:"runtime_engine,omitempty"` + Kind ComputeKind `json:"kind,omitempty"` + UseMlRuntime *bool `json:"use_ml_runtime,omitempty"` + IsSingleNode *bool `json:"is_single_node,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` + DependencyMode DependencyMode `json:"dependency_mode,omitempty"` +} + +func editClusterRequestToWire(v *EditClusterRequest) (*editClusterRequestWire, error) { + if v == nil { + return nil, nil + } + awsAttributesWireValue, err := awsAttributesToWire(v.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditClusterRequest.AwsAttributes", err) + } + azureAttributesWireValue, err := azureAttributesToWire(v.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditClusterRequest.AzureAttributes", err) + } + gcpAttributesWireValue, err := gcpAttributesToWire(v.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditClusterRequest.GcpAttributes", err) + } + workerNodeTypeFlexibilityWireValue, err := nodeTypeFlexibilityToWire(v.WorkerNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditClusterRequest.WorkerNodeTypeFlexibility", err) + } + driverNodeTypeFlexibilityWireValue, err := nodeTypeFlexibilityToWire(v.DriverNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditClusterRequest.DriverNodeTypeFlexibility", err) + } + clusterLogConfWireValue, err := clusterLogConfToWire(v.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditClusterRequest.ClusterLogConf", err) + } + initScriptsWireValue, err := convertSlice(v.InitScripts, initScriptInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditClusterRequest.InitScripts", err) + } + dockerImageWireValue, err := dockerImageToWire(v.DockerImage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditClusterRequest.DockerImage", err) + } + workloadTypeWireValue, err := workloadTypeToWire(v.WorkloadType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditClusterRequest.WorkloadType", err) + } + var sizeNumWorkersWire *int + var sizeAutoscaleWire *autoScaleWire + switch value := v.Size.(type) { + case nil: + case *EditClusterRequest_Size_NumWorkers: + if value != nil { + sizeNumWorkersWire = new(value.NumWorkers) + } + case *EditClusterRequest_Size_Autoscale: + if value != nil { + sizeAutoscaleConverted, err := autoScaleToWire(&value.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditClusterRequest.Size.Autoscale", err) + } + sizeAutoscaleWire = sizeAutoscaleConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "EditClusterRequest.Size", value) + } + return &editClusterRequestWire{ + ClusterId: v.ClusterId, + ApplyPolicyDefaultValues: v.ApplyPolicyDefaultValues, + NumWorkers: sizeNumWorkersWire, + Autoscale: sizeAutoscaleWire, + ClusterName: v.ClusterName, + SparkVersion: v.SparkVersion, + SparkConf: v.SparkConf, + AwsAttributes: awsAttributesWireValue, + AzureAttributes: azureAttributesWireValue, + GcpAttributes: gcpAttributesWireValue, + NodeTypeId: v.NodeTypeId, + DriverNodeTypeId: v.DriverNodeTypeId, + WorkerNodeTypeFlexibility: workerNodeTypeFlexibilityWireValue, + DriverNodeTypeFlexibility: driverNodeTypeFlexibilityWireValue, + SshPublicKeys: v.SshPublicKeys, + CustomTags: v.CustomTags, + ClusterLogConf: clusterLogConfWireValue, + SparkEnvVars: v.SparkEnvVars, + AutoterminationMinutes: v.AutoterminationMinutes, + EnableElasticDisk: v.EnableElasticDisk, + InitScripts: initScriptsWireValue, + DockerImage: dockerImageWireValue, + InstancePoolId: v.InstancePoolId, + SingleUserName: v.SingleUserName, + PolicyId: v.PolicyId, + EnableLocalDiskEncryption: v.EnableLocalDiskEncryption, + DriverInstancePoolId: v.DriverInstancePoolId, + WorkloadType: workloadTypeWireValue, + DataSecurityMode: v.DataSecurityMode, + RuntimeEngine: v.RuntimeEngine, + Kind: v.Kind, + UseMlRuntime: v.UseMlRuntime, + IsSingleNode: v.IsSingleNode, + RemoteDiskThroughput: v.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: v.TotalInitialRemoteDiskSize, + DependencyMode: v.DependencyMode, + }, nil +} + +type enforcePolicyComplianceForClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + ValidateOnly *bool `json:"validate_only,omitempty"` + EnforceMode EnforcePolicyComplianceForClusterRequest_EnforceMode `json:"enforce_mode,omitempty"` +} + +func enforcePolicyComplianceForClusterRequestToWire(v *EnforcePolicyComplianceForClusterRequest) (*enforcePolicyComplianceForClusterRequestWire, error) { + if v == nil { + return nil, nil + } + return &enforcePolicyComplianceForClusterRequestWire{ + ClusterId: v.ClusterId, + ValidateOnly: v.ValidateOnly, + EnforceMode: v.EnforceMode, + }, nil +} + +type enforcePolicyComplianceForClusterResponseWire struct { + HasChanges *bool `json:"has_changes,omitempty"` + Changes []enforcePolicyComplianceForClusterResponse_ClusterSettingsChangeWire `json:"changes,omitempty"` + EnforceResult EnforcePolicyComplianceForClusterResponse_EnforceResult `json:"enforce_result,omitempty"` +} + +func enforcePolicyComplianceForClusterResponseFromWire(w *enforcePolicyComplianceForClusterResponseWire) (*EnforcePolicyComplianceForClusterResponse, error) { + if w == nil { + return nil, nil + } + changesPublicValue, err := convertSlice(w.Changes, enforcePolicyComplianceForClusterResponse_ClusterSettingsChangeFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse.Changes", err) + } + return &EnforcePolicyComplianceForClusterResponse{ + HasChanges: w.HasChanges, + Changes: changesPublicValue, + EnforceResult: w.EnforceResult, + }, nil +} + +type enforcePolicyComplianceForClusterResponse_ClusterSettingsWire struct { + ClusterName *string `json:"cluster_name,omitempty"` + SparkVersion *string `json:"spark_version,omitempty"` + SparkConf map[string]string `json:"spark_conf,omitempty"` + AwsAttributes *awsAttributesWire `json:"aws_attributes,omitempty"` + AzureAttributes *azureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *gcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + DriverNodeTypeId *string `json:"driver_node_type_id,omitempty"` + WorkerNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"worker_node_type_flexibility,omitempty"` + DriverNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"driver_node_type_flexibility,omitempty"` + SshPublicKeys []string `json:"ssh_public_keys,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + ClusterLogConf *clusterLogConfWire `json:"cluster_log_conf,omitempty"` + SparkEnvVars map[string]string `json:"spark_env_vars,omitempty"` + AutoterminationMinutes *int `json:"autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + InitScripts []initScriptInfoWire `json:"init_scripts,omitempty"` + DockerImage *dockerImageWire `json:"docker_image,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + SingleUserName *string `json:"single_user_name,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + EnableLocalDiskEncryption *bool `json:"enable_local_disk_encryption,omitempty"` + DriverInstancePoolId *string `json:"driver_instance_pool_id,omitempty"` + WorkloadType *workloadTypeWire `json:"workload_type,omitempty"` + DataSecurityMode DataSecurityMode `json:"data_security_mode,omitempty"` + RuntimeEngine RuntimeEngine `json:"runtime_engine,omitempty"` + Kind ComputeKind `json:"kind,omitempty"` + UseMlRuntime *bool `json:"use_ml_runtime,omitempty"` + IsSingleNode *bool `json:"is_single_node,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` + DependencyMode DependencyMode `json:"dependency_mode,omitempty"` + NumWorkers *int `json:"num_workers,omitempty"` + Autoscale *autoScaleWire `json:"autoscale,omitempty"` +} + +func enforcePolicyComplianceForClusterResponse_ClusterSettingsFromWire(w *enforcePolicyComplianceForClusterResponse_ClusterSettingsWire) (*EnforcePolicyComplianceForClusterResponse_ClusterSettings, error) { + if w == nil { + return nil, nil + } + sizeMembers := 0 + if w.NumWorkers != nil { + sizeMembers++ + } + if w.Autoscale != nil { + sizeMembers++ + } + if sizeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.Size") + } + awsAttributesPublicValue, err := awsAttributesFromWire(w.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.AwsAttributes", err) + } + azureAttributesPublicValue, err := azureAttributesFromWire(w.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.AzureAttributes", err) + } + gcpAttributesPublicValue, err := gcpAttributesFromWire(w.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.GcpAttributes", err) + } + workerNodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.WorkerNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.WorkerNodeTypeFlexibility", err) + } + driverNodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.DriverNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.DriverNodeTypeFlexibility", err) + } + clusterLogConfPublicValue, err := clusterLogConfFromWire(w.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.ClusterLogConf", err) + } + initScriptsPublicValue, err := convertSlice(w.InitScripts, initScriptInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.InitScripts", err) + } + dockerImagePublicValue, err := dockerImageFromWire(w.DockerImage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.DockerImage", err) + } + workloadTypePublicValue, err := workloadTypeFromWire(w.WorkloadType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.WorkloadType", err) + } + var sizeSelection isEnforcePolicyComplianceForClusterResponse_ClusterSettings_Size + switch { + case w.NumWorkers != nil: + sizeSelection = &EnforcePolicyComplianceForClusterResponse_ClusterSettings_Size_NumWorkers{NumWorkers: *w.NumWorkers} + case w.Autoscale != nil: + sizeAutoscaleConverted, err := autoScaleFromWire(w.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceForClusterResponse_ClusterSettings.Size.Autoscale", err) + } + sizeSelection = &EnforcePolicyComplianceForClusterResponse_ClusterSettings_Size_Autoscale{Autoscale: *sizeAutoscaleConverted} + } + return &EnforcePolicyComplianceForClusterResponse_ClusterSettings{ + ClusterName: w.ClusterName, + SparkVersion: w.SparkVersion, + SparkConf: w.SparkConf, + AwsAttributes: awsAttributesPublicValue, + AzureAttributes: azureAttributesPublicValue, + GcpAttributes: gcpAttributesPublicValue, + NodeTypeId: w.NodeTypeId, + DriverNodeTypeId: w.DriverNodeTypeId, + WorkerNodeTypeFlexibility: workerNodeTypeFlexibilityPublicValue, + DriverNodeTypeFlexibility: driverNodeTypeFlexibilityPublicValue, + SshPublicKeys: w.SshPublicKeys, + CustomTags: w.CustomTags, + ClusterLogConf: clusterLogConfPublicValue, + SparkEnvVars: w.SparkEnvVars, + AutoterminationMinutes: w.AutoterminationMinutes, + EnableElasticDisk: w.EnableElasticDisk, + InitScripts: initScriptsPublicValue, + DockerImage: dockerImagePublicValue, + InstancePoolId: w.InstancePoolId, + SingleUserName: w.SingleUserName, + PolicyId: w.PolicyId, + EnableLocalDiskEncryption: w.EnableLocalDiskEncryption, + DriverInstancePoolId: w.DriverInstancePoolId, + WorkloadType: workloadTypePublicValue, + DataSecurityMode: w.DataSecurityMode, + RuntimeEngine: w.RuntimeEngine, + Kind: w.Kind, + UseMlRuntime: w.UseMlRuntime, + IsSingleNode: w.IsSingleNode, + RemoteDiskThroughput: w.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: w.TotalInitialRemoteDiskSize, + DependencyMode: w.DependencyMode, + Size: sizeSelection, + }, nil +} + +type enforcePolicyComplianceForClusterResponse_ClusterSettingsChangeWire struct { + Field *string `json:"field,omitempty"` + PreviousValue *string `json:"previous_value,omitempty"` + NewValue *string `json:"new_value,omitempty"` +} + +func enforcePolicyComplianceForClusterResponse_ClusterSettingsChangeFromWire(w *enforcePolicyComplianceForClusterResponse_ClusterSettingsChangeWire) (*EnforcePolicyComplianceForClusterResponse_ClusterSettingsChange, error) { + if w == nil { + return nil, nil + } + return &EnforcePolicyComplianceForClusterResponse_ClusterSettingsChange{ + Field: w.Field, + PreviousValue: w.PreviousValue, + NewValue: w.NewValue, + }, nil +} + +type eventDetailsWire struct { + CurrentNumWorkers *int `json:"current_num_workers,omitempty"` + TargetNumWorkers *int `json:"target_num_workers,omitempty"` + PreviousAttributes *clusterAttributesWire `json:"previous_attributes,omitempty"` + Attributes *clusterAttributesWire `json:"attributes,omitempty"` + PreviousClusterSize *clusterSizeWire `json:"previous_cluster_size,omitempty"` + ClusterSize *clusterSizeWire `json:"cluster_size,omitempty"` + Cause ResizeCause_ResizeCause `json:"cause,omitempty"` + Reason *terminationReasonWire `json:"reason,omitempty"` + User *string `json:"user,omitempty"` + PreviousDiskSize *int64 `json:"previous_disk_size,omitempty"` + DiskSize *int64 `json:"disk_size,omitempty"` + FreeSpace *int64 `json:"free_space,omitempty"` + InstanceId *string `json:"instance_id,omitempty"` + DidNotExpandReason *string `json:"did_not_expand_reason,omitempty"` + DriverStateMessage *string `json:"driver_state_message,omitempty"` + JobRunName *string `json:"job_run_name,omitempty"` + InitScripts *initScriptEventDetailsWire `json:"init_scripts,omitempty"` + EnableTerminationForNodeBlocklisted *bool `json:"enable_termination_for_node_blocklisted,omitempty"` + CurrentNumVcpus *int `json:"current_num_vcpus,omitempty"` + TargetNumVcpus *int `json:"target_num_vcpus,omitempty"` +} + +func eventDetailsFromWire(w *eventDetailsWire) (*EventDetails, error) { + if w == nil { + return nil, nil + } + previousAttributesPublicValue, err := clusterAttributesFromWire(w.PreviousAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EventDetails.PreviousAttributes", err) + } + attributesPublicValue, err := clusterAttributesFromWire(w.Attributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EventDetails.Attributes", err) + } + previousClusterSizePublicValue, err := clusterSizeFromWire(w.PreviousClusterSize) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EventDetails.PreviousClusterSize", err) + } + clusterSizePublicValue, err := clusterSizeFromWire(w.ClusterSize) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EventDetails.ClusterSize", err) + } + reasonPublicValue, err := terminationReasonFromWire(w.Reason) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EventDetails.Reason", err) + } + initScriptsPublicValue, err := initScriptEventDetailsFromWire(w.InitScripts) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EventDetails.InitScripts", err) + } + return &EventDetails{ + CurrentNumWorkers: w.CurrentNumWorkers, + TargetNumWorkers: w.TargetNumWorkers, + PreviousAttributes: previousAttributesPublicValue, + Attributes: attributesPublicValue, + PreviousClusterSize: previousClusterSizePublicValue, + ClusterSize: clusterSizePublicValue, + Cause: w.Cause, + Reason: reasonPublicValue, + User: w.User, + PreviousDiskSize: w.PreviousDiskSize, + DiskSize: w.DiskSize, + FreeSpace: w.FreeSpace, + InstanceId: w.InstanceId, + DidNotExpandReason: w.DidNotExpandReason, + DriverStateMessage: w.DriverStateMessage, + JobRunName: w.JobRunName, + InitScripts: initScriptsPublicValue, + EnableTerminationForNodeBlocklisted: w.EnableTerminationForNodeBlocklisted, + CurrentNumVcpus: w.CurrentNumVcpus, + TargetNumVcpus: w.TargetNumVcpus, + }, nil +} + +type gcpAttributesWire struct { + UsePreemptibleExecutors *bool `json:"use_preemptible_executors,omitempty"` + GoogleServiceAccount *string `json:"google_service_account,omitempty"` + BootDiskSize *int `json:"boot_disk_size,omitempty"` + Availability GcpAvailability `json:"availability,omitempty"` + ZoneId *string `json:"zone_id,omitempty"` + LocalSsdCount *int `json:"local_ssd_count,omitempty"` + FirstOnDemand *int `json:"first_on_demand,omitempty"` + ConfidentialComputeType ConfidentialComputeType `json:"confidential_compute_type,omitempty"` +} + +func gcpAttributesToWire(v *GcpAttributes) (*gcpAttributesWire, error) { + if v == nil { + return nil, nil + } + return &gcpAttributesWire{ + UsePreemptibleExecutors: v.UsePreemptibleExecutors, + GoogleServiceAccount: v.GoogleServiceAccount, + BootDiskSize: v.BootDiskSize, + Availability: v.Availability, + ZoneId: v.ZoneId, + LocalSsdCount: v.LocalSsdCount, + FirstOnDemand: v.FirstOnDemand, + ConfidentialComputeType: v.ConfidentialComputeType, + }, nil +} + +func gcpAttributesFromWire(w *gcpAttributesWire) (*GcpAttributes, error) { + if w == nil { + return nil, nil + } + return &GcpAttributes{ + UsePreemptibleExecutors: w.UsePreemptibleExecutors, + GoogleServiceAccount: w.GoogleServiceAccount, + BootDiskSize: w.BootDiskSize, + Availability: w.Availability, + ZoneId: w.ZoneId, + LocalSsdCount: w.LocalSsdCount, + FirstOnDemand: w.FirstOnDemand, + ConfidentialComputeType: w.ConfidentialComputeType, + }, nil +} + +type gcsStorageInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func gcsStorageInfoToWire(v *GcsStorageInfo) (*gcsStorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &gcsStorageInfoWire{ + Destination: v.Destination, + }, nil +} + +func gcsStorageInfoFromWire(w *gcsStorageInfoWire) (*GcsStorageInfo, error) { + if w == nil { + return nil, nil + } + return &GcsStorageInfo{ + Destination: w.Destination, + }, nil +} + +type getClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` +} + +func getClusterRequestToWire(v *GetClusterRequest) (*getClusterRequestWire, error) { + if v == nil { + return nil, nil + } + return &getClusterRequestWire{ + ClusterId: v.ClusterId, + }, nil +} + +type getEventsResponseWire struct { + Events []clusterEventWire `json:"events,omitempty"` + NextPage *listEventsRequestWire `json:"next_page,omitempty"` + TotalCount *int64 `json:"total_count,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` + PrevPageToken *string `json:"prev_page_token,omitempty"` +} + +func getEventsResponseFromWire(w *getEventsResponseWire) (*GetEventsResponse, error) { + if w == nil { + return nil, nil + } + eventsPublicValue, err := convertSlice(w.Events, clusterEventFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetEventsResponse.Events", err) + } + nextPagePublicValue, err := listEventsRequestFromWire(w.NextPage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetEventsResponse.NextPage", err) + } + return &GetEventsResponse{ + Events: eventsPublicValue, + NextPage: nextPagePublicValue, + TotalCount: w.TotalCount, + NextPageToken: w.NextPageToken, + PrevPageToken: w.PrevPageToken, + }, nil +} + +type getPolicyComplianceForClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` +} + +func getPolicyComplianceForClusterRequestToWire(v *GetPolicyComplianceForClusterRequest) (*getPolicyComplianceForClusterRequestWire, error) { + if v == nil { + return nil, nil + } + return &getPolicyComplianceForClusterRequestWire{ + ClusterId: v.ClusterId, + }, nil +} + +type getPolicyComplianceForClusterResponseWire struct { + IsCompliant *bool `json:"is_compliant,omitempty"` + Violations map[string]string `json:"violations,omitempty"` + PendingEnforcement *pendingEnforcementWire `json:"pending_enforcement,omitempty"` +} + +func getPolicyComplianceForClusterResponseFromWire(w *getPolicyComplianceForClusterResponseWire) (*GetPolicyComplianceForClusterResponse, error) { + if w == nil { + return nil, nil + } + pendingEnforcementPublicValue, err := pendingEnforcementFromWire(w.PendingEnforcement) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPolicyComplianceForClusterResponse.PendingEnforcement", err) + } + return &GetPolicyComplianceForClusterResponse{ + IsCompliant: w.IsCompliant, + Violations: w.Violations, + PendingEnforcement: pendingEnforcementPublicValue, + }, nil +} + +type getSparkVersionsResponseWire struct { + Versions []sparkVersionWire `json:"versions,omitempty"` +} + +func getSparkVersionsResponseFromWire(w *getSparkVersionsResponseWire) (*GetSparkVersionsResponse, error) { + if w == nil { + return nil, nil + } + versionsPublicValue, err := convertSlice(w.Versions, sparkVersionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetSparkVersionsResponse.Versions", err) + } + return &GetSparkVersionsResponse{ + Versions: versionsPublicValue, + }, nil +} + +type initScriptEventDetailsWire struct { + ReportedForNode *string `json:"reported_for_node,omitempty"` + Global []initScriptEventDetails_InitScriptInfoAndExecutionDetailsWire `json:"global,omitempty"` + Cluster []initScriptEventDetails_InitScriptInfoAndExecutionDetailsWire `json:"cluster,omitempty"` +} + +func initScriptEventDetailsFromWire(w *initScriptEventDetailsWire) (*InitScriptEventDetails, error) { + if w == nil { + return nil, nil + } + globalPublicValue, err := convertSlice(w.Global, initScriptEventDetails_InitScriptInfoAndExecutionDetailsFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptEventDetails.Global", err) + } + clusterPublicValue, err := convertSlice(w.Cluster, initScriptEventDetails_InitScriptInfoAndExecutionDetailsFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptEventDetails.Cluster", err) + } + return &InitScriptEventDetails{ + ReportedForNode: w.ReportedForNode, + Global: globalPublicValue, + Cluster: clusterPublicValue, + }, nil +} + +type initScriptEventDetails_InitScriptInfoAndExecutionDetailsWire struct { + Dbfs *dbfsStorageInfoWire `json:"dbfs,omitempty"` + S3 *s3StorageInfoWire `json:"s3,omitempty"` + File *localFileInfoWire `json:"file,omitempty"` + Gcs *gcsStorageInfoWire `json:"gcs,omitempty"` + Abfss *adlsgen2InfoWire `json:"abfss,omitempty"` + Workspace *workspaceStorageInfoWire `json:"workspace,omitempty"` + Volumes *volumesStorageInfoWire `json:"volumes,omitempty"` + Status InitScriptExecutionDetails_InitScriptExecutionStatus `json:"status,omitempty"` + ExecutionDurationSeconds *int `json:"execution_duration_seconds,omitempty"` + ErrorMessage *string `json:"error_message,omitempty"` + Stderr *string `json:"stderr,omitempty"` +} + +func initScriptEventDetails_InitScriptInfoAndExecutionDetailsFromWire(w *initScriptEventDetails_InitScriptInfoAndExecutionDetailsWire) (*InitScriptEventDetails_InitScriptInfoAndExecutionDetails, error) { + if w == nil { + return nil, nil + } + storageInfoMembers := 0 + if w.Dbfs != nil { + storageInfoMembers++ + } + if w.S3 != nil { + storageInfoMembers++ + } + if w.File != nil { + storageInfoMembers++ + } + if w.Gcs != nil { + storageInfoMembers++ + } + if w.Abfss != nil { + storageInfoMembers++ + } + if w.Workspace != nil { + storageInfoMembers++ + } + if w.Volumes != nil { + storageInfoMembers++ + } + if storageInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo") + } + var storageInfoSelection isInitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo + switch { + case w.Dbfs != nil: + storageInfoDbfsConverted, err := dbfsStorageInfoFromWire(w.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo.Dbfs", err) + } + storageInfoSelection = &InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Dbfs{Dbfs: *storageInfoDbfsConverted} + case w.S3 != nil: + storageInfoS3Converted, err := s3StorageInfoFromWire(w.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo.S3", err) + } + storageInfoSelection = &InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_S3{S3: *storageInfoS3Converted} + case w.File != nil: + storageInfoFileConverted, err := localFileInfoFromWire(w.File) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo.File", err) + } + storageInfoSelection = &InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_File{File: *storageInfoFileConverted} + case w.Gcs != nil: + storageInfoGcsConverted, err := gcsStorageInfoFromWire(w.Gcs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo.Gcs", err) + } + storageInfoSelection = &InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Gcs{Gcs: *storageInfoGcsConverted} + case w.Abfss != nil: + storageInfoAbfssConverted, err := adlsgen2InfoFromWire(w.Abfss) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo.Abfss", err) + } + storageInfoSelection = &InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Abfss{Abfss: *storageInfoAbfssConverted} + case w.Workspace != nil: + storageInfoWorkspaceConverted, err := workspaceStorageInfoFromWire(w.Workspace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo.Workspace", err) + } + storageInfoSelection = &InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Workspace{Workspace: *storageInfoWorkspaceConverted} + case w.Volumes != nil: + storageInfoVolumesConverted, err := volumesStorageInfoFromWire(w.Volumes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptEventDetails_InitScriptInfoAndExecutionDetails.StorageInfo.Volumes", err) + } + storageInfoSelection = &InitScriptEventDetails_InitScriptInfoAndExecutionDetails_StorageInfo_Volumes{Volumes: *storageInfoVolumesConverted} + } + return &InitScriptEventDetails_InitScriptInfoAndExecutionDetails{ + Status: w.Status, + ExecutionDurationSeconds: w.ExecutionDurationSeconds, + ErrorMessage: w.ErrorMessage, + Stderr: w.Stderr, + StorageInfo: storageInfoSelection, + }, nil +} + +type initScriptInfoWire struct { + Dbfs *dbfsStorageInfoWire `json:"dbfs,omitempty"` + S3 *s3StorageInfoWire `json:"s3,omitempty"` + File *localFileInfoWire `json:"file,omitempty"` + Gcs *gcsStorageInfoWire `json:"gcs,omitempty"` + Abfss *adlsgen2InfoWire `json:"abfss,omitempty"` + Workspace *workspaceStorageInfoWire `json:"workspace,omitempty"` + Volumes *volumesStorageInfoWire `json:"volumes,omitempty"` +} + +func initScriptInfoToWire(v *InitScriptInfo) (*initScriptInfoWire, error) { + if v == nil { + return nil, nil + } + var storageInfoDbfsWire *dbfsStorageInfoWire + var storageInfoS3Wire *s3StorageInfoWire + var storageInfoFileWire *localFileInfoWire + var storageInfoGcsWire *gcsStorageInfoWire + var storageInfoAbfssWire *adlsgen2InfoWire + var storageInfoWorkspaceWire *workspaceStorageInfoWire + var storageInfoVolumesWire *volumesStorageInfoWire + switch value := v.StorageInfo.(type) { + case nil: + case *InitScriptInfo_StorageInfo_Dbfs: + if value != nil { + storageInfoDbfsConverted, err := dbfsStorageInfoToWire(&value.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Dbfs", err) + } + storageInfoDbfsWire = storageInfoDbfsConverted + } + case *InitScriptInfo_StorageInfo_S3: + if value != nil { + storageInfoS3Converted, err := s3StorageInfoToWire(&value.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.S3", err) + } + storageInfoS3Wire = storageInfoS3Converted + } + case *InitScriptInfo_StorageInfo_File: + if value != nil { + storageInfoFileConverted, err := localFileInfoToWire(&value.File) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.File", err) + } + storageInfoFileWire = storageInfoFileConverted + } + case *InitScriptInfo_StorageInfo_Gcs: + if value != nil { + storageInfoGcsConverted, err := gcsStorageInfoToWire(&value.Gcs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Gcs", err) + } + storageInfoGcsWire = storageInfoGcsConverted + } + case *InitScriptInfo_StorageInfo_Abfss: + if value != nil { + storageInfoAbfssConverted, err := adlsgen2InfoToWire(&value.Abfss) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Abfss", err) + } + storageInfoAbfssWire = storageInfoAbfssConverted + } + case *InitScriptInfo_StorageInfo_Workspace: + if value != nil { + storageInfoWorkspaceConverted, err := workspaceStorageInfoToWire(&value.Workspace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Workspace", err) + } + storageInfoWorkspaceWire = storageInfoWorkspaceConverted + } + case *InitScriptInfo_StorageInfo_Volumes: + if value != nil { + storageInfoVolumesConverted, err := volumesStorageInfoToWire(&value.Volumes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Volumes", err) + } + storageInfoVolumesWire = storageInfoVolumesConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "InitScriptInfo.StorageInfo", value) + } + return &initScriptInfoWire{ + Dbfs: storageInfoDbfsWire, + S3: storageInfoS3Wire, + File: storageInfoFileWire, + Gcs: storageInfoGcsWire, + Abfss: storageInfoAbfssWire, + Workspace: storageInfoWorkspaceWire, + Volumes: storageInfoVolumesWire, + }, nil +} + +func initScriptInfoFromWire(w *initScriptInfoWire) (*InitScriptInfo, error) { + if w == nil { + return nil, nil + } + storageInfoMembers := 0 + if w.Dbfs != nil { + storageInfoMembers++ + } + if w.S3 != nil { + storageInfoMembers++ + } + if w.File != nil { + storageInfoMembers++ + } + if w.Gcs != nil { + storageInfoMembers++ + } + if w.Abfss != nil { + storageInfoMembers++ + } + if w.Workspace != nil { + storageInfoMembers++ + } + if w.Volumes != nil { + storageInfoMembers++ + } + if storageInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "InitScriptInfo.StorageInfo") + } + var storageInfoSelection isInitScriptInfo_StorageInfo + switch { + case w.Dbfs != nil: + storageInfoDbfsConverted, err := dbfsStorageInfoFromWire(w.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Dbfs", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_Dbfs{Dbfs: *storageInfoDbfsConverted} + case w.S3 != nil: + storageInfoS3Converted, err := s3StorageInfoFromWire(w.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.S3", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_S3{S3: *storageInfoS3Converted} + case w.File != nil: + storageInfoFileConverted, err := localFileInfoFromWire(w.File) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.File", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_File{File: *storageInfoFileConverted} + case w.Gcs != nil: + storageInfoGcsConverted, err := gcsStorageInfoFromWire(w.Gcs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Gcs", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_Gcs{Gcs: *storageInfoGcsConverted} + case w.Abfss != nil: + storageInfoAbfssConverted, err := adlsgen2InfoFromWire(w.Abfss) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Abfss", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_Abfss{Abfss: *storageInfoAbfssConverted} + case w.Workspace != nil: + storageInfoWorkspaceConverted, err := workspaceStorageInfoFromWire(w.Workspace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Workspace", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_Workspace{Workspace: *storageInfoWorkspaceConverted} + case w.Volumes != nil: + storageInfoVolumesConverted, err := volumesStorageInfoFromWire(w.Volumes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Volumes", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_Volumes{Volumes: *storageInfoVolumesConverted} + } + return &InitScriptInfo{ + StorageInfo: storageInfoSelection, + }, nil +} + +type listAvailableZonesResponseWire struct { + Zones []string `json:"zones,omitempty"` + DefaultZone *string `json:"default_zone,omitempty"` +} + +func listAvailableZonesResponseFromWire(w *listAvailableZonesResponseWire) (*ListAvailableZonesResponse, error) { + if w == nil { + return nil, nil + } + return &ListAvailableZonesResponse{ + Zones: w.Zones, + DefaultZone: w.DefaultZone, + }, nil +} + +type listClusterComplianceForPolicyRequestWire struct { + PolicyId *string `json:"policy_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listClusterComplianceForPolicyRequestToWire(v *ListClusterComplianceForPolicyRequest) (*listClusterComplianceForPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + return &listClusterComplianceForPolicyRequestWire{ + PolicyId: v.PolicyId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listClusterComplianceForPolicyResponseWire struct { + Clusters []clusterComplianceWire `json:"clusters,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` + PrevPageToken *string `json:"prev_page_token,omitempty"` +} + +func listClusterComplianceForPolicyResponseFromWire(w *listClusterComplianceForPolicyResponseWire) (*ListClusterComplianceForPolicyResponse, error) { + if w == nil { + return nil, nil + } + clustersPublicValue, err := convertSlice(w.Clusters, clusterComplianceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListClusterComplianceForPolicyResponse.Clusters", err) + } + return &ListClusterComplianceForPolicyResponse{ + Clusters: clustersPublicValue, + NextPageToken: w.NextPageToken, + PrevPageToken: w.PrevPageToken, + }, nil +} + +type listClusterRevisionsRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listClusterRevisionsRequestToWire(v *ListClusterRevisionsRequest) (*listClusterRevisionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listClusterRevisionsRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listClusterRevisionsResponseWire struct { + ClusterRevisions []clusterRevisionWire `json:"cluster_revisions,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listClusterRevisionsResponseFromWire(w *listClusterRevisionsResponseWire) (*ListClusterRevisionsResponse, error) { + if w == nil { + return nil, nil + } + clusterRevisionsPublicValue, err := convertSlice(w.ClusterRevisions, clusterRevisionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListClusterRevisionsResponse.ClusterRevisions", err) + } + return &ListClusterRevisionsResponse{ + ClusterRevisions: clusterRevisionsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listClustersRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listClustersRequestToWire(v *ListClustersRequest) (*listClustersRequestWire, error) { + if v == nil { + return nil, nil + } + return &listClustersRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listClustersResponseWire struct { + Clusters []clusterInfoWire `json:"clusters,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` + PrevPageToken *string `json:"prev_page_token,omitempty"` +} + +func listClustersResponseFromWire(w *listClustersResponseWire) (*ListClustersResponse, error) { + if w == nil { + return nil, nil + } + clustersPublicValue, err := convertSlice(w.Clusters, clusterInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListClustersResponse.Clusters", err) + } + return &ListClustersResponse{ + Clusters: clustersPublicValue, + NextPageToken: w.NextPageToken, + PrevPageToken: w.PrevPageToken, + }, nil +} + +type listEventsRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + EndTime *int64 `json:"end_time,omitempty"` + Order GetEventsOrder `json:"order,omitempty"` + EventTypes []ClusterEventType_ClusterEventType `json:"event_types,omitempty"` + Offset *int64 `json:"offset,omitempty"` + Limit *int64 `json:"limit,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listEventsRequestToWire(v *ListEventsRequest) (*listEventsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listEventsRequestWire{ + ClusterId: v.ClusterId, + StartTime: v.StartTime, + EndTime: v.EndTime, + Order: v.Order, + EventTypes: v.EventTypes, + Offset: v.Offset, + Limit: v.Limit, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +func listEventsRequestFromWire(w *listEventsRequestWire) (*ListEventsRequest, error) { + if w == nil { + return nil, nil + } + return &ListEventsRequest{ + ClusterId: w.ClusterId, + StartTime: w.StartTime, + EndTime: w.EndTime, + Order: w.Order, + EventTypes: w.EventTypes, + Offset: w.Offset, + Limit: w.Limit, + PageToken: w.PageToken, + PageSize: w.PageSize, + }, nil +} + +type listNodeTypesResponseWire struct { + NodeTypes []nodeTypeWire `json:"node_types,omitempty"` +} + +func listNodeTypesResponseFromWire(w *listNodeTypesResponseWire) (*ListNodeTypesResponse, error) { + if w == nil { + return nil, nil + } + nodeTypesPublicValue, err := convertSlice(w.NodeTypes, nodeTypeFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListNodeTypesResponse.NodeTypes", err) + } + return &ListNodeTypesResponse{ + NodeTypes: nodeTypesPublicValue, + }, nil +} + +type localFileInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func localFileInfoToWire(v *LocalFileInfo) (*localFileInfoWire, error) { + if v == nil { + return nil, nil + } + return &localFileInfoWire{ + Destination: v.Destination, + }, nil +} + +func localFileInfoFromWire(w *localFileInfoWire) (*LocalFileInfo, error) { + if w == nil { + return nil, nil + } + return &LocalFileInfo{ + Destination: w.Destination, + }, nil +} + +type logAnalyticsInfoWire struct { + LogAnalyticsWorkspaceId *string `json:"log_analytics_workspace_id,omitempty"` + LogAnalyticsPrimaryKey *string `json:"log_analytics_primary_key,omitempty"` +} + +func logAnalyticsInfoToWire(v *LogAnalyticsInfo) (*logAnalyticsInfoWire, error) { + if v == nil { + return nil, nil + } + return &logAnalyticsInfoWire{ + LogAnalyticsWorkspaceId: v.LogAnalyticsWorkspaceId, + LogAnalyticsPrimaryKey: v.LogAnalyticsPrimaryKey, + }, nil +} + +func logAnalyticsInfoFromWire(w *logAnalyticsInfoWire) (*LogAnalyticsInfo, error) { + if w == nil { + return nil, nil + } + return &LogAnalyticsInfo{ + LogAnalyticsWorkspaceId: w.LogAnalyticsWorkspaceId, + LogAnalyticsPrimaryKey: w.LogAnalyticsPrimaryKey, + }, nil +} + +type logSyncStatusWire struct { + LastAttempted *int64 `json:"last_attempted,omitempty"` + LastException *string `json:"last_exception,omitempty"` +} + +func logSyncStatusFromWire(w *logSyncStatusWire) (*LogSyncStatus, error) { + if w == nil { + return nil, nil + } + return &LogSyncStatus{ + LastAttempted: w.LastAttempted, + LastException: w.LastException, + }, nil +} + +type nodeInstanceTypeWire struct { + InstanceTypeId *string `json:"instance_type_id,omitempty"` + LocalDisks *int `json:"local_disks,omitempty"` + LocalDiskSizeGb *int `json:"local_disk_size_gb,omitempty"` + LocalNvmeDiskSizeGb *int `json:"local_nvme_disk_size_gb,omitempty"` + LocalNvmeDisks *int `json:"local_nvme_disks,omitempty"` +} + +func nodeInstanceTypeFromWire(w *nodeInstanceTypeWire) (*NodeInstanceType, error) { + if w == nil { + return nil, nil + } + return &NodeInstanceType{ + InstanceTypeId: w.InstanceTypeId, + LocalDisks: w.LocalDisks, + LocalDiskSizeGb: w.LocalDiskSizeGb, + LocalNvmeDiskSizeGb: w.LocalNvmeDiskSizeGb, + LocalNvmeDisks: w.LocalNvmeDisks, + }, nil +} + +type nodeTypeWire struct { + NodeTypeId *string `json:"node_type_id,omitempty"` + MemoryMb *int `json:"memory_mb,omitempty"` + NumCores *float32 `json:"num_cores,omitempty"` + Description *string `json:"description,omitempty"` + InstanceTypeId *string `json:"instance_type_id,omitempty"` + IsDeprecated *bool `json:"is_deprecated,omitempty"` + Category *string `json:"category,omitempty"` + SupportEbsVolumes *bool `json:"support_ebs_volumes,omitempty"` + SupportClusterTags *bool `json:"support_cluster_tags,omitempty"` + NumGpus *int `json:"num_gpus,omitempty"` + NodeInstanceType *nodeInstanceTypeWire `json:"node_instance_type,omitempty"` + IsHidden *bool `json:"is_hidden,omitempty"` + SupportPortForwarding *bool `json:"support_port_forwarding,omitempty"` + DisplayOrder *int `json:"display_order,omitempty"` + IsIoCacheEnabled *bool `json:"is_io_cache_enabled,omitempty"` + NodeInfo *cloudProviderNodeInfoWire `json:"node_info,omitempty"` + PhotonWorkerCapable *bool `json:"photon_worker_capable,omitempty"` + PhotonDriverCapable *bool `json:"photon_driver_capable,omitempty"` + IsEncryptedInTransit *bool `json:"is_encrypted_in_transit,omitempty"` + IsGraviton *bool `json:"is_graviton,omitempty"` +} + +func nodeTypeFromWire(w *nodeTypeWire) (*NodeType, error) { + if w == nil { + return nil, nil + } + nodeInstanceTypePublicValue, err := nodeInstanceTypeFromWire(w.NodeInstanceType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NodeType.NodeInstanceType", err) + } + nodeInfoPublicValue, err := cloudProviderNodeInfoFromWire(w.NodeInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NodeType.NodeInfo", err) + } + return &NodeType{ + NodeTypeId: w.NodeTypeId, + MemoryMb: w.MemoryMb, + NumCores: w.NumCores, + Description: w.Description, + InstanceTypeId: w.InstanceTypeId, + IsDeprecated: w.IsDeprecated, + Category: w.Category, + SupportEbsVolumes: w.SupportEbsVolumes, + SupportClusterTags: w.SupportClusterTags, + NumGpus: w.NumGpus, + NodeInstanceType: nodeInstanceTypePublicValue, + IsHidden: w.IsHidden, + SupportPortForwarding: w.SupportPortForwarding, + DisplayOrder: w.DisplayOrder, + IsIoCacheEnabled: w.IsIoCacheEnabled, + NodeInfo: nodeInfoPublicValue, + PhotonWorkerCapable: w.PhotonWorkerCapable, + PhotonDriverCapable: w.PhotonDriverCapable, + IsEncryptedInTransit: w.IsEncryptedInTransit, + IsGraviton: w.IsGraviton, + }, nil +} + +type nodeTypeFlexibilityWire struct { + AlternateNodeTypeIds []string `json:"alternate_node_type_ids,omitempty"` +} + +func nodeTypeFlexibilityToWire(v *NodeTypeFlexibility) (*nodeTypeFlexibilityWire, error) { + if v == nil { + return nil, nil + } + return &nodeTypeFlexibilityWire{ + AlternateNodeTypeIds: v.AlternateNodeTypeIds, + }, nil +} + +func nodeTypeFlexibilityFromWire(w *nodeTypeFlexibilityWire) (*NodeTypeFlexibility, error) { + if w == nil { + return nil, nil + } + return &NodeTypeFlexibility{ + AlternateNodeTypeIds: w.AlternateNodeTypeIds, + }, nil +} + +type pendingEnforcementWire struct { + TargetSpec *enforcePolicyComplianceForClusterResponse_ClusterSettingsWire `json:"target_spec,omitempty"` + InitiateTime *types.Time `json:"initiate_time,omitempty"` + EnforcementStatus PendingEnforcement_EnforcementStatus `json:"enforcement_status,omitempty"` + TargetChanges []enforcePolicyComplianceForClusterResponse_ClusterSettingsChangeWire `json:"target_changes,omitempty"` + InitiatorUser *string `json:"initiator_user,omitempty"` +} + +func pendingEnforcementFromWire(w *pendingEnforcementWire) (*PendingEnforcement, error) { + if w == nil { + return nil, nil + } + targetSpecPublicValue, err := enforcePolicyComplianceForClusterResponse_ClusterSettingsFromWire(w.TargetSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PendingEnforcement.TargetSpec", err) + } + targetChangesPublicValue, err := convertSlice(w.TargetChanges, enforcePolicyComplianceForClusterResponse_ClusterSettingsChangeFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PendingEnforcement.TargetChanges", err) + } + return &PendingEnforcement{ + TargetSpec: targetSpecPublicValue, + InitiateTime: w.InitiateTime, + EnforcementStatus: w.EnforcementStatus, + TargetChanges: targetChangesPublicValue, + InitiatorUser: w.InitiatorUser, + }, nil +} + +type permanentDeleteClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` +} + +func permanentDeleteClusterRequestToWire(v *PermanentDeleteClusterRequest) (*permanentDeleteClusterRequestWire, error) { + if v == nil { + return nil, nil + } + return &permanentDeleteClusterRequestWire{ + ClusterId: v.ClusterId, + }, nil +} + +type pinClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` +} + +func pinClusterRequestToWire(v *PinClusterRequest) (*pinClusterRequestWire, error) { + if v == nil { + return nil, nil + } + return &pinClusterRequestWire{ + ClusterId: v.ClusterId, + }, nil +} + +type resizeClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + NumWorkers *int `json:"num_workers,omitempty"` + Autoscale *autoScaleWire `json:"autoscale,omitempty"` +} + +func resizeClusterRequestToWire(v *ResizeClusterRequest) (*resizeClusterRequestWire, error) { + if v == nil { + return nil, nil + } + var sizeNumWorkersWire *int + var sizeAutoscaleWire *autoScaleWire + switch value := v.Size.(type) { + case nil: + case *ResizeClusterRequest_Size_NumWorkers: + if value != nil { + sizeNumWorkersWire = new(value.NumWorkers) + } + case *ResizeClusterRequest_Size_Autoscale: + if value != nil { + sizeAutoscaleConverted, err := autoScaleToWire(&value.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResizeClusterRequest.Size.Autoscale", err) + } + sizeAutoscaleWire = sizeAutoscaleConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ResizeClusterRequest.Size", value) + } + return &resizeClusterRequestWire{ + ClusterId: v.ClusterId, + NumWorkers: sizeNumWorkersWire, + Autoscale: sizeAutoscaleWire, + }, nil +} + +type restartClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + RestartUser *string `json:"restart_user,omitempty"` +} + +func restartClusterRequestToWire(v *RestartClusterRequest) (*restartClusterRequestWire, error) { + if v == nil { + return nil, nil + } + return &restartClusterRequestWire{ + ClusterId: v.ClusterId, + RestartUser: v.RestartUser, + }, nil +} + +type rollbackClusterRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func rollbackClusterRequestToWire(v *RollbackClusterRequest) (*rollbackClusterRequestWire, error) { + if v == nil { + return nil, nil + } + return &rollbackClusterRequestWire{ + Name: v.Name, + }, nil +} + +type s3StorageInfoWire struct { + Destination *string `json:"destination,omitempty"` + Region *string `json:"region,omitempty"` + Endpoint *string `json:"endpoint,omitempty"` + EnableEncryption *bool `json:"enable_encryption,omitempty"` + EncryptionType *string `json:"encryption_type,omitempty"` + KmsKey *string `json:"kms_key,omitempty"` + CannedAcl *string `json:"canned_acl,omitempty"` +} + +func s3StorageInfoToWire(v *S3StorageInfo) (*s3StorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &s3StorageInfoWire{ + Destination: v.Destination, + Region: v.Region, + Endpoint: v.Endpoint, + EnableEncryption: v.EnableEncryption, + EncryptionType: v.EncryptionType, + KmsKey: v.KmsKey, + CannedAcl: v.CannedAcl, + }, nil +} + +func s3StorageInfoFromWire(w *s3StorageInfoWire) (*S3StorageInfo, error) { + if w == nil { + return nil, nil + } + return &S3StorageInfo{ + Destination: w.Destination, + Region: w.Region, + Endpoint: w.Endpoint, + EnableEncryption: w.EnableEncryption, + EncryptionType: w.EncryptionType, + KmsKey: w.KmsKey, + CannedAcl: w.CannedAcl, + }, nil +} + +type sparkInfo_SparkNodeWire struct { + PrivateIp *string `json:"private_ip,omitempty"` + PublicDns *string `json:"public_dns,omitempty"` + NodeId *string `json:"node_id,omitempty"` + InstanceId *string `json:"instance_id,omitempty"` + StartTimestamp *int64 `json:"start_timestamp,omitempty"` + NodeAwsAttributes *sparkInfo_SparkNode_SparkNodeAwsAttributesWire `json:"node_aws_attributes,omitempty"` + HostPrivateIp *string `json:"host_private_ip,omitempty"` +} + +func sparkInfo_SparkNodeFromWire(w *sparkInfo_SparkNodeWire) (*SparkInfo_SparkNode, error) { + if w == nil { + return nil, nil + } + nodeAwsAttributesPublicValue, err := sparkInfo_SparkNode_SparkNodeAwsAttributesFromWire(w.NodeAwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SparkInfo_SparkNode.NodeAwsAttributes", err) + } + return &SparkInfo_SparkNode{ + PrivateIp: w.PrivateIp, + PublicDns: w.PublicDns, + NodeId: w.NodeId, + InstanceId: w.InstanceId, + StartTimestamp: w.StartTimestamp, + NodeAwsAttributes: nodeAwsAttributesPublicValue, + HostPrivateIp: w.HostPrivateIp, + }, nil +} + +type sparkInfo_SparkNode_SparkNodeAwsAttributesWire struct { + IsSpot *bool `json:"is_spot,omitempty"` +} + +func sparkInfo_SparkNode_SparkNodeAwsAttributesFromWire(w *sparkInfo_SparkNode_SparkNodeAwsAttributesWire) (*SparkInfo_SparkNode_SparkNodeAwsAttributes, error) { + if w == nil { + return nil, nil + } + return &SparkInfo_SparkNode_SparkNodeAwsAttributes{ + IsSpot: w.IsSpot, + }, nil +} + +type sparkVersionWire struct { + Key *string `json:"key,omitempty"` + Name *string `json:"name,omitempty"` +} + +func sparkVersionFromWire(w *sparkVersionWire) (*SparkVersion, error) { + if w == nil { + return nil, nil + } + return &SparkVersion{ + Key: w.Key, + Name: w.Name, + }, nil +} + +type startClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` +} + +func startClusterRequestToWire(v *StartClusterRequest) (*startClusterRequestWire, error) { + if v == nil { + return nil, nil + } + return &startClusterRequestWire{ + ClusterId: v.ClusterId, + }, nil +} + +type terminationReasonWire struct { + Code TerminationCode `json:"code,omitempty"` + Type TerminationType `json:"type,omitempty"` + Parameters map[string]string `json:"parameters,omitempty"` +} + +func terminationReasonFromWire(w *terminationReasonWire) (*TerminationReason, error) { + if w == nil { + return nil, nil + } + return &TerminationReason{ + Code: w.Code, + Type: w.Type, + Parameters: w.Parameters, + }, nil +} + +type unpinClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` +} + +func unpinClusterRequestToWire(v *UnpinClusterRequest) (*unpinClusterRequestWire, error) { + if v == nil { + return nil, nil + } + return &unpinClusterRequestWire{ + ClusterId: v.ClusterId, + }, nil +} + +type updateClusterRequestWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + Cluster *updateClusterRequest_UpdateClusterResourceWire `json:"cluster,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateClusterRequestToWire(v *UpdateClusterRequest) (*updateClusterRequestWire, error) { + if v == nil { + return nil, nil + } + clusterWireValue, err := updateClusterRequest_UpdateClusterResourceToWire(v.Cluster) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest.Cluster", err) + } + return &updateClusterRequestWire{ + ClusterId: v.ClusterId, + Cluster: clusterWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateClusterRequest_UpdateClusterResourceWire struct { + NumWorkers *int `json:"num_workers,omitempty"` + Autoscale *autoScaleWire `json:"autoscale,omitempty"` + ClusterName *string `json:"cluster_name,omitempty"` + SparkVersion *string `json:"spark_version,omitempty"` + SparkConf map[string]string `json:"spark_conf,omitempty"` + AwsAttributes *awsAttributesWire `json:"aws_attributes,omitempty"` + AzureAttributes *azureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *gcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + DriverNodeTypeId *string `json:"driver_node_type_id,omitempty"` + WorkerNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"worker_node_type_flexibility,omitempty"` + DriverNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"driver_node_type_flexibility,omitempty"` + SshPublicKeys []string `json:"ssh_public_keys,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + ClusterLogConf *clusterLogConfWire `json:"cluster_log_conf,omitempty"` + SparkEnvVars map[string]string `json:"spark_env_vars,omitempty"` + AutoterminationMinutes *int `json:"autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + InitScripts []initScriptInfoWire `json:"init_scripts,omitempty"` + DockerImage *dockerImageWire `json:"docker_image,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + SingleUserName *string `json:"single_user_name,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + EnableLocalDiskEncryption *bool `json:"enable_local_disk_encryption,omitempty"` + DriverInstancePoolId *string `json:"driver_instance_pool_id,omitempty"` + WorkloadType *workloadTypeWire `json:"workload_type,omitempty"` + DataSecurityMode DataSecurityMode `json:"data_security_mode,omitempty"` + RuntimeEngine RuntimeEngine `json:"runtime_engine,omitempty"` + Kind ComputeKind `json:"kind,omitempty"` + UseMlRuntime *bool `json:"use_ml_runtime,omitempty"` + IsSingleNode *bool `json:"is_single_node,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` + DependencyMode DependencyMode `json:"dependency_mode,omitempty"` +} + +func updateClusterRequest_UpdateClusterResourceToWire(v *UpdateClusterRequest_UpdateClusterResource) (*updateClusterRequest_UpdateClusterResourceWire, error) { + if v == nil { + return nil, nil + } + awsAttributesWireValue, err := awsAttributesToWire(v.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest_UpdateClusterResource.AwsAttributes", err) + } + azureAttributesWireValue, err := azureAttributesToWire(v.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest_UpdateClusterResource.AzureAttributes", err) + } + gcpAttributesWireValue, err := gcpAttributesToWire(v.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest_UpdateClusterResource.GcpAttributes", err) + } + workerNodeTypeFlexibilityWireValue, err := nodeTypeFlexibilityToWire(v.WorkerNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest_UpdateClusterResource.WorkerNodeTypeFlexibility", err) + } + driverNodeTypeFlexibilityWireValue, err := nodeTypeFlexibilityToWire(v.DriverNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest_UpdateClusterResource.DriverNodeTypeFlexibility", err) + } + clusterLogConfWireValue, err := clusterLogConfToWire(v.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest_UpdateClusterResource.ClusterLogConf", err) + } + initScriptsWireValue, err := convertSlice(v.InitScripts, initScriptInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest_UpdateClusterResource.InitScripts", err) + } + dockerImageWireValue, err := dockerImageToWire(v.DockerImage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest_UpdateClusterResource.DockerImage", err) + } + workloadTypeWireValue, err := workloadTypeToWire(v.WorkloadType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest_UpdateClusterResource.WorkloadType", err) + } + var sizeNumWorkersWire *int + var sizeAutoscaleWire *autoScaleWire + switch value := v.Size.(type) { + case nil: + case *UpdateClusterRequest_UpdateClusterResource_Size_NumWorkers: + if value != nil { + sizeNumWorkersWire = new(value.NumWorkers) + } + case *UpdateClusterRequest_UpdateClusterResource_Size_Autoscale: + if value != nil { + sizeAutoscaleConverted, err := autoScaleToWire(&value.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateClusterRequest_UpdateClusterResource.Size.Autoscale", err) + } + sizeAutoscaleWire = sizeAutoscaleConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "UpdateClusterRequest_UpdateClusterResource.Size", value) + } + return &updateClusterRequest_UpdateClusterResourceWire{ + NumWorkers: sizeNumWorkersWire, + Autoscale: sizeAutoscaleWire, + ClusterName: v.ClusterName, + SparkVersion: v.SparkVersion, + SparkConf: v.SparkConf, + AwsAttributes: awsAttributesWireValue, + AzureAttributes: azureAttributesWireValue, + GcpAttributes: gcpAttributesWireValue, + NodeTypeId: v.NodeTypeId, + DriverNodeTypeId: v.DriverNodeTypeId, + WorkerNodeTypeFlexibility: workerNodeTypeFlexibilityWireValue, + DriverNodeTypeFlexibility: driverNodeTypeFlexibilityWireValue, + SshPublicKeys: v.SshPublicKeys, + CustomTags: v.CustomTags, + ClusterLogConf: clusterLogConfWireValue, + SparkEnvVars: v.SparkEnvVars, + AutoterminationMinutes: v.AutoterminationMinutes, + EnableElasticDisk: v.EnableElasticDisk, + InitScripts: initScriptsWireValue, + DockerImage: dockerImageWireValue, + InstancePoolId: v.InstancePoolId, + SingleUserName: v.SingleUserName, + PolicyId: v.PolicyId, + EnableLocalDiskEncryption: v.EnableLocalDiskEncryption, + DriverInstancePoolId: v.DriverInstancePoolId, + WorkloadType: workloadTypeWireValue, + DataSecurityMode: v.DataSecurityMode, + RuntimeEngine: v.RuntimeEngine, + Kind: v.Kind, + UseMlRuntime: v.UseMlRuntime, + IsSingleNode: v.IsSingleNode, + RemoteDiskThroughput: v.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: v.TotalInitialRemoteDiskSize, + DependencyMode: v.DependencyMode, + }, nil +} + +type volumesStorageInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func volumesStorageInfoToWire(v *VolumesStorageInfo) (*volumesStorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &volumesStorageInfoWire{ + Destination: v.Destination, + }, nil +} + +func volumesStorageInfoFromWire(w *volumesStorageInfoWire) (*VolumesStorageInfo, error) { + if w == nil { + return nil, nil + } + return &VolumesStorageInfo{ + Destination: w.Destination, + }, nil +} + +type workloadTypeWire struct { + Clients *workloadType_ClientsTypesWire `json:"clients,omitempty"` +} + +func workloadTypeToWire(v *WorkloadType) (*workloadTypeWire, error) { + if v == nil { + return nil, nil + } + clientsWireValue, err := workloadType_ClientsTypesToWire(v.Clients) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkloadType.Clients", err) + } + return &workloadTypeWire{ + Clients: clientsWireValue, + }, nil +} + +func workloadTypeFromWire(w *workloadTypeWire) (*WorkloadType, error) { + if w == nil { + return nil, nil + } + clientsPublicValue, err := workloadType_ClientsTypesFromWire(w.Clients) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkloadType.Clients", err) + } + return &WorkloadType{ + Clients: clientsPublicValue, + }, nil +} + +type workloadType_ClientsTypesWire struct { + Notebooks *bool `json:"notebooks,omitempty"` + Jobs *bool `json:"jobs,omitempty"` +} + +func workloadType_ClientsTypesToWire(v *WorkloadType_ClientsTypes) (*workloadType_ClientsTypesWire, error) { + if v == nil { + return nil, nil + } + return &workloadType_ClientsTypesWire{ + Notebooks: v.Notebooks, + Jobs: v.Jobs, + }, nil +} + +func workloadType_ClientsTypesFromWire(w *workloadType_ClientsTypesWire) (*WorkloadType_ClientsTypes, error) { + if w == nil { + return nil, nil + } + return &WorkloadType_ClientsTypes{ + Notebooks: w.Notebooks, + Jobs: w.Jobs, + }, nil +} + +type workspaceStorageInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func workspaceStorageInfoToWire(v *WorkspaceStorageInfo) (*workspaceStorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &workspaceStorageInfoWire{ + Destination: v.Destination, + }, nil +} + +func workspaceStorageInfoFromWire(w *workspaceStorageInfoWire) (*WorkspaceStorageInfo, error) { + if w == nil { + return nil, nil + } + return &WorkspaceStorageInfo{ + Destination: w.Destination, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/commandexecution/.package.json b/commandexecution/.package.json new file mode 100644 index 0000000..f05a721 --- /dev/null +++ b/commandexecution/.package.json @@ -0,0 +1,3 @@ +{ + "package": "commandexecution" +} diff --git a/commandexecution/CHANGELOG.md b/commandexecution/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/commandexecution/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/commandexecution/README.md b/commandexecution/README.md new file mode 100644 index 0000000..0f09963 --- /dev/null +++ b/commandexecution/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/commandexecution + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/commandexecution@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/commandexecution/v2" + +client, err := commandexecution.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/commandexecution/go.mod b/commandexecution/go.mod new file mode 100644 index 0000000..ab97988 --- /dev/null +++ b/commandexecution/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/commandexecution + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/commandexecution/internal/version.go b/commandexecution/internal/version.go new file mode 100644 index 0000000..4627257 --- /dev/null +++ b/commandexecution/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-commandexecution" + +const Version = "0.0.1-dev.1" diff --git a/commandexecution/v2/client.go b/commandexecution/v2/client.go new file mode 100755 index 0000000..76f1fd2 --- /dev/null +++ b/commandexecution/v2/client.go @@ -0,0 +1,762 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package commandexecution + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/commandexecution/internal" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Cancels a currently running command within an execution context. +// +// The command ID is obtained from a prior successful call to __execute__. +func (c *internalClient) cancelBase(ctx context.Context, req *CancelCommandRequest, opts ...call.Option) (*CancelResponse, error) { + wireReq, err := cancelCommandRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/1.2/commands/cancel" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CancelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &CancelResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Cancels a currently running command within an execution context. +// +// The command ID is obtained from a prior successful call to __execute__. +func (c *internalClient) Cancel(ctx context.Context, req *CancelCommandRequest, opts ...call.Option) (*CancelWaiter, error) { + if req.ClusterId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ClusterId") + } + capturedClusterId := *req.ClusterId + if req.ContextId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ContextId") + } + capturedContextId := *req.ContextId + if req.CommandId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "CommandId") + } + capturedCommandId := *req.CommandId + _, err := c.cancelBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &CancelWaiter{ + poll: c.GetCommandStatus, + clusterId: capturedClusterId, + contextId: capturedContextId, + commandId: capturedCommandId, + }, nil +} + +// CancelWaiter tracks the state of the operation started by Cancel. +type CancelWaiter struct { + poll func(context.Context, *GetCommandStatusRequest, ...call.Option) (*GetCommandStatusResponse, error) + clusterId string + contextId string + commandId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CancelWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetCommandStatusRequest{ + ClusterId: &w.clusterId, + ContextId: &w.contextId, + CommandId: &w.commandId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case CommandStatus_CommandCancelled, CommandStatus_CommandError: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CancelWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetCommandStatusResponse, error) { + var result *GetCommandStatusResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetCommandStatusRequest{ + ClusterId: &w.clusterId, + ContextId: &w.contextId, + CommandId: &w.commandId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case CommandStatus_CommandCancelled: + result = pollResp + return nil + case CommandStatus_CommandError: + message := "(no message)" + if pollResp.Results != nil && pollResp.Results.Cause != nil { + message = fmt.Sprintf("%v", *pollResp.Results.Cause) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Creates an execution context for running cluster commands. +// +// If successful, this method returns the ID of the new execution context. +func (c *internalClient) createBase(ctx context.Context, req *CreateContextRequest, opts ...call.Option) (*CreateResponse, error) { + wireReq, err := createContextRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/1.2/contexts/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates an execution context for running cluster commands. +// +// If successful, this method returns the ID of the new execution context. +func (c *internalClient) Create(ctx context.Context, req *CreateContextRequest, opts ...call.Option) (*CreateWaiter, error) { + if req.ClusterId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ClusterId") + } + capturedClusterId := *req.ClusterId + resp, err := c.createBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.Id == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "Id") + } + return &CreateWaiter{ + poll: c.GetContextStatus, + clusterId: capturedClusterId, + contextId: *resp.Id, + }, nil +} + +// CreateWaiter tracks the state of the operation started by Create. +type CreateWaiter struct { + poll func(context.Context, *GetContextStatusRequest, ...call.Option) (*GetContextStatusResponse, error) + clusterId string + contextId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetContextStatusRequest{ + ClusterId: &w.clusterId, + ContextId: &w.contextId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ContextStatus_ContextRunning, ContextStatus_ContextError: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetContextStatusResponse, error) { + var result *GetContextStatusResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetContextStatusRequest{ + ClusterId: &w.clusterId, + ContextId: &w.contextId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ContextStatus_ContextRunning: + result = pollResp + return nil + case ContextStatus_ContextError: + message := "(no message)" + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Deletes an execution context. +func (c *internalClient) Destroy(ctx context.Context, req *DestroyContextRequest, opts ...call.Option) (*DestroyResponse, error) { + wireReq, err := destroyContextRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/1.2/contexts/destroy" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DestroyResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DestroyResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Runs a cluster command in the given execution context, using the provided +// language. +// +// If successful, it returns an ID for tracking the status of the command's +// execution. +func (c *internalClient) executeBase(ctx context.Context, req *ExecuteCommandRequest, opts ...call.Option) (*CreateResponse, error) { + wireReq, err := executeCommandRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/1.2/commands/execute" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Runs a cluster command in the given execution context, using the provided +// language. +// +// If successful, it returns an ID for tracking the status of the command's +// execution. +func (c *internalClient) Execute(ctx context.Context, req *ExecuteCommandRequest, opts ...call.Option) (*ExecuteWaiter, error) { + if req.ClusterId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ClusterId") + } + capturedClusterId := *req.ClusterId + if req.ContextId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ContextId") + } + capturedContextId := *req.ContextId + resp, err := c.executeBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.Id == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "Id") + } + return &ExecuteWaiter{ + poll: c.GetCommandStatus, + clusterId: capturedClusterId, + contextId: capturedContextId, + commandId: *resp.Id, + }, nil +} + +// ExecuteWaiter tracks the state of the operation started by Execute. +type ExecuteWaiter struct { + poll func(context.Context, *GetCommandStatusRequest, ...call.Option) (*GetCommandStatusResponse, error) + clusterId string + contextId string + commandId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *ExecuteWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetCommandStatusRequest{ + ClusterId: &w.clusterId, + ContextId: &w.contextId, + CommandId: &w.commandId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case CommandStatus_CommandFinished, CommandStatus_CommandError, CommandStatus_CommandCancelled, CommandStatus_CommandCancelling: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *ExecuteWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetCommandStatusResponse, error) { + var result *GetCommandStatusResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetCommandStatusRequest{ + ClusterId: &w.clusterId, + ContextId: &w.contextId, + CommandId: &w.commandId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case CommandStatus_CommandFinished, CommandStatus_CommandError: + result = pollResp + return nil + case CommandStatus_CommandCancelled, CommandStatus_CommandCancelling: + message := "(no message)" + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Gets the status of and, if available, the results from a currently executing +// command. +// +// The command ID is obtained from a prior successful call to __execute__. +func (c *internalClient) GetCommandStatus(ctx context.Context, req *GetCommandStatusRequest, opts ...call.Option) (*GetCommandStatusResponse, error) { + wireReq, err := getCommandStatusRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/1.2/commands/status" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "clusterId", wireReq.ClusterId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "contextId", wireReq.ContextId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "commandId", wireReq.CommandId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetCommandStatusResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getCommandStatusResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getCommandStatusResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the status for an execution context. +func (c *internalClient) GetContextStatus(ctx context.Context, req *GetContextStatusRequest, opts ...call.Option) (*GetContextStatusResponse, error) { + wireReq, err := getContextStatusRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/1.2/contexts/status" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "clusterId", wireReq.ClusterId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "contextId", wireReq.ContextId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetContextStatusResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getContextStatusResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getContextStatusResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/commandexecution/v2/genhelper.go b/commandexecution/v2/genhelper.go new file mode 100755 index 0000000..1388bd4 --- /dev/null +++ b/commandexecution/v2/genhelper.go @@ -0,0 +1,199 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package commandexecution + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} diff --git a/commandexecution/v2/model.go b/commandexecution/v2/model.go new file mode 100755 index 0000000..497d6af --- /dev/null +++ b/commandexecution/v2/model.go @@ -0,0 +1,138 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package commandexecution + +import "encoding/json" + +type CommandStatus string + +const ( + CommandStatus_Unspecified CommandStatus = "" + CommandStatus_CommandCancelled CommandStatus = "Cancelled" + CommandStatus_CommandCancelling CommandStatus = "Cancelling" + CommandStatus_CommandError CommandStatus = "Error" + CommandStatus_CommandFinished CommandStatus = "Finished" + CommandStatus_CommandQueued CommandStatus = "Queued" + CommandStatus_CommandRunning CommandStatus = "Running" +) + +type ContextStatus string + +const ( + ContextStatus_Unspecified ContextStatus = "" + ContextStatus_ContextRunning ContextStatus = "Running" + ContextStatus_ContextPending ContextStatus = "Pending" + ContextStatus_ContextError ContextStatus = "Error" +) + +type Language string + +const ( + Language_Unspecified Language = "" + Language_Python Language = "python" + Language_Scala Language = "scala" + Language_Sql Language = "sql" + Language_R Language = "r" +) + +type ResultType string + +const ( + ResultType_Unspecified ResultType = "" + ResultType_ErrorResult ResultType = "error" + ResultType_ImageResult ResultType = "image" + ResultType_ImagesResult ResultType = "images" + ResultType_TableResult ResultType = "table" + ResultType_TextResult ResultType = "text" +) + +type CancelCommandRequest struct { + ClusterId *string + CommandId *string + ContextId *string +} + +type CancelResponse struct { +} + +type CreateContextRequest struct { + // Running cluster id + ClusterId *string + Language Language +} + +type CreateResponse struct { + Id *string +} + +type DestroyContextRequest struct { + ClusterId *string + ContextId *string +} + +type DestroyResponse struct { +} + +type ExecuteCommandRequest struct { + // Running cluster id + ClusterId *string + // Running context id + ContextId *string + Language Language + // Executable code + Command *string +} + +// Request to get the status of a previously submitted command.. +type GetCommandStatusRequest struct { + ClusterId *string + ContextId *string + CommandId *string +} + +type GetCommandStatusResponse struct { + Id *string + Status CommandStatus + Results *Results +} + +// Request to retrieve the status of an execution context.. +type GetContextStatusRequest struct { + ClusterId *string + ContextId *string +} + +type GetContextStatusResponse struct { + Id *string + Status ContextStatus +} + +type Results struct { + // The cause of the error + Cause *string + Data json.RawMessage + // The image data in one of the following formats: + // + // 1. A Data URL with base64-encoded image data: + // `data:image/{type};base64,{base64-data}`. Example: + // `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...` + // + // 2. A FileStore file path for large images: `/plots/{filename}.png`. Example: + // `/plots/b6a7ad70-fb2c-4353-8aed-3f1e015174a4.png` + FileName *string + // List of image data for multiple images. Each element follows the same format + // as file_name. + FileNames []string + // true if a JSON schema is returned instead of a string representation of the + // Hive type. + IsJsonSchema *bool + // internal field used by SDK + Pos *int + ResultType ResultType + // The table schema + Schema []map[string]json.RawMessage + // The summary of the error + Summary *string + // true if partial results are returned. + Truncated *bool +} diff --git a/commandexecution/v2/wire.go b/commandexecution/v2/wire.go new file mode 100755 index 0000000..e87300b --- /dev/null +++ b/commandexecution/v2/wire.go @@ -0,0 +1,186 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package commandexecution + +import ( + "encoding/json" + "fmt" +) + +type cancelCommandRequestWire struct { + ClusterId *string `json:"clusterId,omitempty"` + CommandId *string `json:"commandId,omitempty"` + ContextId *string `json:"contextId,omitempty"` +} + +func cancelCommandRequestToWire(v *CancelCommandRequest) (*cancelCommandRequestWire, error) { + if v == nil { + return nil, nil + } + return &cancelCommandRequestWire{ + ClusterId: v.ClusterId, + CommandId: v.CommandId, + ContextId: v.ContextId, + }, nil +} + +type createContextRequestWire struct { + ClusterId *string `json:"clusterId,omitempty"` + Language Language `json:"language,omitempty"` +} + +func createContextRequestToWire(v *CreateContextRequest) (*createContextRequestWire, error) { + if v == nil { + return nil, nil + } + return &createContextRequestWire{ + ClusterId: v.ClusterId, + Language: v.Language, + }, nil +} + +type createResponseWire struct { + Id *string `json:"id,omitempty"` +} + +func createResponseFromWire(w *createResponseWire) (*CreateResponse, error) { + if w == nil { + return nil, nil + } + return &CreateResponse{ + Id: w.Id, + }, nil +} + +type destroyContextRequestWire struct { + ClusterId *string `json:"clusterId,omitempty"` + ContextId *string `json:"contextId,omitempty"` +} + +func destroyContextRequestToWire(v *DestroyContextRequest) (*destroyContextRequestWire, error) { + if v == nil { + return nil, nil + } + return &destroyContextRequestWire{ + ClusterId: v.ClusterId, + ContextId: v.ContextId, + }, nil +} + +type executeCommandRequestWire struct { + ClusterId *string `json:"clusterId,omitempty"` + ContextId *string `json:"contextId,omitempty"` + Language Language `json:"language,omitempty"` + Command *string `json:"command,omitempty"` +} + +func executeCommandRequestToWire(v *ExecuteCommandRequest) (*executeCommandRequestWire, error) { + if v == nil { + return nil, nil + } + return &executeCommandRequestWire{ + ClusterId: v.ClusterId, + ContextId: v.ContextId, + Language: v.Language, + Command: v.Command, + }, nil +} + +type getCommandStatusRequestWire struct { + ClusterId *string `json:"clusterId,omitempty"` + ContextId *string `json:"contextId,omitempty"` + CommandId *string `json:"commandId,omitempty"` +} + +func getCommandStatusRequestToWire(v *GetCommandStatusRequest) (*getCommandStatusRequestWire, error) { + if v == nil { + return nil, nil + } + return &getCommandStatusRequestWire{ + ClusterId: v.ClusterId, + ContextId: v.ContextId, + CommandId: v.CommandId, + }, nil +} + +type getCommandStatusResponseWire struct { + Id *string `json:"id,omitempty"` + Status CommandStatus `json:"status,omitempty"` + Results *resultsWire `json:"results,omitempty"` +} + +func getCommandStatusResponseFromWire(w *getCommandStatusResponseWire) (*GetCommandStatusResponse, error) { + if w == nil { + return nil, nil + } + resultsPublicValue, err := resultsFromWire(w.Results) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetCommandStatusResponse.Results", err) + } + return &GetCommandStatusResponse{ + Id: w.Id, + Status: w.Status, + Results: resultsPublicValue, + }, nil +} + +type getContextStatusRequestWire struct { + ClusterId *string `json:"clusterId,omitempty"` + ContextId *string `json:"contextId,omitempty"` +} + +func getContextStatusRequestToWire(v *GetContextStatusRequest) (*getContextStatusRequestWire, error) { + if v == nil { + return nil, nil + } + return &getContextStatusRequestWire{ + ClusterId: v.ClusterId, + ContextId: v.ContextId, + }, nil +} + +type getContextStatusResponseWire struct { + Id *string `json:"id,omitempty"` + Status ContextStatus `json:"status,omitempty"` +} + +func getContextStatusResponseFromWire(w *getContextStatusResponseWire) (*GetContextStatusResponse, error) { + if w == nil { + return nil, nil + } + return &GetContextStatusResponse{ + Id: w.Id, + Status: w.Status, + }, nil +} + +type resultsWire struct { + Cause *string `json:"cause,omitempty"` + Data json.RawMessage `json:"data,omitempty"` + FileName *string `json:"fileName,omitempty"` + FileNames []string `json:"fileNames,omitempty"` + IsJsonSchema *bool `json:"isJsonSchema,omitempty"` + Pos *int `json:"pos,omitempty"` + ResultType ResultType `json:"resultType,omitempty"` + Schema []map[string]json.RawMessage `json:"schema,omitempty"` + Summary *string `json:"summary,omitempty"` + Truncated *bool `json:"truncated,omitempty"` +} + +func resultsFromWire(w *resultsWire) (*Results, error) { + if w == nil { + return nil, nil + } + return &Results{ + Cause: w.Cause, + Data: w.Data, + FileName: w.FileName, + FileNames: w.FileNames, + IsJsonSchema: w.IsJsonSchema, + Pos: w.Pos, + ResultType: w.ResultType, + Schema: w.Schema, + Summary: w.Summary, + Truncated: w.Truncated, + }, nil +} diff --git a/core/.package.json b/core/.package.json new file mode 100644 index 0000000..dd25cfd --- /dev/null +++ b/core/.package.json @@ -0,0 +1,3 @@ +{ + "package": "core" +} diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/core/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/core/README.md b/core/README.md index f9e9cf6..1c30d99 100644 --- a/core/README.md +++ b/core/README.md @@ -2,11 +2,6 @@ [![Go Reference](https://pkg.go.dev/badge/github.com/databricks/sdk-go/core.svg)](https://pkg.go.dev/github.com/databricks/sdk-go/core) -> [!WARNING] -> **Preview: not for production use.** This SDK is in active development. APIs are -> experimental and breaking changes may occur at any time. For production use -> cases, use the current [Databricks SDK for Go](https://github.com/databricks/databricks-sdk-go). - Internal core of the [Databricks Modular Go SDK](https://github.com/databricks/sdk-go), providing foundational primitives for error handling, operation execution with retry and rate limiting, configuration profile resolution, and client metadata collection. ## Installation @@ -20,9 +15,10 @@ go get github.com/databricks/sdk-go/core | Package | Description | | --- | --- | | [apierr](https://pkg.go.dev/github.com/databricks/sdk-go/core/apierr) | Transport-agnostic API error types with canonical error codes and structured error details. | -| [clientinfo](https://pkg.go.dev/github.com/databricks/sdk-go/core/clientinfo) | Client and environment metadata for User-Agent headers, with auto-detection of CI/CD providers and runtimes. | +| [clientinfo](https://pkg.go.dev/github.com/databricks/sdk-go/core/clientinfo) | Client metadata for User-Agent headers, with automatic detection of runtimes, CI/CD providers, coding agents, and agent meta-harnesses. | | [ops](https://pkg.go.dev/github.com/databricks/sdk-go/core/ops) | Operation execution with configurable retry, timeout, and rate limiting. | | [profiles](https://pkg.go.dev/github.com/databricks/sdk-go/core/profiles) | Resolution of Databricks configuration profiles from `~/.databrickscfg` files and environment variables. | +| [types](https://pkg.go.dev/github.com/databricks/sdk-go/core/types) | Typed field masks and Protocol Buffer-compatible duration and timestamp values. | ## Go Version Support diff --git a/core/clientinfo/clientinfo.go b/core/clientinfo/clientinfo.go index f3a1a19..ab84c65 100644 --- a/core/clientinfo/clientinfo.go +++ b/core/clientinfo/clientinfo.go @@ -6,7 +6,7 @@ // [ClientInfo.With] derives a new value with additional key/value // segments; it never mutates the original. // -// Databricks tooling (Terraform provider, CLI, partner integrations) +// Databricks tools (Terraform provider, CLI, partner integrations) // should call [SetProduct], [SetPartner], or [AddToDefault] at startup // to register global metadata before any client is created. package clientinfo @@ -119,36 +119,54 @@ func Default() ClientInfo { // abstract environment access for testing. type lookupFunc func(string) (string, bool) +func lookupNonEmpty(lookupEnv lookupFunc, name string) (string, bool) { + value, ok := lookupEnv(name) + return value, ok && value != "" +} + func defaultWithEnv(lookupEnv lookupFunc) ClientInfo { - // 3 fixed + base segments + up to 5 env detection segments. - s := make([]segment, 0, 3+len(base.segments)+5) + // 3 fixed + base segments + up to 6 environment-derived segments. + s := make([]segment, 0, 3+len(base.segments)+6) s = append(s, segment{internal.ModuleName, internal.Version}, segment{"go", cachedGoVersion}, segment{"os", runtime.GOOS}, ) s = append(s, base.segments...) - // DATABRICKS_SDK_UPSTREAM and DATABRICKS_SDK_UPSTREAM_VERSION are set - // by tools built on top of this SDK (e.g. Terraform provider, Pulumi) - // to identify themselves as the upstream product. Both must be present - // for the upstream segment to be included. - if p, ok := lookupEnv("DATABRICKS_SDK_UPSTREAM"); ok { - if v, ok := lookupEnv("DATABRICKS_SDK_UPSTREAM_VERSION"); ok { - s = append(s, segment{"upstream", sanitize(p)}, segment{"upstream-version", sanitize(v)}) - } + if product, version := detectUpstream(lookupEnv); product != "" { + s = append(s, segment{"upstream", product}, segment{"upstream-version", version}) + } + if provider := detectCICD(lookupEnv); provider != "" { + s = append(s, segment{"cicd", provider}) } - if p := detectCICD(lookupEnv); p != "" { - s = append(s, segment{"cicd", p}) + if version := detectRuntimeVersion(lookupEnv); version != "" { + s = append(s, segment{"runtime", version}) } - if v, ok := lookupEnv("DATABRICKS_RUNTIME_VERSION"); ok && v != "" { - s = append(s, segment{"runtime", sanitize(v)}) + if provider := detectAgent(lookupEnv); provider != "" { + s = append(s, segment{"agent", provider}) } - if a := detectAgent(lookupEnv); a != "" { - s = append(s, segment{"agent", a}) + if provider := detectMetaHarness(lookupEnv); provider != "" { + s = append(s, segment{"meta-harness", provider}) } return ClientInfo{segments: s} } +func detectUpstream(lookupEnv lookupFunc) (product, version string) { + upstreamProduct, productSet := lookupNonEmpty(lookupEnv, "DATABRICKS_SDK_UPSTREAM") + upstreamVersion, versionSet := lookupNonEmpty(lookupEnv, "DATABRICKS_SDK_UPSTREAM_VERSION") + if !productSet || !versionSet { + return "", "" + } + return sanitize(upstreamProduct), sanitize(upstreamVersion) +} + +func detectRuntimeVersion(lookupEnv lookupFunc) string { + if value, ok := lookupNonEmpty(lookupEnv, "DATABRICKS_RUNTIME_VERSION"); ok { + return sanitize(value) + } + return "" +} + // SetProduct sets the product name and version globally. The version must // be a valid semver string. // @@ -204,23 +222,31 @@ func sanitize(s string) string { return regexpInvalidSegmentChar.ReplaceAllString(s, "-") } -type agentDef struct { +type environmentProductDef struct { envVar string product string } -var knownAgents = []agentDef{ +var knownAgents = []environmentProductDef{ + {"AMP_CURRENT_THREAD_ID", "amp"}, {"ANTIGRAVITY_AGENT", "antigravity"}, + {"AUGMENT_AGENT", "augment"}, {"CLAUDECODE", "claude-code"}, {"CLINE_ACTIVE", "cline"}, {"CODEX_CI", "codex"}, {"COPILOT_CLI", "copilot-cli"}, {"CURSOR_AGENT", "cursor"}, {"GEMINI_CLI", "gemini-cli"}, - {"OPENCODE", "opencode"}, + {"GOOSE_TERMINAL", "goose"}, + {"KIRO", "kiro"}, {"OPENCLAW_SHELL", "openclaw"}, + {"OPENCODE", "opencode"}, + {"VSCODE_AGENT", "vscode-agent"}, + {"WINDSURF_AGENT", "windsurf"}, } +const maxAgentFallbackLength = 64 + type envCheck struct { name string expectedValue string @@ -244,27 +270,53 @@ var cicdProviders = []cicdDef{ {"tf-cloud", []envCheck{{"TFC_RUN_ID", ""}}}, } -// detectAgent returns the name of a single detected AI coding agent, or -// empty if zero or more than one agent is detected. When multiple agents -// are present (e.g. Claude from within Cursor), we cannot reliably -// determine which one initiated the request, so we omit the segment. -// -// TODO: support reporting multiple concurrent agents. +// detectAgent returns the explicit agent name, "multiple" for stacked +// explicit agents, or the sanitized AGENT/AI_AGENT fallback. func detectAgent(lookupEnv lookupFunc) string { + if agent := detectEnvironmentProduct(lookupEnv, knownAgents); agent != "" { + return agent + } + return detectAgentFallback(lookupEnv) +} + +func detectAgentFallback(lookupEnv lookupFunc) string { + value, ok := lookupNonEmpty(lookupEnv, "AGENT") + if !ok { + value, ok = lookupNonEmpty(lookupEnv, "AI_AGENT") + } + if !ok { + return "" + } + value = sanitize(value) + if len(value) > maxAgentFallbackLength { + value = value[:maxAgentFallbackLength] + } + return value +} + +var knownMetaHarnesses = []environmentProductDef{ + {"OMNIGENT", "omnigent"}, +} + +func detectMetaHarness(lookupEnv lookupFunc) string { + return detectEnvironmentProduct(lookupEnv, knownMetaHarnesses) +} + +func detectEnvironmentProduct(lookupEnv lookupFunc, products []environmentProductDef) string { var detected string count := 0 - for _, a := range knownAgents { - if _, ok := lookupEnv(a.envVar); ok { - detected = a.product + for _, product := range products { + if _, ok := lookupEnv(product.envVar); ok { + detected = product.product count++ - if count > 1 { - break - } } } if count == 1 { return detected } + if count > 1 { + return "multiple" + } return "" } diff --git a/core/clientinfo/clientinfo_test.go b/core/clientinfo/clientinfo_test.go index 91e8e91..cabcd56 100644 --- a/core/clientinfo/clientinfo_test.go +++ b/core/clientinfo/clientinfo_test.go @@ -206,9 +206,24 @@ func TestDefault(t *testing.T) { want: prefix + " agent/claude-code", }, { - desc: "multiple agents omitted", + desc: "multiple agents report the multiple sentinel", env: map[string]string{"CLAUDECODE": "1", "CURSOR_AGENT": "1"}, - want: prefix, + want: prefix + " agent/multiple", + }, + { + desc: "AGENT fallback", + env: map[string]string{"AGENT": "goose"}, + want: prefix + " agent/goose", + }, + { + desc: "AI_AGENT fallback", + env: map[string]string{"AI_AGENT": "cursor"}, + want: prefix + " agent/cursor", + }, + { + desc: "omnigent meta-harness", + env: map[string]string{"OMNIGENT": "1"}, + want: prefix + " meta-harness/omnigent", }, { desc: "databricks runtime", @@ -233,6 +248,30 @@ func TestDefault(t *testing.T) { env: map[string]string{"DATABRICKS_SDK_UPSTREAM": "terraform"}, want: prefix, }, + { + desc: "upstream omitted when product is empty", + env: map[string]string{ + "DATABRICKS_SDK_UPSTREAM": "", + "DATABRICKS_SDK_UPSTREAM_VERSION": "1.5.0", + }, + want: prefix, + }, + { + desc: "upstream omitted when version is empty", + env: map[string]string{ + "DATABRICKS_SDK_UPSTREAM": "terraform", + "DATABRICKS_SDK_UPSTREAM_VERSION": "", + }, + want: prefix, + }, + { + desc: "upstream sanitized when rendered", + env: map[string]string{ + "DATABRICKS_SDK_UPSTREAM": "terraform provider", + "DATABRICKS_SDK_UPSTREAM_VERSION": "1.5.0/dev", + }, + want: prefix + " upstream/terraform-provider upstream-version/1.5.0-dev", + }, { desc: "all env detection combined", env: map[string]string{ @@ -241,8 +280,9 @@ func TestDefault(t *testing.T) { "GITHUB_ACTIONS": "true", "DATABRICKS_RUNTIME_VERSION": "15.5", "CLAUDECODE": "1", + "OMNIGENT": "1", }, - want: prefix + " upstream/terraform upstream-version/1.5.0 cicd/github runtime/15.5 agent/claude-code", + want: prefix + " upstream/terraform upstream-version/1.5.0 cicd/github runtime/15.5 agent/claude-code meta-harness/omnigent", }, } @@ -259,6 +299,180 @@ func TestDefault(t *testing.T) { } } +func TestDetectUpstream(t *testing.T) { + testCases := []struct { + desc string + env map[string]string + wantProduct string + wantVersion string + }{ + {desc: "unset"}, + {desc: "only product", env: map[string]string{"DATABRICKS_SDK_UPSTREAM": "terraform"}}, + {desc: "only version", env: map[string]string{"DATABRICKS_SDK_UPSTREAM_VERSION": "1.5.0"}}, + {desc: "empty product", env: map[string]string{"DATABRICKS_SDK_UPSTREAM": "", "DATABRICKS_SDK_UPSTREAM_VERSION": "1.5.0"}}, + {desc: "empty version", env: map[string]string{"DATABRICKS_SDK_UPSTREAM": "terraform", "DATABRICKS_SDK_UPSTREAM_VERSION": ""}}, + { + desc: "valid values unchanged", + env: map[string]string{ + "DATABRICKS_SDK_UPSTREAM": "terraform-provider", + "DATABRICKS_SDK_UPSTREAM_VERSION": "1.5.0-dev+build.1", + }, + wantProduct: "terraform-provider", + wantVersion: "1.5.0-dev+build.1", + }, + { + desc: "malformed values sanitized", + env: map[string]string{ + "DATABRICKS_SDK_UPSTREAM": "terraform provider/beta", + "DATABRICKS_SDK_UPSTREAM_VERSION": "1.5.0/dev\r\nnext", + }, + wantProduct: "terraform-provider-beta", + wantVersion: "1.5.0-dev--next", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + gotProduct, gotVersion := detectUpstream(mockEnv(tc.env)) + if gotProduct != tc.wantProduct || gotVersion != tc.wantVersion { + t.Errorf("detectUpstream() = (%q, %q), want (%q, %q)", gotProduct, gotVersion, tc.wantProduct, tc.wantVersion) + } + }) + } +} + +func TestDetectAgent(t *testing.T) { + testCases := []struct { + desc string + env map[string]string + want string + }{ + {desc: "no agent", want: ""}, + {desc: "amp", env: map[string]string{"AMP_CURRENT_THREAD_ID": "thread"}, want: "amp"}, + {desc: "antigravity", env: map[string]string{"ANTIGRAVITY_AGENT": "1"}, want: "antigravity"}, + {desc: "augment", env: map[string]string{"AUGMENT_AGENT": "1"}, want: "augment"}, + {desc: "claude code", env: map[string]string{"CLAUDECODE": "1"}, want: "claude-code"}, + {desc: "cline", env: map[string]string{"CLINE_ACTIVE": "1"}, want: "cline"}, + {desc: "codex", env: map[string]string{"CODEX_CI": "1"}, want: "codex"}, + {desc: "copilot CLI", env: map[string]string{"COPILOT_CLI": "1"}, want: "copilot-cli"}, + {desc: "cursor", env: map[string]string{"CURSOR_AGENT": "1"}, want: "cursor"}, + {desc: "gemini CLI", env: map[string]string{"GEMINI_CLI": "1"}, want: "gemini-cli"}, + {desc: "goose", env: map[string]string{"GOOSE_TERMINAL": "1"}, want: "goose"}, + {desc: "kiro", env: map[string]string{"KIRO": "1"}, want: "kiro"}, + {desc: "openclaw", env: map[string]string{"OPENCLAW_SHELL": "1"}, want: "openclaw"}, + {desc: "opencode", env: map[string]string{"OPENCODE": "1"}, want: "opencode"}, + {desc: "VS Code agent", env: map[string]string{"VSCODE_AGENT": "1"}, want: "vscode-agent"}, + {desc: "windsurf", env: map[string]string{"WINDSURF_AGENT": "1"}, want: "windsurf"}, + {desc: "empty explicit value counts", env: map[string]string{"CLAUDECODE": ""}, want: "claude-code"}, + {desc: "multiple explicit agents", env: map[string]string{"CLAUDECODE": "1", "CURSOR_AGENT": "1"}, want: "multiple"}, + {desc: "AGENT fallback", env: map[string]string{"AGENT": "goose"}, want: "goose"}, + {desc: "AGENT sanitized", env: map[string]string{"AGENT": "claude code/agent"}, want: "claude-code-agent"}, + {desc: "AGENT length capped", env: map[string]string{"AGENT": strings.Repeat("a", 100)}, want: strings.Repeat("a", 64)}, + {desc: "empty AGENT falls through", env: map[string]string{"AGENT": "", "AI_AGENT": "cursor"}, want: "cursor"}, + {desc: "AGENT wins over AI_AGENT", env: map[string]string{"AGENT": "claude-code", "AI_AGENT": "cursor"}, want: "claude-code"}, + {desc: "explicit matcher wins over fallback", env: map[string]string{"CLAUDECODE": "1", "AGENT": "goose"}, want: "claude-code"}, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + if got := detectAgent(mockEnv(tc.env)); got != tc.want { + t.Errorf("detectAgent() = %q, want %q", got, tc.want) + } + }) + } +} + +func TestDetectRuntime(t *testing.T) { + testCases := []struct { + desc string + env map[string]string + want string + }{ + {desc: "unset", want: ""}, + {desc: "empty", env: map[string]string{"DATABRICKS_RUNTIME_VERSION": ""}, want: ""}, + {desc: "version", env: map[string]string{"DATABRICKS_RUNTIME_VERSION": "15.5"}, want: "15.5"}, + {desc: "sanitized", env: map[string]string{"DATABRICKS_RUNTIME_VERSION": "15.5 beta/2"}, want: "15.5-beta-2"}, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + if got := detectRuntimeVersion(mockEnv(tc.env)); got != tc.want { + t.Errorf("detectRuntimeVersion() = %q, want %q", got, tc.want) + } + }) + } +} + +func TestDetectCICD(t *testing.T) { + testCases := []struct { + desc string + env map[string]string + want string + }{ + {desc: "unset", want: ""}, + {desc: "github", env: map[string]string{"GITHUB_ACTIONS": "true"}, want: "github"}, + {desc: "gitlab", env: map[string]string{"GITLAB_CI": "true"}, want: "gitlab"}, + {desc: "jenkins", env: map[string]string{"JENKINS_URL": ""}, want: "jenkins"}, + {desc: "azure devops", env: map[string]string{"TF_BUILD": "True"}, want: "azure-devops"}, + {desc: "circle", env: map[string]string{"CIRCLECI": "true"}, want: "circle"}, + {desc: "travis", env: map[string]string{"TRAVIS": "true"}, want: "travis"}, + {desc: "bitbucket", env: map[string]string{"BITBUCKET_BUILD_NUMBER": ""}, want: "bitbucket"}, + {desc: "google cloud build", env: map[string]string{"PROJECT_ID": "project", "BUILD_ID": "build", "PROJECT_NUMBER": "123", "LOCATION": "us-central1"}, want: "google-cloud-build"}, + {desc: "aws codebuild", env: map[string]string{"CODEBUILD_BUILD_ARN": ""}, want: "aws-code-build"}, + {desc: "terraform cloud", env: map[string]string{"TFC_RUN_ID": ""}, want: "tf-cloud"}, + {desc: "github exact value", env: map[string]string{"GITHUB_ACTIONS": "True"}, want: ""}, + {desc: "gitlab exact value", env: map[string]string{"GITLAB_CI": "1"}, want: ""}, + {desc: "azure devops exact value", env: map[string]string{"TF_BUILD": "true"}, want: ""}, + {desc: "circle exact value", env: map[string]string{"CIRCLECI": "1"}, want: ""}, + {desc: "travis exact value", env: map[string]string{"TRAVIS": "1"}, want: ""}, + {desc: "google cloud build missing project", env: map[string]string{"BUILD_ID": "build", "PROJECT_NUMBER": "123", "LOCATION": "us-central1"}, want: ""}, + {desc: "google cloud build missing build", env: map[string]string{"PROJECT_ID": "project", "PROJECT_NUMBER": "123", "LOCATION": "us-central1"}, want: ""}, + {desc: "google cloud build missing project number", env: map[string]string{"PROJECT_ID": "project", "BUILD_ID": "build", "LOCATION": "us-central1"}, want: ""}, + {desc: "google cloud build missing location", env: map[string]string{"PROJECT_ID": "project", "BUILD_ID": "build", "PROJECT_NUMBER": "123"}, want: ""}, + {desc: "first match wins", env: map[string]string{"GITHUB_ACTIONS": "true", "GITLAB_CI": "true"}, want: "github"}, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + if got := detectCICD(mockEnv(tc.env)); got != tc.want { + t.Errorf("detectCICD() = %q, want %q", got, tc.want) + } + }) + } +} + +func TestDetectMetaHarness(t *testing.T) { + testCases := []struct { + desc string + env map[string]string + want string + }{ + {desc: "unset", want: ""}, + {desc: "present", env: map[string]string{"OMNIGENT": "1"}, want: "omnigent"}, + {desc: "empty value counts", env: map[string]string{"OMNIGENT": ""}, want: "omnigent"}, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + if got := detectMetaHarness(mockEnv(tc.env)); got != tc.want { + t.Errorf("detectMetaHarness() = %q, want %q", got, tc.want) + } + }) + } +} + +func TestDetectMetaHarness_multiple(t *testing.T) { + metaHarnesses := []environmentProductDef{ + {envVar: "FIRST_HARNESS", product: "first"}, + {envVar: "SECOND_HARNESS", product: "second"}, + } + env := mockEnv(map[string]string{"FIRST_HARNESS": "1", "SECOND_HARNESS": "1"}) + + if got, want := detectEnvironmentProduct(env, metaHarnesses), "multiple"; got != want { + t.Errorf("detectEnvironmentProduct() = %q, want %q", got, want) + } +} + func TestSetProduct(t *testing.T) { testCases := []struct { desc string diff --git a/core/internal/version.go b/core/internal/version.go index a2aa75d..cd601bf 100644 --- a/core/internal/version.go +++ b/core/internal/version.go @@ -2,4 +2,4 @@ package internal const ModuleName = "sdk-go-core" -const Version = "0.0.1-dev" +const Version = "0.0.1-dev.1" diff --git a/core/ops/ops.go b/core/ops/ops.go index c978545..a3b245b 100644 --- a/core/ops/ops.go +++ b/core/ops/ops.go @@ -9,7 +9,8 @@ import ( "time" ) -// Execute executes operation op with the given options. +// Execute executes operation op with the given options. The operation is +// expected to honor cancellation and deadlines on the context passed to it. func Execute(ctx context.Context, op func(context.Context) error, opts ...Option) error { options := Options{} for _, opt := range opts { diff --git a/core/types/doc.go b/core/types/doc.go new file mode 100644 index 0000000..c2e8871 --- /dev/null +++ b/core/types/doc.go @@ -0,0 +1,4 @@ +// Package types provides values used by generated Databricks SDK models, +// including typed field masks and Protocol Buffer-compatible timestamps and +// durations. +package types diff --git a/core/types/duration.go b/core/types/duration.go new file mode 100644 index 0000000..f708430 --- /dev/null +++ b/core/types/duration.go @@ -0,0 +1,281 @@ +package types + +import ( + "encoding/json" + "fmt" + "math" + "strconv" + "strings" + "time" +) + +const ( + // MaxDurationSeconds is the largest valid Duration seconds value, inclusive. + MaxDurationSeconds = int64(315_576_000_000) + // MinDurationSeconds is the smallest valid Duration seconds value, inclusive. + MinDurationSeconds = -MaxDurationSeconds + // MaxDurationNanos is the largest valid Duration nanoseconds value, inclusive. + MaxDurationNanos = int32(999_999_999) + // MinDurationNanos is the smallest valid Duration nanoseconds value, inclusive. + MinDurationNanos = -MaxDurationNanos + + nanosecondsPerSecond = int64(time.Second) +) + +// Duration is a signed, fixed-length span of time with nanosecond precision. +// It models the google.protobuf.Duration well-known type without the range +// loss of [time.Duration]. +// +// The zero value represents a duration of zero. Seconds must be between +// -315,576,000,000 and +315,576,000,000, inclusive. Nanos must be between +// -999,999,999 and +999,999,999, inclusive, and must have the same sign as +// Seconds when both are non-zero. [Duration.CheckValid] checks these invariants. +// +// Its representation, range, and normalization rules follow the +// [google.protobuf.Duration definition]. +// +// [google.protobuf.Duration definition]: https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/duration.proto +type Duration struct { + // Seconds is the signed whole-second component. + Seconds int64 + // Nanos is the signed fractional-second component in nanoseconds. + Nanos int32 +} + +// NewFromDuration constructs a valid Duration from a standard-library duration. +func NewFromDuration(duration time.Duration) *Duration { + nanos := duration.Nanoseconds() + seconds := nanos / nanosecondsPerSecond + nanos -= seconds * nanosecondsPerSecond + return &Duration{Seconds: seconds, Nanos: int32(nanos)} +} + +// AsDuration converts d to a standard-library duration. It returns the nearest +// [time.Duration] boundary when d is outside the standard library's range. A +// nil receiver converts to zero. +func (d *Duration) AsDuration() time.Duration { + if d == nil { + return 0 + } + const ( + minSeconds = int64(math.MinInt64 / nanosecondsPerSecond) + maxSeconds = int64(math.MaxInt64 / nanosecondsPerSecond) + minNanos = int32(math.MinInt64 - minSeconds*nanosecondsPerSecond) + maxNanos = int32(math.MaxInt64 - maxSeconds*nanosecondsPerSecond) + ) + nanos := int64(d.Nanos) + secondsCarry := nanos / nanosecondsPerSecond + if secondsCarry > 0 && d.Seconds > math.MaxInt64-secondsCarry { + return time.Duration(math.MaxInt64) + } + if secondsCarry < 0 && d.Seconds < math.MinInt64-secondsCarry { + return time.Duration(math.MinInt64) + } + seconds := d.Seconds + secondsCarry + nanos %= nanosecondsPerSecond + if seconds < minSeconds || seconds == minSeconds && nanos < int64(minNanos) { + return time.Duration(math.MinInt64) + } + if seconds > maxSeconds || seconds == maxSeconds && nanos > int64(maxNanos) { + return time.Duration(math.MaxInt64) + } + return time.Duration(seconds*nanosecondsPerSecond + nanos) +} + +// Add returns the sum of d and other with the nanoseconds normalized. Add +// expects each non-nil operand to satisfy [Duration.CheckValid] and does not +// validate either operand. It does not clamp the result to the Duration range; +// callers can continue arithmetic and use CheckValid on the final result. Add +// returns nil when d is nil. A nil other is treated as zero. +func (d *Duration) Add(other *Duration) *Duration { + if d == nil { + return nil + } + if other == nil { + return &Duration{Seconds: d.Seconds, Nanos: d.Nanos} + } + result := normalizeDuration(d.Seconds+other.Seconds, int64(d.Nanos)+int64(other.Nanos)) + return &result +} + +func normalizeDuration(seconds, nanos int64) Duration { + seconds += nanos / nanosecondsPerSecond + nanos %= nanosecondsPerSecond + if seconds > 0 && nanos < 0 { + seconds-- + nanos += nanosecondsPerSecond + } else if seconds < 0 && nanos > 0 { + seconds++ + nanos -= nanosecondsPerSecond + } + return Duration{Seconds: seconds, Nanos: int32(nanos)} +} + +func formatDuration(d *Duration) string { + negative := d.Seconds < 0 || d.Nanos < 0 + seconds := d.Seconds + nanos := int64(d.Nanos) + if seconds < 0 { + seconds = -seconds + } + if nanos < 0 { + nanos = -nanos + } + out := strconv.FormatInt(seconds, 10) + if nanos != 0 { + fraction := fmt.Sprintf("%09d", nanos) + switch { + case fraction[3:] == "000000": + fraction = fraction[:3] + case fraction[6:] == "000": + fraction = fraction[:6] + } + out += "." + fraction + } + if negative { + out = "-" + out + } + return out + "s" +} + +// String returns a formatted representation of d as signed seconds with an +// "s" suffix. It returns "" for a nil receiver. Invalid field +// combinations are rendered as their component values. +func (d *Duration) String() string { + if d == nil { + return "" + } + if err := d.CheckValid(); err != nil { + return fmt.Sprintf("Duration{Seconds: %d, Nanos: %d}", d.Seconds, d.Nanos) + } + return formatDuration(d) +} + +// MarshalJSON encodes d as a ProtoJSON Duration, using zero, three, six, +// or nine fractional digits as needed to represent its nanoseconds exactly. +// It returns an error when d does not satisfy [Duration.CheckValid]. +// +// See the [ProtoJSON well-known type mapping]. +// +// [ProtoJSON well-known type mapping]: https://protobuf.dev/programming-guides/json/#format-description +func (d Duration) MarshalJSON() ([]byte, error) { + if err := d.CheckValid(); err != nil { + return nil, err + } + return json.Marshal(formatDuration(&d)) +} + +// UnmarshalJSON decodes the SDK's accepted subset of ProtoJSON Duration inputs. +// It accepts the form +// -?(0|[1-9][0-9]*)(\.[0-9]{1,9})?s. It intentionally rejects non-canonical +// extensions such as a leading plus sign or a missing digit on either side of +// the decimal point. The JSON value must be a string; null is rejected. If +// decoding fails, d is unchanged. +// +// See the [ProtoJSON well-known type mapping]. +// +// [ProtoJSON well-known type mapping]: https://protobuf.dev/programming-guides/json/#format-description +func (d *Duration) UnmarshalJSON(data []byte) error { + var value string + if err := json.Unmarshal(data, &value); err != nil { + return err + } + seconds, nanos, err := parseDuration(value) + if err != nil { + return fmt.Errorf("parse duration %q: %w", value, err) + } + parsed := Duration{Seconds: seconds, Nanos: nanos} + if err := parsed.CheckValid(); err != nil { + return fmt.Errorf("parse duration %q: %w", value, err) + } + *d = parsed + return nil +} + +// parseDuration parses the protobuf JSON Duration form: +// +// -?(0|[1-9][0-9]*)(\.[0-9]{1,9})?s +// +// Whole seconds are required. A decimal point must be followed by one to nine +// fractional digits. Leading plus signs, leading zeroes, and a missing "s" +// suffix are rejected. +func parseDuration(input string) (int64, int32, error) { + if len(input) < 2 || input[len(input)-1] != 's' { + return 0, 0, fmt.Errorf("value must end with %q", "s") + } + value := input[:len(input)-1] + + negative := false + if value[0] == '-' { + negative = true + value = value[1:] + } + if len(value) == 0 { + return 0, 0, fmt.Errorf("value must contain seconds") + } + + integerEnd := strings.IndexByte(value, '.') + if integerEnd < 0 { + integerEnd = len(value) + } + integerPart := value[:integerEnd] + if len(integerPart) == 0 || len(integerPart) > 1 && integerPart[0] == '0' { + return 0, 0, fmt.Errorf("seconds must be zero or start with a non-zero digit") + } + for _, digit := range integerPart { + if digit < '0' || digit > '9' { + return 0, 0, fmt.Errorf("seconds must contain only decimal digits") + } + } + + fraction := "" + if integerEnd < len(value) { + fraction = value[integerEnd+1:] + if len(fraction) == 0 || len(fraction) > 9 { + return 0, 0, fmt.Errorf("fraction must contain between 1 and 9 digits") + } + for _, digit := range fraction { + if digit < '0' || digit > '9' { + return 0, 0, fmt.Errorf("fraction must contain only decimal digits") + } + } + } + + seconds, err := strconv.ParseInt(integerPart, 10, 64) + if err != nil { + return 0, 0, fmt.Errorf("parse seconds: %w", err) + } + + var nanos int64 + if fraction != "" { + fraction += strings.Repeat("0", 9-len(fraction)) + nanos, err = strconv.ParseInt(fraction, 10, 32) + if err != nil { + return 0, 0, fmt.Errorf("parse fraction: %w", err) + } + } + + if negative { + seconds = -seconds + nanos = -nanos + } + return seconds, int32(nanos), nil +} + +// CheckValid returns an error unless d satisfies the Protocol Buffers Duration +// range and normalization rules. A nil Duration is invalid. +func (d *Duration) CheckValid() error { + if d == nil { + return fmt.Errorf("invalid nil Duration") + } + if d.Seconds < MinDurationSeconds || d.Seconds > MaxDurationSeconds { + return fmt.Errorf("duration seconds %d outside protobuf range", d.Seconds) + } + if d.Nanos < MinDurationNanos || d.Nanos > MaxDurationNanos { + return fmt.Errorf("duration nanoseconds %d outside protobuf range", d.Nanos) + } + if d.Seconds > 0 && d.Nanos < 0 || d.Seconds < 0 && d.Nanos > 0 { + return fmt.Errorf("duration seconds and nanoseconds have different signs") + } + return nil +} diff --git a/core/types/duration_test.go b/core/types/duration_test.go new file mode 100644 index 0000000..7a82817 --- /dev/null +++ b/core/types/duration_test.go @@ -0,0 +1,301 @@ +package types_test + +import ( + "encoding/json" + "math" + "testing" + "time" + + "github.com/databricks/sdk-go/core/types" + "github.com/google/go-cmp/cmp" +) + +func TestDuration_MarshalJSON_usesCanonicalFractionWidth(t *testing.T) { + testCases := []struct { + name string + value types.Duration + json string + }{ + {name: "zero", value: types.Duration{}, json: `"0s"`}, + {name: "positive fractional", value: types.Duration{Seconds: 12, Nanos: 345_000_000}, json: `"12.345s"`}, + {name: "microsecond precision", value: types.Duration{Seconds: 12, Nanos: 345_678_000}, json: `"12.345678s"`}, + {name: "nanosecond precision", value: types.Duration{Seconds: 12, Nanos: 345_678_901}, json: `"12.345678901s"`}, + {name: "millisecond precision uses three digits", value: types.Duration{Nanos: 1_000_000}, json: `"0.001s"`}, + {name: "microsecond precision uses six digits", value: types.Duration{Nanos: 1_000}, json: `"0.000001s"`}, + {name: "nanosecond precision uses nine digits", value: types.Duration{Nanos: 1}, json: `"0.000000001s"`}, + {name: "negative subsecond", value: types.Duration{Nanos: -500_000_000}, json: `"-0.500s"`}, + {name: "negative seconds and nanos", value: types.Duration{Seconds: -12, Nanos: -345_000_000}, json: `"-12.345s"`}, + {name: "protobuf maximum", value: types.Duration{Seconds: types.MaxDurationSeconds, Nanos: types.MaxDurationNanos}, json: `"315576000000.999999999s"`}, + {name: "protobuf minimum", value: types.Duration{Seconds: types.MinDurationSeconds, Nanos: types.MinDurationNanos}, json: `"-315576000000.999999999s"`}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + encoded, err := json.Marshal(tc.value) + if err != nil { + t.Fatalf("Marshal() error = %v", err) + } + if got := string(encoded); got != tc.json { + t.Errorf("Marshal() = %q, want %q", got, tc.json) + } + + }) + } +} + +func TestDuration_String(t *testing.T) { + testCases := []struct { + name string + value *types.Duration + want string + }{ + {name: "nil", want: ""}, + {name: "zero", value: &types.Duration{}, want: "0s"}, + {name: "whole seconds", value: &types.Duration{Seconds: 90}, want: "90s"}, + {name: "fractional", value: &types.Duration{Seconds: -12, Nanos: -345_000_000}, want: "-12.345s"}, + {name: "invalid", value: &types.Duration{Seconds: 1, Nanos: -1}, want: "Duration{Seconds: 1, Nanos: -1}"}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if got := tc.value.String(); got != tc.want { + t.Errorf("String() = %q, want %q", got, tc.want) + } + }) + } +} + +func TestDuration_JSONRoundTrip(t *testing.T) { + testCases := []types.Duration{ + {}, + {Seconds: 12}, + {Seconds: 12, Nanos: 345_678_901}, + {Seconds: -12, Nanos: -345_678_901}, + {Nanos: 1}, + {Nanos: -1}, + {Seconds: types.MaxDurationSeconds, Nanos: types.MaxDurationNanos}, + {Seconds: types.MinDurationSeconds, Nanos: types.MinDurationNanos}, + } + for _, want := range testCases { + encoded, err := json.Marshal(want) + if err != nil { + t.Fatalf("Marshal(%+v) error = %v", want, err) + } + var got types.Duration + if err := json.Unmarshal(encoded, &got); err != nil { + t.Fatalf("Unmarshal(%s) error = %v", encoded, err) + } + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("round trip mismatch (-want +got):\n%s", diff) + } + } +} + +func TestDuration_UnmarshalJSON_acceptsFixedPointSeconds(t *testing.T) { + testCases := []struct { + input string + want types.Duration + }{ + {input: `"1s"`, want: types.Duration{Seconds: 1}}, + {input: `"-0s"`, want: types.Duration{}}, + {input: `"0.1s"`, want: types.Duration{Nanos: 100_000_000}}, + {input: `"0.12s"`, want: types.Duration{Nanos: 120_000_000}}, + {input: `"0.123s"`, want: types.Duration{Nanos: 123_000_000}}, + {input: `"0.1234s"`, want: types.Duration{Nanos: 123_400_000}}, + {input: `"0.12345s"`, want: types.Duration{Nanos: 123_450_000}}, + {input: `"0.123456s"`, want: types.Duration{Nanos: 123_456_000}}, + {input: `"0.1234567s"`, want: types.Duration{Nanos: 123_456_700}}, + {input: `"0.12345678s"`, want: types.Duration{Nanos: 123_456_780}}, + {input: `"-1s"`, want: types.Duration{Seconds: -1}}, + {input: `"-0.1s"`, want: types.Duration{Nanos: -100_000_000}}, + {input: `"0.00000001s"`, want: types.Duration{Nanos: 10}}, + {input: `"1.123456789s"`, want: types.Duration{Seconds: 1, Nanos: 123_456_789}}, + {input: `"315576000000.999999999s"`, want: types.Duration{Seconds: types.MaxDurationSeconds, Nanos: types.MaxDurationNanos}}, + {input: `"-315576000000.999999999s"`, want: types.Duration{Seconds: types.MinDurationSeconds, Nanos: types.MinDurationNanos}}, + } + for _, tc := range testCases { + t.Run(tc.input, func(t *testing.T) { + var got types.Duration + if err := json.Unmarshal([]byte(tc.input), &got); err != nil { + t.Fatalf("Unmarshal(%s) error = %v", tc.input, err) + } + if diff := cmp.Diff(tc.want, got); diff != "" { + t.Errorf("Unmarshal(%s) mismatch (-want +got):\n%s", tc.input, diff) + } + }) + } +} + +func TestDuration_UnmarshalJSON_rejectsInvalidValues(t *testing.T) { + testCases := []string{ + `""`, + `"a"`, + `"-s"`, + `"s"`, + `"1"`, + `"1S"`, + `"+1s"`, + `".1s"`, + `"-.1s"`, + `"1.s"`, + `"01s"`, + `"1,1s"`, + `"1e3s"`, + `" 1s"`, + `"1.1234567890s"`, + `"1.as"`, + `"1.2.3s"`, + `"315576000001s"`, + `"-315576000001s"`, + `"--1s"`, + `1`, + `null`, + } + for _, input := range testCases { + t.Run(input, func(t *testing.T) { + got := types.Duration{Seconds: 7, Nanos: 8} + if err := json.Unmarshal([]byte(input), &got); err == nil { + t.Fatalf("Unmarshal(%s) error = nil", input) + } + if got != (types.Duration{Seconds: 7, Nanos: 8}) { + t.Errorf("Unmarshal(%s) modified receiver to %+v", input, got) + } + }) + } +} + +func TestDuration_TimeConversion(t *testing.T) { + var nilDuration *types.Duration + if got := nilDuration.AsDuration(); got != 0 { + t.Errorf("nil.AsDuration() = %v, want zero", got) + } + + testCases := []time.Duration{ + 0, + 2*time.Hour + 3*time.Millisecond, + -2*time.Hour - 3*time.Millisecond, + time.Duration(1<<63 - 1), + time.Duration(-1 << 63), + } + for _, want := range testCases { + if got := types.NewFromDuration(want).AsDuration(); got != want { + t.Errorf("NewFromDuration(%v).AsDuration() = %v", want, got) + } + } + + const nanosPerSecond = int64(time.Second) + maxSeconds := int64(math.MaxInt64 / nanosPerSecond) + maxNanos := int32(math.MaxInt64 - maxSeconds*nanosPerSecond) + minSeconds := int64(math.MinInt64 / nanosPerSecond) + minNanos := int32(math.MinInt64 - minSeconds*nanosPerSecond) + clampCases := []struct { + name string + value types.Duration + want time.Duration + }{ + {name: "maximum exact", value: types.Duration{Seconds: maxSeconds, Nanos: maxNanos}, want: time.Duration(math.MaxInt64)}, + {name: "one above maximum", value: types.Duration{Seconds: maxSeconds, Nanos: maxNanos + 1}, want: time.Duration(math.MaxInt64)}, + {name: "minimum exact", value: types.Duration{Seconds: minSeconds, Nanos: minNanos}, want: time.Duration(math.MinInt64)}, + {name: "one below minimum", value: types.Duration{Seconds: minSeconds, Nanos: minNanos - 1}, want: time.Duration(math.MinInt64)}, + {name: "invalid nanos overflow below boundary second", value: types.Duration{Seconds: maxSeconds - 1, Nanos: math.MaxInt32}, want: time.Duration(math.MaxInt64)}, + {name: "invalid nanos underflow above boundary second", value: types.Duration{Seconds: minSeconds + 1, Nanos: math.MinInt32}, want: time.Duration(math.MinInt64)}, + {name: "protobuf maximum", value: types.Duration{Seconds: types.MaxDurationSeconds, Nanos: types.MaxDurationNanos}, want: time.Duration(math.MaxInt64)}, + {name: "protobuf minimum", value: types.Duration{Seconds: types.MinDurationSeconds, Nanos: types.MinDurationNanos}, want: time.Duration(math.MinInt64)}, + {name: "arbitrary maximum fields", value: types.Duration{Seconds: math.MaxInt64, Nanos: math.MaxInt32}, want: time.Duration(math.MaxInt64)}, + {name: "arbitrary minimum fields", value: types.Duration{Seconds: math.MinInt64, Nanos: math.MinInt32}, want: time.Duration(math.MinInt64)}, + } + for _, tc := range clampCases { + t.Run(tc.name, func(t *testing.T) { + if got := tc.value.AsDuration(); got != tc.want { + t.Errorf("AsDuration() = %v, want %v", got, tc.want) + } + }) + } +} + +func TestDuration_Add_normalizesWithoutClamping(t *testing.T) { + testCases := []struct { + name string + left *types.Duration + right *types.Duration + want *types.Duration + valid bool + }{ + {name: "zero", left: &types.Duration{}, right: &types.Duration{}, want: &types.Duration{}, valid: true}, + {name: "carry", left: &types.Duration{Seconds: 10, Nanos: 900_000_000}, right: &types.Duration{Nanos: 200_000_000}, want: &types.Duration{Seconds: 11, Nanos: 100_000_000}, valid: true}, + {name: "positive borrow", left: &types.Duration{Seconds: 10, Nanos: 100_000_000}, right: &types.Duration{Nanos: -200_000_000}, want: &types.Duration{Seconds: 9, Nanos: 900_000_000}, valid: true}, + {name: "negative borrow", left: &types.Duration{Seconds: -10, Nanos: -100_000_000}, right: &types.Duration{Nanos: 200_000_000}, want: &types.Duration{Seconds: -9, Nanos: -900_000_000}, valid: true}, + {name: "cancel", left: &types.Duration{Seconds: 10, Nanos: 100}, right: &types.Duration{Seconds: -10, Nanos: -100}, want: &types.Duration{}, valid: true}, + {name: "maximum plus one nanosecond", left: &types.Duration{Seconds: types.MaxDurationSeconds, Nanos: types.MaxDurationNanos}, right: &types.Duration{Nanos: 1}, want: &types.Duration{Seconds: types.MaxDurationSeconds + 1}, valid: false}, + {name: "minimum minus one nanosecond", left: &types.Duration{Seconds: types.MinDurationSeconds, Nanos: types.MinDurationNanos}, right: &types.Duration{Nanos: -1}, want: &types.Duration{Seconds: types.MinDurationSeconds - 1}, valid: false}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + left, right := *tc.left, *tc.right + got := tc.left.Add(tc.right) + if diff := cmp.Diff(tc.want, got); diff != "" { + t.Errorf("Add() mismatch (-want +got):\n%s", diff) + } + if (got.CheckValid() == nil) != tc.valid { + t.Errorf("Add().CheckValid() valid = %t, want %t", got.CheckValid() == nil, tc.valid) + } + if *tc.left != left || *tc.right != right { + t.Error("Add() modified an operand") + } + }) + } +} + +func TestDuration_Add_nil(t *testing.T) { + var duration *types.Duration + if got := duration.Add(&types.Duration{Seconds: 1}); got != nil { + t.Errorf("nil.Add() = %+v, want nil", got) + } + + duration = &types.Duration{Seconds: 1, Nanos: 2} + got := duration.Add(nil) + if got == duration || *got != *duration { + t.Errorf("Add(nil) = %+v, want an equal copy", got) + } +} + +func TestDuration_MarshalJSON_rejectsInvalidValue(t *testing.T) { + for _, value := range []types.Duration{ + {Seconds: types.MaxDurationSeconds + 1}, + {Seconds: types.MinDurationSeconds - 1}, + {Nanos: types.MaxDurationNanos + 1}, + {Nanos: types.MinDurationNanos - 1}, + {Seconds: 1, Nanos: -1}, + {Seconds: -1, Nanos: 1}, + } { + if _, err := json.Marshal(value); err == nil { + t.Errorf("Marshal(%+v) error = nil", value) + } + } +} + +func TestDuration_CheckValid(t *testing.T) { + testCases := []struct { + name string + value *types.Duration + valid bool + }{ + {name: "nil", value: nil}, + {name: "zero", value: &types.Duration{}, valid: true}, + {name: "maximum", value: &types.Duration{Seconds: types.MaxDurationSeconds, Nanos: types.MaxDurationNanos}, valid: true}, + {name: "minimum", value: &types.Duration{Seconds: types.MinDurationSeconds, Nanos: types.MinDurationNanos}, valid: true}, + {name: "seconds overflow", value: &types.Duration{Seconds: types.MaxDurationSeconds + 1}}, + {name: "seconds underflow", value: &types.Duration{Seconds: types.MinDurationSeconds - 1}}, + {name: "nanos overflow", value: &types.Duration{Nanos: types.MaxDurationNanos + 1}}, + {name: "nanos underflow", value: &types.Duration{Nanos: types.MinDurationNanos - 1}}, + {name: "positive seconds negative nanos", value: &types.Duration{Seconds: 1, Nanos: -1}}, + {name: "negative seconds positive nanos", value: &types.Duration{Seconds: -1, Nanos: 1}}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.value.CheckValid() + if (err == nil) != tc.valid { + t.Errorf("CheckValid() error = %v, valid = %t", err, tc.valid) + } + }) + } +} diff --git a/core/types/example_test.go b/core/types/example_test.go new file mode 100644 index 0000000..d08b3ae --- /dev/null +++ b/core/types/example_test.go @@ -0,0 +1,53 @@ +package types_test + +import ( + "fmt" + "time" + + "github.com/databricks/sdk-go/core/types" +) + +func ExampleNewFromDuration() { + requestTimeout := types.NewFromDuration(15 * time.Minute) + fmt.Println(requestTimeout) + // Output: + // 900s +} + +func ExampleNewFromTime() { + requestStartTime := types.NewFromTime(time.Date( + 2024, time.January, 15, 11, 30, 0, 0, + time.FixedZone("UTC+1", 60*60), + )) + fmt.Println(requestStartTime) + // Output: + // 2024-01-15T10:30:00Z +} + +func ExampleTime_Add() { + createdAt := types.NewFromTime(time.Date(2024, time.January, 15, 10, 30, 0, 0, time.UTC)) + ttl := &types.Duration{Seconds: 3_600, Nanos: 500_000_000} + expiresAt := createdAt.Add(ttl) + + fmt.Println(expiresAt) + // Output: + // 2024-01-15T11:30:00.500Z +} + +func ExampleTime_comparisonUsingStandardLibrary() { + updatedAt := types.NewFromTime(time.Date(2024, time.January, 15, 10, 30, 0, 0, time.UTC)) + expiresAt := types.NewFromTime(time.Date(2024, time.January, 15, 11, 30, 0, 0, time.UTC)) + + fmt.Println(updatedAt.AsTime().Before(expiresAt.AsTime())) + // Output: + // true +} + +func ExampleTime_elapsedUsingStandardLibrary() { + startedAt := types.NewFromTime(time.Date(2024, time.January, 15, 10, 30, 0, 0, time.UTC)) + finishedAt := types.NewFromTime(time.Date(2024, time.January, 15, 10, 32, 30, 0, time.UTC)) + + fmt.Println(finishedAt.AsTime().Sub(startedAt.AsTime())) + // Output: + // 2m30s +} diff --git a/core/types/fieldmask.go b/core/types/fieldmask.go new file mode 100644 index 0000000..1ad0a98 --- /dev/null +++ b/core/types/fieldmask.go @@ -0,0 +1,57 @@ +package types + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" +) + +// FieldMask represents normalized wire paths for fields of T. T is expected to +// be a generated SDK model. Custom types that reproduce the generator's +// reflection metadata may work but are not supported. +type FieldMask[T any] struct { + value string +} + +// NewFieldMask validates paths against the fields of T and returns their +// sorted, deduplicated, and parent-subsumed representation. The path "*" +// represents full replacement and subsumes all other valid paths. +func NewFieldMask[T any](paths ...string) (*FieldMask[T], error) { + if err := validateFieldMaskPaths(reflect.TypeFor[T](), paths); err != nil { + return nil, err + } + return &FieldMask[T]{value: normalizeFieldMaskPaths(paths)}, nil +} + +// String returns the normalized wire paths separated by commas. +func (m FieldMask[T]) String() string { + return m.value +} + +// MarshalJSON encodes the normalized field mask as a JSON string. +func (m FieldMask[T]) MarshalJSON() ([]byte, error) { + return json.Marshal(m.value) +} + +// UnmarshalJSON decodes and validates a comma-separated field mask without +// changing the receiver when validation fails. +func (m *FieldMask[T]) UnmarshalJSON(data []byte) error { + if m == nil { + return fmt.Errorf("cannot unmarshal a field mask into a nil receiver") + } + var value string + if err := json.Unmarshal(data, &value); err != nil { + return err + } + var paths []string + if value != "" { + paths = strings.Split(value, ",") + } + parsed, err := NewFieldMask[T](paths...) + if err != nil { + return err + } + m.value = parsed.value + return nil +} diff --git a/core/types/fieldmask_path.go b/core/types/fieldmask_path.go new file mode 100644 index 0000000..b8d3c9d --- /dev/null +++ b/core/types/fieldmask_path.go @@ -0,0 +1,23 @@ +package types + +import ( + "slices" + "strings" +) + +func normalizeFieldMaskPaths(paths []string) string { + if slices.Contains(paths, "*") { + return "*" + } + paths = slices.Clone(paths) + slices.Sort(paths) + paths = slices.Compact(paths) + normalized := paths[:0] + for _, path := range paths { + if len(normalized) > 0 && strings.HasPrefix(path, normalized[len(normalized)-1]+".") { + continue + } + normalized = append(normalized, path) + } + return strings.Join(normalized, ",") +} diff --git a/core/types/fieldmask_test.go b/core/types/fieldmask_test.go new file mode 100644 index 0000000..445dbb3 --- /dev/null +++ b/core/types/fieldmask_test.go @@ -0,0 +1,170 @@ +package types_test + +import ( + "encoding/json" + "testing" + + "github.com/databricks/sdk-go/core/types" +) + +type fieldMaskPrintedEdition struct { + Printer *string `fieldmask:"printer"` +} + +type fieldMaskBookEdition interface { + fieldMaskBookEdition() +} + +type fieldMaskBookEditionPrintedEdition struct { + PrintedEdition fieldMaskPrintedEdition `fieldmask:"printed_edition"` +} + +func (*fieldMaskBookEditionPrintedEdition) fieldMaskBookEdition() {} + +type fieldMaskBookEditionDigitalURI struct { + DigitalURI string `fieldmask:"digital_uri"` +} + +func (*fieldMaskBookEditionDigitalURI) fieldMaskBookEdition() {} + +type fieldMaskBookEditionMetadata struct { + *fieldMaskBookEditionPrintedEdition + *fieldMaskBookEditionDigitalURI +} + +type fieldMaskBook struct { + Title *string `fieldmask:"title"` + RelatedBook *fieldMaskBook `fieldmask:"related_book"` + Labels []string `fieldmask:"labels"` + Attributes map[string]string `fieldmask:"attributes"` + PublishedAt *types.Time `fieldmask:"published_at"` + ReadingTime *types.Duration `fieldmask:"reading_time"` + Details json.RawMessage `fieldmask:"details"` + Values []json.RawMessage `fieldmask:"values"` + Properties map[string]json.RawMessage `fieldmask:"properties"` + LegacyName *string `fieldmask:"legacyName"` + Edition fieldMaskBookEdition + _ [0]fieldMaskBookEditionMetadata `fieldmask_oneof:"Edition"` +} + +func TestNewFieldMask(t *testing.T) { + testCases := []struct { + name string + paths []string + want string + wantErr bool + }{ + {name: "empty", want: ""}, + {name: "flat", paths: []string{"title"}, want: "title"}, + {name: "nested oneof message", paths: []string{"printed_edition.printer"}, want: "printed_edition.printer"}, + {name: "recursive", paths: []string{"related_book.related_book.title"}, want: "related_book.related_book.title"}, + {name: "oneof scalar", paths: []string{"digital_uri"}, want: "digital_uri"}, + {name: "collections as terminals", paths: []string{"labels", "attributes"}, want: "attributes,labels"}, + { + name: "well-known JSON terminals", + paths: []string{"values", "reading_time", "properties", "published_at", "details"}, + want: "details,properties,published_at,reading_time,values", + }, + {name: "non-snake wire name", paths: []string{"legacyName"}, want: "legacyName"}, + { + name: "sort deduplicate and subsume children", + paths: []string{"title", "printed_edition.printer", "printed_edition", "title"}, + want: "printed_edition,title", + }, + {name: "empty path", paths: []string{""}, wantErr: true}, + {name: "missing field", paths: []string{"missing"}, wantErr: true}, + {name: "Go field name", paths: []string{"RelatedBook"}, wantErr: true}, + {name: "wildcard", paths: []string{"*"}, want: "*"}, + { + name: "wildcard subsumes other paths", + paths: []string{"title", "*", "printed_edition.printer"}, + want: "*", + }, + {name: "bare oneof group", paths: []string{"edition"}, wantErr: true}, + {name: "oneof group prefix", paths: []string{"edition.printed_edition"}, wantErr: true}, + {name: "scalar traversal", paths: []string{"title.value"}, wantErr: true}, + {name: "array traversal", paths: []string{"labels.value"}, wantErr: true}, + {name: "map traversal", paths: []string{"attributes.value"}, wantErr: true}, + { + name: "validate before parent subsumption", + paths: []string{"printed_edition", "printed_edition.missing"}, + wantErr: true, + }, + { + name: "validate before wildcard subsumption", + paths: []string{"*", "missing"}, + wantErr: true, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + mask, err := types.NewFieldMask[fieldMaskBook](testCase.paths...) + if testCase.wantErr { + if err == nil { + t.Fatal("NewFieldMask() returned nil error") + } + return + } + if err != nil { + t.Fatalf("NewFieldMask() returned error: %v", err) + } + if got := mask.String(); got != testCase.want { + t.Errorf("String() = %q, want %q", got, testCase.want) + } + }) + } +} + +func TestFieldMask_JSONRoundTrip(t *testing.T) { + mask, err := types.NewFieldMask[fieldMaskBook]("title", "printed_edition.printer", "legacyName") + if err != nil { + t.Fatalf("NewFieldMask() returned error: %v", err) + } + data, err := json.Marshal(mask) + if err != nil { + t.Fatalf("json.Marshal() returned error: %v", err) + } + if got, want := string(data), `"legacyName,printed_edition.printer,title"`; got != want { + t.Errorf("json.Marshal() = %s, want %s", got, want) + } + + var got types.FieldMask[fieldMaskBook] + if err := json.Unmarshal(data, &got); err != nil { + t.Fatalf("json.Unmarshal() returned error: %v", err) + } + if got.String() != mask.String() { + t.Errorf("round trip String() = %q, want %q", got.String(), mask.String()) + } +} + +func TestFieldMask_UnmarshalJSON_zeroValueAndNilPointer(t *testing.T) { + var value types.FieldMask[fieldMaskBook] + if err := json.Unmarshal([]byte(`"title,printed_edition.printer"`), &value); err != nil { + t.Fatalf("json.Unmarshal() into zero value returned error: %v", err) + } + if got, want := value.String(), "printed_edition.printer,title"; got != want { + t.Errorf("zero value String() = %q, want %q", got, want) + } + + var pointer *types.FieldMask[fieldMaskBook] + if err := json.Unmarshal([]byte(`"title"`), &pointer); err != nil { + t.Fatalf("json.Unmarshal() into nil pointer returned error: %v", err) + } + if pointer == nil || pointer.String() != "title" { + t.Errorf("nil pointer unmarshal = %#v, want mask %q", pointer, "title") + } +} + +func TestFieldMask_UnmarshalJSON_preservesReceiverOnFailure(t *testing.T) { + mask, err := types.NewFieldMask[fieldMaskBook]("title") + if err != nil { + t.Fatalf("NewFieldMask() returned error: %v", err) + } + if err := json.Unmarshal([]byte(`"missing"`), mask); err == nil { + t.Fatal("json.Unmarshal() returned nil error") + } + if got := mask.String(); got != "title" { + t.Errorf("String() after failed unmarshal = %q, want %q", got, "title") + } +} diff --git a/core/types/fieldmask_validation.go b/core/types/fieldmask_validation.go new file mode 100644 index 0000000..3de30c6 --- /dev/null +++ b/core/types/fieldmask_validation.go @@ -0,0 +1,124 @@ +package types + +import ( + "fmt" + "reflect" + "strings" +) + +func validateFieldMaskPaths(root reflect.Type, paths []string) error { + if root.Kind() != reflect.Struct { + return fmt.Errorf("field mask root %s must be a struct", root) + } + for _, path := range paths { + if err := validateFieldMaskPath(root, path); err != nil { + return fmt.Errorf("invalid field mask path %q: %w", path, err) + } + } + return nil +} + +func validateFieldMaskPath(root reflect.Type, path string) error { + if path == "" { + return fmt.Errorf("path is empty") + } + if path == "*" { + return nil + } + current := root + segments := strings.Split(path, ".") + for i, segment := range segments { + if segment == "*" { + return fmt.Errorf("wildcard %q must be the entire path", segment) + } + field, ok := findFieldMaskField(current, segment) + if !ok { + return fmt.Errorf("field %q does not exist", segment) + } + if i < len(segments)-1 { + child, ok := fieldMaskMessageType(field.Type) + if !ok { + return fmt.Errorf("field %q may only appear at the end of a path", segment) + } + current = child + } + } + return nil +} + +func findFieldMaskField(root reflect.Type, path string) (reflect.StructField, bool) { + for i := range root.NumField() { + field := root.Field(i) + fieldPath, hasFieldPath := field.Tag.Lookup("fieldmask") + oneofGroup, hasOneofGroup := field.Tag.Lookup("fieldmask_oneof") + switch { + case hasFieldPath && hasOneofGroup: + continue + case hasFieldPath: + if field.PkgPath == "" && fieldPath == path { + return field, true + } + case hasOneofGroup: + if oneofGroup == "" { + continue + } + if field, ok := findFieldMaskOneofField(root, field, oneofGroup, path); ok { + return field, true + } + } + } + return reflect.StructField{}, false +} + +func findFieldMaskOneofField(root reflect.Type, carrier reflect.StructField, group, path string) (reflect.StructField, bool) { + if carrier.Name != "_" || carrier.Type.Kind() != reflect.Array || carrier.Type.Len() != 0 { + return reflect.StructField{}, false + } + oneofField, ok := root.FieldByName(group) + if !ok || oneofField.PkgPath != "" || oneofField.Type.Kind() != reflect.Interface { + return reflect.StructField{}, false + } + + metadataType := carrier.Type.Elem() + if metadataType.Kind() != reflect.Struct || metadataType.NumField() == 0 { + return reflect.StructField{}, false + } + for i := range metadataType.NumField() { + embedded := metadataType.Field(i) + if !embedded.Anonymous { + continue + } + wrapperType := embedded.Type + if wrapperType.Kind() == reflect.Pointer { + wrapperType = wrapperType.Elem() + } + if wrapperType.Kind() != reflect.Struct || wrapperType.NumField() != 1 { + continue + } + payload := wrapperType.Field(0) + fieldPath, ok := payload.Tag.Lookup("fieldmask") + if ok && payload.PkgPath == "" && fieldPath == path { + return payload, true + } + } + return reflect.StructField{}, false +} + +func fieldMaskMessageType(typ reflect.Type) (reflect.Type, bool) { + for typ.Kind() == reflect.Pointer { + typ = typ.Elem() + } + if typ.Kind() != reflect.Struct { + return nil, false + } + for i := range typ.NumField() { + field := typ.Field(i) + if _, ok := field.Tag.Lookup("fieldmask"); ok { + return typ, true + } + if _, ok := field.Tag.Lookup("fieldmask_oneof"); ok { + return typ, true + } + } + return nil, false +} diff --git a/core/types/fieldmask_validation_test.go b/core/types/fieldmask_validation_test.go new file mode 100644 index 0000000..2446592 --- /dev/null +++ b/core/types/fieldmask_validation_test.go @@ -0,0 +1,294 @@ +package types + +import ( + "fmt" + "reflect" + "testing" +) + +type fieldMaskRecursiveTestModel struct { + Related *fieldMaskRecursiveTestModel `fieldmask:"related"` + Title string `fieldmask:"title"` +} + +type fieldMaskOneofTest interface { + fieldMaskOneofTest() +} + +type fieldMaskPrintedEditionTest struct { + Printer string `fieldmask:"printer"` +} + +type fieldMaskEditionPrintedTest struct { + PrintedEdition fieldMaskPrintedEditionTest `fieldmask:"printed_edition"` +} + +func (*fieldMaskEditionPrintedTest) fieldMaskOneofTest() {} + +type fieldMaskEditionDigitalTest struct { + DigitalURI string `fieldmask:"digital_uri"` +} + +func (*fieldMaskEditionDigitalTest) fieldMaskOneofTest() {} + +type fieldMaskEditionMetadataTest struct { + *fieldMaskEditionPrintedTest + *fieldMaskEditionDigitalTest +} + +type fieldMaskUntaggedWrapperTest struct { + Value string +} + +func (*fieldMaskUntaggedWrapperTest) fieldMaskOneofTest() {} + +type fieldMaskMalformedWrapperTest struct { + First string `fieldmask:"first"` + Second string `fieldmask:"second"` +} + +func (*fieldMaskMalformedWrapperTest) fieldMaskOneofTest() {} + +type fieldMaskPartialEditionMetadataTest struct { + *fieldMaskEditionPrintedTest + *fieldMaskUntaggedWrapperTest + *fieldMaskMalformedWrapperTest +} + +func TestValidateFieldMaskPaths(t *testing.T) { + pointerRoot := reflect.TypeOf(&struct{}{}) + testCases := []struct { + name string + root reflect.Type + paths []string + wantErr string + }{ + { + name: "empty", + root: reflect.TypeOf(struct{}{}), + }, + { + name: "flat", + root: reflect.TypeOf(struct { + Name string `fieldmask:"name"` + }{}), + paths: []string{"name"}, + }, + { + name: "nested", + root: reflect.TypeOf(struct { + Child *struct { + Name string `fieldmask:"name"` + } `fieldmask:"child"` + }{}), + paths: []string{"child.name"}, + }, + { + name: "recursive", + root: reflect.TypeFor[fieldMaskRecursiveTestModel](), + paths: []string{"related.related.title"}, + }, + { + name: "oneof", + root: reflect.TypeOf(struct { + Edition fieldMaskOneofTest + _ [0]fieldMaskEditionMetadataTest `fieldmask_oneof:"Edition"` + }{}), + paths: []string{"printed_edition.printer", "digital_uri"}, + }, + { + name: "terminal fields", + root: reflect.TypeOf(struct { + Scalar string `fieldmask:"scalar"` + Array []string `fieldmask:"array"` + Map map[string]string `fieldmask:"map"` + Custom struct { + Value string + } `fieldmask:"custom"` + }{}), + paths: []string{"scalar", "array", "map", "custom"}, + }, + { + name: "non-snake tag", + root: reflect.TypeOf(struct { + Legacy string `fieldmask:"legacyName"` + }{}), + paths: []string{"legacyName"}, + }, + { + name: "duplicate tag keeps first field", + root: reflect.TypeOf(struct { + First string `fieldmask:"duplicate"` + Second struct { + Child string `fieldmask:"child"` + } `fieldmask:"duplicate"` + }{}), + paths: []string{"duplicate.child"}, + wantErr: `invalid field mask path "duplicate.child": field "duplicate" may only appear at the end of a path`, + }, + { + name: "missing field tag", + root: reflect.TypeOf(struct { + Name string `fieldmask:"name"` + Added string + }{}), + paths: []string{"added"}, + wantErr: `invalid field mask path "added": field "added" does not exist`, + }, + { + name: "field with conflicting metadata tags", + root: reflect.TypeOf(struct { + Choice fieldMaskOneofTest + Field string `fieldmask:"field" fieldmask_oneof:"Choice"` + }{}), + paths: []string{"field"}, + wantErr: `invalid field mask path "field": field "field" does not exist`, + }, + { + name: "malformed oneof carrier", + root: reflect.TypeOf(struct { + Edition fieldMaskOneofTest + Metadata [0]fieldMaskEditionMetadataTest `fieldmask_oneof:"Edition"` + }{}), + paths: []string{"digital_uri"}, + wantErr: `invalid field mask path "digital_uri": field "digital_uri" does not exist`, + }, + { + name: "oneof carrier references non-interface field", + root: reflect.TypeOf(struct { + Edition string + _ [0]fieldMaskEditionMetadataTest `fieldmask_oneof:"Edition"` + }{}), + paths: []string{"digital_uri"}, + wantErr: `invalid field mask path "digital_uri": field "digital_uri" does not exist`, + }, + { + name: "malformed oneof wrappers", + root: reflect.TypeOf(struct { + Edition fieldMaskOneofTest + _ [0]struct { + *fieldMaskUntaggedWrapperTest + *fieldMaskMalformedWrapperTest + } `fieldmask_oneof:"Edition"` + }{}), + paths: []string{"value"}, + wantErr: `invalid field mask path "value": field "value" does not exist`, + }, + { + name: "partially usable oneof", + root: reflect.TypeOf(struct { + Edition fieldMaskOneofTest + _ [0]fieldMaskPartialEditionMetadataTest `fieldmask_oneof:"Edition"` + }{}), + paths: []string{"printed_edition.printer"}, + }, + { + name: "partially usable oneof omits malformed wrapper", + root: reflect.TypeOf(struct { + Edition fieldMaskOneofTest + _ [0]fieldMaskPartialEditionMetadataTest `fieldmask_oneof:"Edition"` + }{}), + paths: []string{"value"}, + wantErr: `invalid field mask path "value": field "value" does not exist`, + }, + { + name: "wildcard", + root: reflect.TypeOf(struct { + Name string `fieldmask:"name"` + }{}), + paths: []string{"*"}, + }, + { + name: "wildcard path segment", + root: reflect.TypeOf(struct { + Child struct { + Name string `fieldmask:"name"` + } `fieldmask:"child"` + }{}), + paths: []string{"child.*"}, + wantErr: `invalid field mask path "child.*": wildcard "*" must be the entire path`, + }, + { + name: "missing field", + root: reflect.TypeOf(struct { + Name string `fieldmask:"name"` + }{}), + paths: []string{"missing"}, + wantErr: `invalid field mask path "missing": field "missing" does not exist`, + }, + { + name: "scalar traversal", + root: reflect.TypeOf(struct { + Scalar string `fieldmask:"scalar"` + }{}), + paths: []string{"scalar.child"}, + wantErr: `invalid field mask path "scalar.child": field "scalar" may only appear at the end of a path`, + }, + { + name: "array traversal", + root: reflect.TypeOf(struct { + Array []struct { + Child string `fieldmask:"child"` + } `fieldmask:"array"` + }{}), + paths: []string{"array.child"}, + wantErr: `invalid field mask path "array.child": field "array" may only appear at the end of a path`, + }, + { + name: "map traversal", + root: reflect.TypeOf(struct { + Map map[string]struct { + Child string `fieldmask:"child"` + } `fieldmask:"map"` + }{}), + paths: []string{"map.child"}, + wantErr: `invalid field mask path "map.child": field "map" may only appear at the end of a path`, + }, + { + name: "untagged struct traversal", + root: reflect.TypeOf(struct { + Custom struct { + Child string + } `fieldmask:"custom"` + }{}), + paths: []string{"custom.child"}, + wantErr: `invalid field mask path "custom.child": field "custom" may only appear at the end of a path`, + }, + { + name: "empty path", + root: reflect.TypeOf(struct { + Name string `fieldmask:"name"` + }{}), + paths: []string{""}, + wantErr: `invalid field mask path "": path is empty`, + }, + { + name: "non-struct root without paths", + root: reflect.TypeFor[string](), + wantErr: "field mask root string must be a struct", + }, + { + name: "pointer root without paths", + root: pointerRoot, + wantErr: fmt.Sprintf("field mask root %s must be a struct", pointerRoot), + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + err := validateFieldMaskPaths(testCase.root, testCase.paths) + if testCase.wantErr == "" { + if err != nil { + t.Fatalf("validateFieldMaskPaths() returned error: %v", err) + } + return + } + if err == nil { + t.Fatal("validateFieldMaskPaths() returned nil error") + } + if got := err.Error(); got != testCase.wantErr { + t.Errorf("validateFieldMaskPaths() error = %q, want %q", got, testCase.wantErr) + } + }) + } +} diff --git a/core/types/time.go b/core/types/time.go new file mode 100644 index 0000000..2061cba --- /dev/null +++ b/core/types/time.go @@ -0,0 +1,205 @@ +package types + +import ( + "encoding/json" + "fmt" + "strings" + "time" +) + +const ( + // MinTimestampSeconds is 0001-01-01T00:00:00Z in Unix seconds, the + // smallest valid Time seconds value. + MinTimestampSeconds = int64(-62_135_596_800) + // MaxTimestampSeconds is 9999-12-31T23:59:59Z in Unix seconds, the + // largest valid Time seconds value. + MaxTimestampSeconds = int64(253_402_300_799) +) + +// Time is an instant with nanosecond precision. It models the +// google.protobuf.Timestamp well-known type. +// +// The zero value represents the Unix epoch, 1970-01-01T00:00:00Z. Seconds is +// limited to instants from 0001-01-01T00:00:00Z through +// 9999-12-31T23:59:59Z, inclusive. Nanos must be between 0 and 999,999,999, +// inclusive. [Time.CheckValid] checks these invariants. +// +// Its representation and range follow the [google.protobuf.Timestamp definition]. +// +// [google.protobuf.Timestamp definition]: https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/timestamp.proto +type Time struct { + // Seconds is the number of whole seconds since the Unix epoch. + Seconds int64 + // Nanos is the non-negative fractional-second component in nanoseconds. + Nanos int32 +} + +// NewFromTime constructs a Time from a standard-library time. Go can represent +// years outside the Protocol Buffers Timestamp range, so callers converting +// such values must use [Time.CheckValid] before sending them to an API. +func NewFromTime(value time.Time) *Time { + return &Time{Seconds: value.Unix(), Nanos: int32(value.Nanosecond())} +} + +// AsTime converts t to a standard-library time in UTC. It uses [time.Unix] +// normalization for invalid field combinations rather than validating them. A +// nil receiver converts to the Unix epoch. +func (t *Time) AsTime() time.Time { + if t == nil { + return time.Unix(0, 0).UTC() + } + return time.Unix(t.Seconds, int64(t.Nanos)).UTC() +} + +// Add returns t with d added and the nanoseconds normalized. Add expects each +// non-nil operand to satisfy its CheckValid method and does not validate either +// operand. It does not clamp the result to the Time range; callers can continue +// arithmetic and use [Time.CheckValid] on the final result. Add returns nil +// when t is nil. A nil d is treated as zero. +func (t *Time) Add(d *Duration) *Time { + if t == nil { + return nil + } + if d == nil { + return &Time{Seconds: t.Seconds, Nanos: t.Nanos} + } + result := normalizeTime(t.Seconds+d.Seconds, int64(t.Nanos)+int64(d.Nanos)) + return &result +} + +func formatTime(t *Time) string { + formatted := t.AsTime().Format("2006-01-02T15:04:05.000000000") + formatted = strings.TrimSuffix(formatted, "000") + formatted = strings.TrimSuffix(formatted, "000") + formatted = strings.TrimSuffix(formatted, ".000") + return formatted + "Z" +} + +// String returns an RFC 3339 representation of t in UTC. It returns "" +// for a nil receiver. Invalid field combinations are rendered as their +// component values. +func (t *Time) String() string { + if t == nil { + return "" + } + if err := t.CheckValid(); err != nil { + return fmt.Sprintf("Time{Seconds: %d, Nanos: %d}", t.Seconds, t.Nanos) + } + return formatTime(t) +} + +// MarshalJSON encodes t as a ProtoJSON Timestamp in UTC with a Z suffix, +// using zero, three, six, or nine fractional digits as needed to represent its +// nanoseconds exactly. It returns an error when t does not satisfy +// [Time.CheckValid]. +// +// See the [ProtoJSON well-known type mapping]. +// +// [ProtoJSON well-known type mapping]: https://protobuf.dev/programming-guides/json/#format-description +func (t Time) MarshalJSON() ([]byte, error) { + if err := t.CheckValid(); err != nil { + return nil, err + } + return json.Marshal(formatTime(&t)) +} + +// UnmarshalJSON decodes a ProtoJSON Timestamp. It accepts UTC or numeric +// timezone offsets and between zero and nine fractional digits. In accordance +// with the protobuf Timestamp JSON form, fractional seconds use a period; the +// comma separator permitted by the broader RFC 3339 grammar is rejected. The +// JSON value must be a string; null is rejected. If decoding fails, t is +// unchanged. +// +// See the [ProtoJSON well-known type mapping]. +// +// [ProtoJSON well-known type mapping]: https://protobuf.dev/programming-guides/json/#format-description +func (t *Time) UnmarshalJSON(data []byte) error { + var value string + if err := json.Unmarshal(data, &value); err != nil { + return err + } + if err := validateTimestampSyntax(value); err != nil { + return fmt.Errorf("parse timestamp %q: %w", value, err) + } + parsed, err := time.Parse(time.RFC3339Nano, value) + if err != nil { + return fmt.Errorf("parse timestamp %q: %w", value, err) + } + result := NewFromTime(parsed) + if err := result.CheckValid(); err != nil { + return fmt.Errorf("parse timestamp %q: %w", value, err) + } + *t = *result + return nil +} + +func validateTimestampSyntax(value string) error { + if len(value) < len("0001-01-01T00:00:00Z") || + value[4] != '-' || value[7] != '-' || value[10] != 'T' || + value[13] != ':' || value[16] != ':' { + return fmt.Errorf("value must have the form YYYY-MM-DDTHH:MM:SS[.fffffffff](Z|+HH:MM|-HH:MM)") + } + for _, index := range []int{0, 1, 2, 3, 5, 6, 8, 9, 11, 12, 14, 15, 17, 18} { + if value[index] < '0' || value[index] > '9' { + return fmt.Errorf("date and time components must contain only decimal digits") + } + } + + rest := value[19:] + if len(rest) > 0 && rest[0] == '.' { + rest = rest[1:] + digits := 0 + for digits < len(rest) && rest[digits] >= '0' && rest[digits] <= '9' { + digits++ + } + if digits == 0 || digits > 9 { + return fmt.Errorf("fraction must contain between 1 and 9 digits") + } + rest = rest[digits:] + } + if rest == "Z" { + return nil + } + if len(rest) != 6 || rest[0] != '+' && rest[0] != '-' || rest[3] != ':' { + return fmt.Errorf("timezone must be Z or a numeric offset in the form +HH:MM or -HH:MM") + } + for _, index := range []int{1, 2, 4, 5} { + if rest[index] < '0' || rest[index] > '9' { + return fmt.Errorf("timezone offset must contain only decimal digits") + } + } + hours := int(rest[1]-'0')*10 + int(rest[2]-'0') + minutes := int(rest[4]-'0')*10 + int(rest[5]-'0') + if hours > 23 || minutes > 59 { + return fmt.Errorf("timezone offset is outside the RFC 3339 range") + } + return nil +} + +// CheckValid returns an error unless t satisfies the Protocol Buffers +// Timestamp range and normalization rules. A nil Time is invalid. +func (t *Time) CheckValid() error { + if t == nil { + return fmt.Errorf("invalid nil Time") + } + if t.Seconds < MinTimestampSeconds { + return fmt.Errorf("timestamp seconds %d before 0001-01-01", t.Seconds) + } + if t.Seconds > MaxTimestampSeconds { + return fmt.Errorf("timestamp seconds %d after 9999-12-31", t.Seconds) + } + if t.Nanos < 0 || t.Nanos >= int32(time.Second) { + return fmt.Errorf("timestamp nanoseconds %d outside protobuf range", t.Nanos) + } + return nil +} + +func normalizeTime(seconds, nanos int64) Time { + seconds += nanos / nanosecondsPerSecond + nanos %= nanosecondsPerSecond + if nanos < 0 { + seconds-- + nanos += nanosecondsPerSecond + } + return Time{Seconds: seconds, Nanos: int32(nanos)} +} diff --git a/core/types/time_test.go b/core/types/time_test.go new file mode 100644 index 0000000..44d83c3 --- /dev/null +++ b/core/types/time_test.go @@ -0,0 +1,230 @@ +package types_test + +import ( + "encoding/json" + "testing" + "time" + + "github.com/databricks/sdk-go/core/types" + "github.com/google/go-cmp/cmp" +) + +func TestTime_JSONRoundTrip(t *testing.T) { + testCases := []struct { + name string + value *types.Time + json string + }{ + {name: "whole second", value: &types.Time{Seconds: 1_705_315_800}, json: `"2024-01-15T10:50:00Z"`}, + {name: "millisecond precision", value: &types.Time{Seconds: 1_705_315_800, Nanos: 123_000_000}, json: `"2024-01-15T10:50:00.123Z"`}, + {name: "microsecond precision", value: &types.Time{Seconds: 1_705_315_800, Nanos: 123_456_000}, json: `"2024-01-15T10:50:00.123456Z"`}, + {name: "nanosecond precision", value: &types.Time{Seconds: 1_705_315_800, Nanos: 123_456_789}, json: `"2024-01-15T10:50:00.123456789Z"`}, + {name: "minimum", value: &types.Time{Seconds: types.MinTimestampSeconds}, json: `"0001-01-01T00:00:00Z"`}, + {name: "maximum", value: &types.Time{Seconds: types.MaxTimestampSeconds, Nanos: 999_999_999}, json: `"9999-12-31T23:59:59.999999999Z"`}, + {name: "fractional pre epoch", value: &types.Time{Seconds: -1, Nanos: 500_000_000}, json: `"1969-12-31T23:59:59.500Z"`}, + {name: "one nanosecond", value: &types.Time{Nanos: 1}, json: `"1970-01-01T00:00:00.000000001Z"`}, + {name: "one microsecond", value: &types.Time{Nanos: 1_000}, json: `"1970-01-01T00:00:00.000001Z"`}, + {name: "millisecond plus nanosecond", value: &types.Time{Nanos: 1_000_001}, json: `"1970-01-01T00:00:00.001000001Z"`}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + encoded, err := json.Marshal(tc.value) + if err != nil { + t.Fatalf("Marshal() error = %v", err) + } + if got := string(encoded); got != tc.json { + t.Errorf("Marshal() = %q, want %q", got, tc.json) + } + + var got types.Time + if err := json.Unmarshal(encoded, &got); err != nil { + t.Fatalf("Unmarshal() error = %v", err) + } + if diff := cmp.Diff(tc.value, &got); diff != "" { + t.Errorf("round trip mismatch (-want +got):\n%s", diff) + } + }) + } +} + +func TestTime_String(t *testing.T) { + testCases := []struct { + name string + value *types.Time + want string + }{ + {name: "nil", want: ""}, + {name: "zero", value: &types.Time{}, want: "1970-01-01T00:00:00Z"}, + {name: "fractional", value: &types.Time{Seconds: -1, Nanos: 500_000_000}, want: "1969-12-31T23:59:59.500Z"}, + {name: "invalid", value: &types.Time{Nanos: -1}, want: "Time{Seconds: 0, Nanos: -1}"}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if got := tc.value.String(); got != tc.want { + t.Errorf("String() = %q, want %q", got, tc.want) + } + }) + } +} + +func TestTime_UnmarshalJSON_acceptsRFC3339(t *testing.T) { + testCases := []struct { + input string + want *types.Time + }{ + {input: `"2024-01-15T11:50:00.123+01:00"`, want: &types.Time{Seconds: 1_705_315_800, Nanos: 123_000_000}}, + {input: `"1970-01-01T23:59:00+23:59"`, want: &types.Time{}}, + {input: `"1969-12-31T00:01:00-23:59"`, want: &types.Time{}}, + {input: `"1970-01-01T00:00:00.1Z"`, want: &types.Time{Nanos: 100_000_000}}, + {input: `"2000-02-29T00:00:00Z"`, want: &types.Time{Seconds: 951_782_400}}, + {input: `"1970-01-01T00:00:00.000000001Z"`, want: &types.Time{Nanos: 1}}, + } + for _, tc := range testCases { + t.Run(tc.input, func(t *testing.T) { + var got types.Time + if err := json.Unmarshal([]byte(tc.input), &got); err != nil { + t.Fatalf("Unmarshal() error = %v", err) + } + if diff := cmp.Diff(tc.want, &got); diff != "" { + t.Errorf("Unmarshal() mismatch (-want +got):\n%s", diff) + } + }) + } +} + +func TestTime_StandardLibraryConversionAndAdd(t *testing.T) { + stdlib := time.Date(2024, 1, 15, 10, 30, 0, 0, time.FixedZone("offset", 3600)) + custom := types.NewFromTime(stdlib) + if got := custom.AsTime(); !got.Equal(stdlib) { + t.Errorf("AsTime() = %v, want instant %v", got, stdlib) + } + + got := custom.Add(&types.Duration{Seconds: 3_600, Nanos: 500_000_000}) + want := types.NewFromTime(stdlib.Add(time.Hour + 500*time.Millisecond)) + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("Add() mismatch (-want +got):\n%s", diff) + } +} + +func TestTime_nilBehavior(t *testing.T) { + var value *types.Time + if got := value.AsTime(); !got.Equal(time.Unix(0, 0)) { + t.Errorf("nil.AsTime() = %v, want Unix epoch", got) + } + if got := value.Add(&types.Duration{Seconds: 1}); got != nil { + t.Errorf("nil.Add() = %+v, want nil", got) + } + + value = &types.Time{Seconds: 1, Nanos: 2} + got := value.Add(nil) + if got == value || *got != *value { + t.Errorf("Add(nil) = %+v, want an equal copy", got) + } +} + +func TestTime_Add_normalizesWithoutClamping(t *testing.T) { + testCases := []struct { + name string + time *types.Time + duration *types.Duration + want *types.Time + valid bool + }{ + {name: "carry", time: &types.Time{Seconds: 10, Nanos: 900_000_000}, duration: &types.Duration{Nanos: 200_000_000}, want: &types.Time{Seconds: 11, Nanos: 100_000_000}, valid: true}, + {name: "borrow", time: &types.Time{Seconds: 10, Nanos: 100_000_000}, duration: &types.Duration{Nanos: -200_000_000}, want: &types.Time{Seconds: 9, Nanos: 900_000_000}, valid: true}, + {name: "maximum plus one nanosecond", time: &types.Time{Seconds: types.MaxTimestampSeconds, Nanos: 999_999_999}, duration: &types.Duration{Nanos: 1}, want: &types.Time{Seconds: types.MaxTimestampSeconds + 1}, valid: false}, + {name: "minimum minus one nanosecond", time: &types.Time{Seconds: types.MinTimestampSeconds}, duration: &types.Duration{Nanos: -1}, want: &types.Time{Seconds: types.MinTimestampSeconds - 1, Nanos: 999_999_999}, valid: false}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + originalTime, originalDuration := *tc.time, *tc.duration + got := tc.time.Add(tc.duration) + if diff := cmp.Diff(tc.want, got); diff != "" { + t.Errorf("Add() mismatch (-want +got):\n%s", diff) + } + if (*got).CheckValid() == nil != tc.valid { + t.Errorf("Add().CheckValid() valid = %t, want %t", got.CheckValid() == nil, tc.valid) + } + if *tc.time != originalTime || *tc.duration != originalDuration { + t.Error("Add() modified an operand") + } + if !tc.valid { + if _, err := json.Marshal(got); err == nil { + t.Error("Marshal(Add()) error = nil for out-of-range result") + } + } + }) + } +} + +func TestTime_UnmarshalJSON_rejectsInvalidValue(t *testing.T) { + testCases := []string{ + `"not-a-time"`, + `"2024-01-15T10:50:00Z "`, + `"2024-01-15t10:50:00Z"`, + `"2024-01-15T10:50:00z"`, + `"2024-01-15T10:50:00"`, + `"2024-01-15T10:50:00.Z"`, + `"2024-01-15T10:50:00,1Z"`, + `"2024-01-15T10:50:00.1234567890Z"`, + `"2024-01-15T10:50:00+24:00"`, + `"2024-01-15T10:50:00+23:60"`, + `"2023-02-29T00:00:00Z"`, + `"1900-02-29T00:00:00Z"`, + `"2024-01-15T10:50:60Z"`, + `"0000-01-01T00:00:00Z"`, + `"0001-01-01T00:00:00+00:01"`, + `"9999-12-31T23:59:59-00:01"`, + `1`, + `null`, + } + for _, input := range testCases { + t.Run(input, func(t *testing.T) { + got := types.Time{Seconds: 7, Nanos: 8} + if err := json.Unmarshal([]byte(input), &got); err == nil { + t.Fatalf("Unmarshal(%s) error = nil", input) + } + if got != (types.Time{Seconds: 7, Nanos: 8}) { + t.Errorf("Unmarshal(%s) modified receiver to %+v", input, got) + } + }) + } +} + +func TestTime_MarshalJSON_rejectsInvalidValue(t *testing.T) { + for _, value := range []types.Time{ + {Seconds: types.MinTimestampSeconds - 1}, + {Seconds: types.MaxTimestampSeconds + 1}, + {Nanos: -1}, + {Nanos: 1_000_000_000}, + } { + if _, err := json.Marshal(value); err == nil { + t.Errorf("Marshal(%+v) error = nil", value) + } + } +} + +func TestTime_CheckValid(t *testing.T) { + testCases := []struct { + name string + value *types.Time + valid bool + }{ + {name: "nil", value: nil}, + {name: "zero", value: &types.Time{}, valid: true}, + {name: "minimum", value: &types.Time{Seconds: types.MinTimestampSeconds}, valid: true}, + {name: "maximum", value: &types.Time{Seconds: types.MaxTimestampSeconds, Nanos: 999_999_999}, valid: true}, + {name: "seconds underflow", value: &types.Time{Seconds: types.MinTimestampSeconds - 1}}, + {name: "seconds overflow", value: &types.Time{Seconds: types.MaxTimestampSeconds + 1}}, + {name: "negative nanos", value: &types.Time{Nanos: -1}}, + {name: "nanos overflow", value: &types.Time{Nanos: 1_000_000_000}}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.value.CheckValid() + if (err == nil) != tc.valid { + t.Errorf("CheckValid() error = %v, valid = %t", err, tc.valid) + } + }) + } +} diff --git a/customllms/.package.json b/customllms/.package.json new file mode 100644 index 0000000..a3b2da3 --- /dev/null +++ b/customllms/.package.json @@ -0,0 +1,3 @@ +{ + "package": "customllms" +} diff --git a/customllms/CHANGELOG.md b/customllms/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/customllms/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/customllms/README.md b/customllms/README.md new file mode 100644 index 0000000..ff156cc --- /dev/null +++ b/customllms/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/customllms + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/customllms@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/customllms/v1" + +client, err := customllms.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/customllms/go.mod b/customllms/go.mod new file mode 100644 index 0000000..9302662 --- /dev/null +++ b/customllms/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/customllms + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/customllms/internal/version.go b/customllms/internal/version.go new file mode 100644 index 0000000..1b168ad --- /dev/null +++ b/customllms/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-customllms" + +const Version = "0.0.1-dev.1" diff --git a/customllms/v1/client.go b/customllms/v1/client.go new file mode 100755 index 0000000..aadd512 --- /dev/null +++ b/customllms/v1/client.go @@ -0,0 +1,451 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package customllms + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/customllms/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Cancel a Custom LLM Optimization Run. +func (c *internalClient) CancelCustomLlmOptimizationRun(ctx context.Context, req *CancelCustomLlmOptimizationRunRequest, opts ...call.Option) error { + wireReq, err := cancelCustomLlmOptimizationRunRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/custom-llms/") + pb.singleSegment(*req.Id) + pb.literal("/optimize/cancel") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Create a Custom LLM. +func (c *internalClient) CreateCustomLlm(ctx context.Context, req *CreateCustomLlmRequest, opts ...call.Option) (*CustomLlm, error) { + wireReq, err := createCustomLlmRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/custom-llms" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomLlm + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customLlmWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customLlmFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a Custom LLM. +func (c *internalClient) DeleteCustomLlm(ctx context.Context, req *DeleteCustomLlmRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/custom-llms/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Get a Custom LLM. +func (c *internalClient) GetCustomLlm(ctx context.Context, req *GetCustomLlmRequest, opts ...call.Option) (*CustomLlm, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/custom-llms/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomLlm + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customLlmWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customLlmFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Start a Custom LLM Optimization Run. +func (c *internalClient) StartCustomLlmOptimizationRun(ctx context.Context, req *StartCustomLlmOptimizationRunRequest, opts ...call.Option) (*CustomLlm, error) { + wireReq, err := startCustomLlmOptimizationRunRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/custom-llms/") + pb.singleSegment(*req.Id) + pb.literal("/optimize") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomLlm + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customLlmWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customLlmFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a Custom LLM. +func (c *internalClient) UpdateCustomLlm(ctx context.Context, req *UpdateCustomLlmRequest, opts ...call.Option) (*CustomLlm, error) { + wireReq, err := updateCustomLlmRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/custom-llms/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomLlm + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customLlmWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customLlmFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/customllms/v1/genhelper.go b/customllms/v1/genhelper.go new file mode 100755 index 0000000..e1d989e --- /dev/null +++ b/customllms/v1/genhelper.go @@ -0,0 +1,188 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package customllms + +import ( + "context" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/customllms/v1/model.go b/customllms/v1/model.go new file mode 100755 index 0000000..b276720 --- /dev/null +++ b/customllms/v1/model.go @@ -0,0 +1,100 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package customllms + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// States of Custom LLM optimization lifecycle. +type State string + +const ( + State_Unspecified State = "" + State_Created State = "CREATED" + State_Running State = "RUNNING" + State_Completed State = "COMPLETED" + State_Failed State = "FAILED" + State_Pending State = "PENDING" + State_Cancelled State = "CANCELLED" +) + +type CancelCustomLlmOptimizationRunRequest struct { + Id *string +} + +type CreateCustomLlmRequest struct { + // Name of the custom LLM. Only alphanumeric characters and dashes allowed. + Name *string + // Instructions for the custom LLM to follow + Instructions *string + // Datasets used for training and evaluating the model, not for inference. + // Currently, only 1 dataset is accepted. + Datasets []Dataset + // Guidelines for the custom LLM to adhere to + Guidelines []string + // This will soon be deprecated!! Optional: UC path for agent artifacts. If you + // are using a dataset that you only have read permissions, please provide a + // destination path where you have write permissions. Please provide this in + // catalog.schema format. + AgentArtifactPath *string +} + +type CustomLlm struct { + Id *string `fieldmask:"id"` + // Name of the custom LLM + Name *string `fieldmask:"name"` + // Name of the endpoint that will be used to serve the custom LLM + EndpointName *string `fieldmask:"endpoint_name"` + // Instructions for the custom LLM to follow + Instructions *string `fieldmask:"instructions"` + // Datasets used for training and evaluating the model, not for inference + Datasets []Dataset `fieldmask:"datasets"` + // Guidelines for the custom LLM to adhere to + Guidelines []string `fieldmask:"guidelines"` + // If optimization is kicked off, tracks the state of the custom LLM + OptimizationState State `fieldmask:"optimization_state"` + // Creator of the custom LLM + Creator *string `fieldmask:"creator"` + // Creation timestamp of the custom LLM + CreationTime *types.Time `fieldmask:"creation_time"` + AgentArtifactPath *string `fieldmask:"agent_artifact_path"` +} + +type Dataset struct { + Table *Table +} + +type DeleteCustomLlmRequest struct { + // The id of the custom llm + Id *string +} + +type GetCustomLlmRequest struct { + // The id of the custom llm + Id *string +} + +type StartCustomLlmOptimizationRunRequest struct { + // The Id of the tile. + Id *string +} + +type Table struct { + // Full UC table path in catalog.schema.table_name format + TablePath *string + // Name of the request column + RequestCol *string + // Optional: Name of the response column if the data is labeled + ResponseCol *string +} + +type UpdateCustomLlmRequest struct { + // The id of the custom llm + Id *string + // The CustomLlm containing the fields which should be updated. + CustomLlm *CustomLlm + // The list of the CustomLlm fields to update. These should correspond to the + // values (or lack thereof) present in `custom_llm`. + UpdateMask *types.FieldMask[CustomLlm] +} diff --git a/customllms/v1/wire.go b/customllms/v1/wire.go new file mode 100755 index 0000000..f883be5 --- /dev/null +++ b/customllms/v1/wire.go @@ -0,0 +1,219 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package customllms + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type cancelCustomLlmOptimizationRunRequestWire struct { + Id *string `json:"id,omitempty"` +} + +func cancelCustomLlmOptimizationRunRequestToWire(v *CancelCustomLlmOptimizationRunRequest) (*cancelCustomLlmOptimizationRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &cancelCustomLlmOptimizationRunRequestWire{ + Id: v.Id, + }, nil +} + +type createCustomLlmRequestWire struct { + Name *string `json:"name,omitempty"` + Instructions *string `json:"instructions,omitempty"` + Datasets []datasetWire `json:"datasets,omitempty"` + Guidelines []string `json:"guidelines,omitempty"` + AgentArtifactPath *string `json:"agent_artifact_path,omitempty"` +} + +func createCustomLlmRequestToWire(v *CreateCustomLlmRequest) (*createCustomLlmRequestWire, error) { + if v == nil { + return nil, nil + } + datasetsWireValue, err := convertSlice(v.Datasets, datasetToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCustomLlmRequest.Datasets", err) + } + return &createCustomLlmRequestWire{ + Name: v.Name, + Instructions: v.Instructions, + Datasets: datasetsWireValue, + Guidelines: v.Guidelines, + AgentArtifactPath: v.AgentArtifactPath, + }, nil +} + +type customLlmWire struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + Instructions *string `json:"instructions,omitempty"` + Datasets []datasetWire `json:"datasets,omitempty"` + Guidelines []string `json:"guidelines,omitempty"` + OptimizationState State `json:"optimization_state,omitempty"` + Creator *string `json:"creator,omitempty"` + CreationTime *types.Time `json:"creation_time,omitempty"` + AgentArtifactPath *string `json:"agent_artifact_path,omitempty"` +} + +func customLlmToWire(v *CustomLlm) (*customLlmWire, error) { + if v == nil { + return nil, nil + } + datasetsWireValue, err := convertSlice(v.Datasets, datasetToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomLlm.Datasets", err) + } + return &customLlmWire{ + Id: v.Id, + Name: v.Name, + EndpointName: v.EndpointName, + Instructions: v.Instructions, + Datasets: datasetsWireValue, + Guidelines: v.Guidelines, + OptimizationState: v.OptimizationState, + Creator: v.Creator, + CreationTime: v.CreationTime, + AgentArtifactPath: v.AgentArtifactPath, + }, nil +} + +func customLlmFromWire(w *customLlmWire) (*CustomLlm, error) { + if w == nil { + return nil, nil + } + datasetsPublicValue, err := convertSlice(w.Datasets, datasetFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomLlm.Datasets", err) + } + return &CustomLlm{ + Id: w.Id, + Name: w.Name, + EndpointName: w.EndpointName, + Instructions: w.Instructions, + Datasets: datasetsPublicValue, + Guidelines: w.Guidelines, + OptimizationState: w.OptimizationState, + Creator: w.Creator, + CreationTime: w.CreationTime, + AgentArtifactPath: w.AgentArtifactPath, + }, nil +} + +type datasetWire struct { + Table *tableWire `json:"table,omitempty"` +} + +func datasetToWire(v *Dataset) (*datasetWire, error) { + if v == nil { + return nil, nil + } + tableWireValue, err := tableToWire(v.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dataset.Table", err) + } + return &datasetWire{ + Table: tableWireValue, + }, nil +} + +func datasetFromWire(w *datasetWire) (*Dataset, error) { + if w == nil { + return nil, nil + } + tablePublicValue, err := tableFromWire(w.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dataset.Table", err) + } + return &Dataset{ + Table: tablePublicValue, + }, nil +} + +type startCustomLlmOptimizationRunRequestWire struct { + Id *string `json:"id,omitempty"` +} + +func startCustomLlmOptimizationRunRequestToWire(v *StartCustomLlmOptimizationRunRequest) (*startCustomLlmOptimizationRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &startCustomLlmOptimizationRunRequestWire{ + Id: v.Id, + }, nil +} + +type tableWire struct { + TablePath *string `json:"table_path,omitempty"` + RequestCol *string `json:"request_col,omitempty"` + ResponseCol *string `json:"response_col,omitempty"` +} + +func tableToWire(v *Table) (*tableWire, error) { + if v == nil { + return nil, nil + } + return &tableWire{ + TablePath: v.TablePath, + RequestCol: v.RequestCol, + ResponseCol: v.ResponseCol, + }, nil +} + +func tableFromWire(w *tableWire) (*Table, error) { + if w == nil { + return nil, nil + } + return &Table{ + TablePath: w.TablePath, + RequestCol: w.RequestCol, + ResponseCol: w.ResponseCol, + }, nil +} + +type updateCustomLlmRequestWire struct { + Id *string `json:"id,omitempty"` + CustomLlm *customLlmWire `json:"custom_llm,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateCustomLlmRequestToWire(v *UpdateCustomLlmRequest) (*updateCustomLlmRequestWire, error) { + if v == nil { + return nil, nil + } + customLlmWireValue, err := customLlmToWire(v.CustomLlm) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCustomLlmRequest.CustomLlm", err) + } + return &updateCustomLlmRequestWire{ + Id: v.Id, + CustomLlm: customLlmWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/database/.package.json b/database/.package.json new file mode 100644 index 0000000..e3c76e2 --- /dev/null +++ b/database/.package.json @@ -0,0 +1,3 @@ +{ + "package": "database" +} diff --git a/database/CHANGELOG.md b/database/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/database/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/database/README.md b/database/README.md new file mode 100644 index 0000000..24f4410 --- /dev/null +++ b/database/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/database + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/database@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/database/v1" + +client, err := database.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/database/go.mod b/database/go.mod new file mode 100644 index 0000000..e912db9 --- /dev/null +++ b/database/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/database + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/database/internal/version.go b/database/internal/version.go new file mode 100644 index 0000000..250e458 --- /dev/null +++ b/database/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-database" + +const Version = "0.0.1-dev.1" diff --git a/database/v1/client.go b/database/v1/client.go new file mode 100755 index 0000000..eb81de9 --- /dev/null +++ b/database/v1/client.go @@ -0,0 +1,1886 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package database + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/database/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a Database Catalog. +func (c *internalClient) CreateDatabaseCatalog(ctx context.Context, req *CreateDatabaseCatalogRequest, opts ...call.Option) (*DatabaseCatalog, error) { + wireReq, err := createDatabaseCatalogRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Catalog) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/database/catalogs" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseCatalog + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseCatalogWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseCatalogFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a Database Instance. +func (c *internalClient) createDatabaseInstanceBase(ctx context.Context, req *CreateDatabaseInstanceRequest, opts ...call.Option) (*DatabaseInstance, error) { + wireReq, err := createDatabaseInstanceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.DatabaseInstance) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/database/instances" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseInstance + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseInstanceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseInstanceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a Database Instance. +func (c *internalClient) CreateDatabaseInstance(ctx context.Context, req *CreateDatabaseInstanceRequest, opts ...call.Option) (*CreateDatabaseInstanceWaiter, error) { + resp, err := c.createDatabaseInstanceBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.Name == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "Name") + } + return &CreateDatabaseInstanceWaiter{ + poll: c.GetDatabaseInstance, + name: *resp.Name, + }, nil +} + +// CreateDatabaseInstanceWaiter tracks the state of the operation started by CreateDatabaseInstance. +type CreateDatabaseInstanceWaiter struct { + poll func(context.Context, *GetDatabaseInstanceRequest, ...call.Option) (*DatabaseInstance, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateDatabaseInstanceWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetDatabaseInstanceRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case DatabaseInstance_State_Available: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateDatabaseInstanceWaiter) Wait(ctx context.Context, opts ...lro.Option) (*DatabaseInstance, error) { + var result *DatabaseInstance + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetDatabaseInstanceRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case DatabaseInstance_State_Available: + result = pollResp + return nil + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Create a role for a Database Instance. +func (c *internalClient) CreateDatabaseInstanceRole(ctx context.Context, req *CreateDatabaseInstanceRoleRequest, opts ...call.Option) (*DatabaseInstanceRole, error) { + wireReq, err := createDatabaseInstanceRoleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.DatabaseInstanceRole) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/instances/") + pb.singleSegment(*req.InstanceName) + pb.literal("/roles") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "database_instance_name", wireReq.DatabaseInstanceName); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseInstanceRole + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseInstanceRoleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseInstanceRoleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a Database Table. Useful for registering pre-existing PG tables in UC. +// See CreateSyncedDatabaseTable for creating synced tables in PG from a source +// table in UC. +func (c *internalClient) CreateDatabaseTable(ctx context.Context, req *CreateDatabaseTableRequest, opts ...call.Option) (*DatabaseTable, error) { + wireReq, err := createDatabaseTableRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Table) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/database/tables" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseTable + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseTableWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseTableFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a Synced Database Table. +func (c *internalClient) CreateSyncedDatabaseTable(ctx context.Context, req *CreateSyncedDatabaseTableRequest, opts ...call.Option) (*SyncedDatabaseTable, error) { + wireReq, err := createSyncedDatabaseTableRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.SyncedTable) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/database/synced_tables" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SyncedDatabaseTable + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp syncedDatabaseTableWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = syncedDatabaseTableFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a Database Catalog. +func (c *internalClient) DeleteDatabaseCatalog(ctx context.Context, req *DeleteDatabaseCatalogRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/catalogs/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete a Database Instance. +func (c *internalClient) DeleteDatabaseInstance(ctx context.Context, req *DeleteDatabaseInstanceRequest, opts ...call.Option) error { + wireReq, err := deleteDatabaseInstanceRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/instances/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return err + } + if err := addQueryValue(queryParams, "purge", wireReq.Purge); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Deletes a role for a Database Instance. +func (c *internalClient) DeleteDatabaseInstanceRole(ctx context.Context, req *DeleteDatabaseInstanceRoleRequest, opts ...call.Option) error { + wireReq, err := deleteDatabaseInstanceRoleRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/instances/") + pb.singleSegment(*req.InstanceName) + pb.literal("/roles/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "reassign_owned_to", wireReq.ReassignOwnedTo); err != nil { + return err + } + if err := addQueryValue(queryParams, "allow_missing", wireReq.AllowMissing); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete a Database Table. +func (c *internalClient) DeleteDatabaseTable(ctx context.Context, req *DeleteDatabaseTableRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/tables/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete a Synced Database Table. +func (c *internalClient) DeleteSyncedDatabaseTable(ctx context.Context, req *DeleteSyncedDatabaseTableRequest, opts ...call.Option) error { + wireReq, err := deleteSyncedDatabaseTableRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/synced_tables/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "purge_data", wireReq.PurgeData); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Find a Database Instance by uid. +func (c *internalClient) FindDatabaseInstanceByUid(ctx context.Context, req *FindDatabaseInstanceByUidRequest, opts ...call.Option) (*DatabaseInstance, error) { + wireReq, err := findDatabaseInstanceByUidRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/database/instances:findByUid" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "uid", wireReq.Uid); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseInstance + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseInstanceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseInstanceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Generates a credential that can be used to access database instances. +func (c *internalClient) GenerateDatabaseCredential(ctx context.Context, req *GenerateDatabaseCredentialRequest, opts ...call.Option) (*DatabaseCredential, error) { + wireReq, err := generateDatabaseCredentialRequestToWire(req) + if err != nil { + return nil, err + } + if wireReq.RequestId == nil || *wireReq.RequestId == "" { + wireReq.RequestId = new(generateRequestID()) + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/database/credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseCredential + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseCredentialWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseCredentialFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a Database Catalog. +func (c *internalClient) GetDatabaseCatalog(ctx context.Context, req *GetDatabaseCatalogRequest, opts ...call.Option) (*DatabaseCatalog, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/catalogs/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseCatalog + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseCatalogWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseCatalogFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a Database Instance. +func (c *internalClient) GetDatabaseInstance(ctx context.Context, req *GetDatabaseInstanceRequest, opts ...call.Option) (*DatabaseInstance, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/instances/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseInstance + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseInstanceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseInstanceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a role for a Database Instance. +func (c *internalClient) GetDatabaseInstanceRole(ctx context.Context, req *GetDatabaseInstanceRoleRequest, opts ...call.Option) (*DatabaseInstanceRole, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/instances/") + pb.singleSegment(*req.InstanceName) + pb.literal("/roles/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseInstanceRole + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseInstanceRoleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseInstanceRoleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a Database Table. +func (c *internalClient) GetDatabaseTable(ctx context.Context, req *GetDatabaseTableRequest, opts ...call.Option) (*DatabaseTable, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/tables/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseTable + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseTableWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseTableFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a Synced Database Table. +func (c *internalClient) GetSyncedDatabaseTable(ctx context.Context, req *GetSyncedDatabaseTableRequest, opts ...call.Option) (*SyncedDatabaseTable, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/synced_tables/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SyncedDatabaseTable + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp syncedDatabaseTableWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = syncedDatabaseTableFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// This API is currently unimplemented, but exposed for Terraform support. +func (c *internalClient) ListDatabaseCatalogs(ctx context.Context, req *ListDatabaseCatalogsRequest, opts ...call.Option) (*ListDatabaseCatalogsResponse, error) { + wireReq, err := listDatabaseCatalogsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/instances/") + pb.singleSegment(*req.InstanceName) + pb.literal("/catalogs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListDatabaseCatalogsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listDatabaseCatalogsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listDatabaseCatalogsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListDatabaseCatalogsIter returns an iterator that iterates +// over the results of ListDatabaseCatalogs. +// +// For example: +// +// for item, err := range c.ListDatabaseCatalogsIter(ctx, &ListDatabaseCatalogsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListDatabaseCatalogs call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListDatabaseCatalogs directly. +func (c *internalClient) ListDatabaseCatalogsIter(ctx context.Context, req *ListDatabaseCatalogsRequest, opts ...call.Option) iter.Seq2[*DatabaseCatalog, error] { + return func(yield func(*DatabaseCatalog, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListDatabaseCatalogsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListDatabaseCatalogs(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.DatabaseCatalogs { + if !yield(&resp.DatabaseCatalogs[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// START OF PG ROLE APIs Section These APIs are marked a PUBLIC with stage < +// PUBLIC_PREVIEW. With more recent Lakebase V2 plans, we don't plan to ever +// advance these to PUBLIC_PREVIEW. These APIs will remain effectively +// undocumented/UI-only and we'll aim for a new public roles API as part of V2 +// PuPr. +func (c *internalClient) ListDatabaseInstanceRoles(ctx context.Context, req *ListDatabaseInstanceRolesRequest, opts ...call.Option) (*ListDatabaseInstanceRolesResponse, error) { + wireReq, err := listDatabaseInstanceRolesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/instances/") + pb.singleSegment(*req.InstanceName) + pb.literal("/roles") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListDatabaseInstanceRolesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listDatabaseInstanceRolesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listDatabaseInstanceRolesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListDatabaseInstanceRolesIter returns an iterator that iterates +// over the results of ListDatabaseInstanceRoles. +// +// For example: +// +// for item, err := range c.ListDatabaseInstanceRolesIter(ctx, &ListDatabaseInstanceRolesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListDatabaseInstanceRoles call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListDatabaseInstanceRoles directly. +func (c *internalClient) ListDatabaseInstanceRolesIter(ctx context.Context, req *ListDatabaseInstanceRolesRequest, opts ...call.Option) iter.Seq2[*DatabaseInstanceRole, error] { + return func(yield func(*DatabaseInstanceRole, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListDatabaseInstanceRolesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListDatabaseInstanceRoles(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.DatabaseInstanceRoles { + if !yield(&resp.DatabaseInstanceRoles[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List Database Instances. +func (c *internalClient) ListDatabaseInstances(ctx context.Context, req *ListDatabaseInstancesRequest, opts ...call.Option) (*ListDatabaseInstancesResponse, error) { + wireReq, err := listDatabaseInstancesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/database/instances" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListDatabaseInstancesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listDatabaseInstancesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listDatabaseInstancesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListDatabaseInstancesIter returns an iterator that iterates +// over the results of ListDatabaseInstances. +// +// For example: +// +// for item, err := range c.ListDatabaseInstancesIter(ctx, &ListDatabaseInstancesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListDatabaseInstances call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListDatabaseInstances directly. +func (c *internalClient) ListDatabaseInstancesIter(ctx context.Context, req *ListDatabaseInstancesRequest, opts ...call.Option) iter.Seq2[*DatabaseInstance, error] { + return func(yield func(*DatabaseInstance, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListDatabaseInstancesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListDatabaseInstances(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.DatabaseInstances { + if !yield(&resp.DatabaseInstances[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// This API is currently unimplemented, but exposed for Terraform support. +func (c *internalClient) ListSyncedDatabaseTables(ctx context.Context, req *ListSyncedDatabaseTablesRequest, opts ...call.Option) (*ListSyncedDatabaseTablesResponse, error) { + wireReq, err := listSyncedDatabaseTablesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/instances/") + pb.singleSegment(*req.InstanceName) + pb.literal("/synced_tables") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListSyncedDatabaseTablesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listSyncedDatabaseTablesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listSyncedDatabaseTablesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListSyncedDatabaseTablesIter returns an iterator that iterates +// over the results of ListSyncedDatabaseTables. +// +// For example: +// +// for item, err := range c.ListSyncedDatabaseTablesIter(ctx, &ListSyncedDatabaseTablesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListSyncedDatabaseTables call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListSyncedDatabaseTables directly. +func (c *internalClient) ListSyncedDatabaseTablesIter(ctx context.Context, req *ListSyncedDatabaseTablesRequest, opts ...call.Option) iter.Seq2[*SyncedDatabaseTable, error] { + return func(yield func(*SyncedDatabaseTable, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListSyncedDatabaseTablesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListSyncedDatabaseTables(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.SyncedTables { + if !yield(&resp.SyncedTables[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// This API is currently unimplemented, but exposed for Terraform support. +func (c *internalClient) UpdateDatabaseCatalog(ctx context.Context, req *UpdateDatabaseCatalogRequest, opts ...call.Option) (*DatabaseCatalog, error) { + wireReq, err := updateDatabaseCatalogRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.DatabaseCatalog) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/catalogs/") + pb.singleSegment(*req.DatabaseCatalog.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseCatalog + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseCatalogWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseCatalogFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a Database Instance. +func (c *internalClient) UpdateDatabaseInstance(ctx context.Context, req *UpdateDatabaseInstanceRequest, opts ...call.Option) (*DatabaseInstance, error) { + wireReq, err := updateDatabaseInstanceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.DatabaseInstance) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/instances/") + pb.singleSegment(*req.DatabaseInstance.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseInstance + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseInstanceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseInstanceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// This API is currently unimplemented, but exposed for Terraform support. +func (c *internalClient) UpdateSyncedDatabaseTable(ctx context.Context, req *UpdateSyncedDatabaseTableRequest, opts ...call.Option) (*SyncedDatabaseTable, error) { + wireReq, err := updateSyncedDatabaseTableRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.SyncedTable) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/database/synced_tables/") + pb.singleSegment(*req.SyncedTable.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SyncedDatabaseTable + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp syncedDatabaseTableWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = syncedDatabaseTableFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/database/v1/genhelper.go b/database/v1/genhelper.go new file mode 100755 index 0000000..836d288 --- /dev/null +++ b/database/v1/genhelper.go @@ -0,0 +1,257 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package database + +import ( + "bytes" + "context" + "crypto/rand" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// generateRequestID returns a random RFC 4122 version 4 UUID string, used as an +// idempotency token when the caller does not supply one. It uses crypto/rand to +// avoid a UUID dependency; a read failure is treated as unrecoverable. +func generateRequestID() string { + var b [16]byte + if _, err := rand.Read(b[:]); err != nil { + panic(fmt.Sprintf("generate request id: %v", err)) + } + b[6] = (b[6] & 0x0f) | 0x40 // version 4 + b[8] = (b[8] & 0x3f) | 0x80 // variant 10 + return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16]) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/database/v1/model.go b/database/v1/model.go new file mode 100755 index 0000000..6062b6e --- /dev/null +++ b/database/v1/model.go @@ -0,0 +1,865 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package database + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type ProvisioningPhase string + +const ( + ProvisioningPhase_Unspecified ProvisioningPhase = "" + // Ingestion phase of the synced table. This is when the synced table is + // ingesting data from the delta table. + ProvisioningPhase_ProvisioningPhaseMain ProvisioningPhase = "PROVISIONING_PHASE_MAIN" + // Index scan phase of the synced table. This is when the synced table is + // creating indexes on the ingested data. + ProvisioningPhase_ProvisioningPhaseIndexScan ProvisioningPhase = "PROVISIONING_PHASE_INDEX_SCAN" + // Index sort phase of the synced table. This is when the synced table is + // creating indexes on the ingested data. + ProvisioningPhase_ProvisioningPhaseIndexSort ProvisioningPhase = "PROVISIONING_PHASE_INDEX_SORT" +) + +type SyncedTableSchedulingPolicy string + +const ( + SyncedTableSchedulingPolicy_Unspecified SyncedTableSchedulingPolicy = "" + // Pipeline runs continuously after generating the initial data. Requires the + // source table to have Change Data Feed (CDF) enabled. + SyncedTableSchedulingPolicy_Continuous SyncedTableSchedulingPolicy = "CONTINUOUS" + // Pipeline stops after generating the initial data and can be triggered later + // (manually, through a cron job or through data triggers). Requires the source + // table to have Change Data Feed (CDF) enabled. + SyncedTableSchedulingPolicy_Triggered SyncedTableSchedulingPolicy = "TRIGGERED" + // Pipeline stops after generating the initial data and can be triggered later + // (manually, through a cron job or through data triggers). Successive updates + // always perform a full copy of the source table data (no incremental updates). + // Does not require the source table to have Change Data Feed (CDF) enabled. + SyncedTableSchedulingPolicy_Snapshot SyncedTableSchedulingPolicy = "SNAPSHOT" +) + +// The state of a synced table. +type SyncedTableState string + +const ( + SyncedTableState_Unspecified SyncedTableState = "" + // The synced table has just been created and resources are being provisioned. + // This is also the catch-all state if there is not a more suitable state to + // report for the synced table. + SyncedTableState_SyncedTableProvisioning SyncedTableState = "SYNCED_TABLE_PROVISIONING" + // The synced table is provisioning resources for the data synchronization + // pipeline. + SyncedTableState_SyncedTableProvisioningPipelineResources SyncedTableState = "SYNCED_TABLE_PROVISIONING_PIPELINE_RESOURCES" + // The synced table is executing the initial data synchronization. + SyncedTableState_SyncedTableProvisioningInitialSnapshot SyncedTableState = "SYNCED_TABLE_PROVISIONING_INITIAL_SNAPSHOT" + // The synced table is ready to serve data. + SyncedTableState_SyncedTableOnline SyncedTableState = "SYNCED_TABLE_ONLINE" + // The synced table is ready to serve data and is continuously updating. Only + // shown for synced tables using the "Continuous" sync mode. + SyncedTableState_SyncedTableOnlineContinuousUpdate SyncedTableState = "SYNCED_TABLE_ONLINE_CONTINUOUS_UPDATE" + // The synced table is ready to serve data and an active update is in progress. + // Only shown for synced tables using the "Triggered" sync mode. + SyncedTableState_SyncedTableOnlineTriggeredUpdate SyncedTableState = "SYNCED_TABLE_ONLINE_TRIGGERED_UPDATE" + // The synced table is ready to serve data and there are no active updates. Only + // shown for synced tables using the "Triggered" sync mode. + SyncedTableState_SyncedTableOnlineNoPendingUpdate SyncedTableState = "SYNCED_TABLE_ONLINE_NO_PENDING_UPDATE" + // The synced table has encountered an internal error and is not available for + // serving. + SyncedTableState_SyncedTabledOffline SyncedTableState = "SYNCED_TABLED_OFFLINE" + // The synced table is not available for serving because the data + // synchronization pipeline has failed. Please review the pipeline event logs to + // troubleshoot. + SyncedTableState_SyncedTableOfflineFailed SyncedTableState = "SYNCED_TABLE_OFFLINE_FAILED" + // The data synchronization pipeline has encountered an error but the synced + // table is still available for serving (potentially stale) data. Please review + // the pipeline event logs to troubleshoot. + SyncedTableState_SyncedTableOnlinePipelineFailed SyncedTableState = "SYNCED_TABLE_ONLINE_PIPELINE_FAILED" + // The synced table is available for serving, and is provisioning resources for + // a newly started data synchronization pipeline. + SyncedTableState_SyncedTableOnlineUpdatingPipelineResources SyncedTableState = "SYNCED_TABLE_ONLINE_UPDATING_PIPELINE_RESOURCES" +) + +type DatabaseInstance_State string + +const ( + DatabaseInstance_State_Unspecified DatabaseInstance_State = "" + // The instance is being brought online. + DatabaseInstance_State_Starting DatabaseInstance_State = "STARTING" + // The instance is active and ready to use. + DatabaseInstance_State_Available DatabaseInstance_State = "AVAILABLE" + // The instance is being deleted. + DatabaseInstance_State_Deleting DatabaseInstance_State = "DELETING" + // The instance is stopped. + DatabaseInstance_State_Stopped DatabaseInstance_State = "STOPPED" + // The instance is being updated. + DatabaseInstance_State_Updating DatabaseInstance_State = "UPDATING" + // The instance is failing over. + DatabaseInstance_State_FailingOver DatabaseInstance_State = "FAILING_OVER" +) + +type DatabaseInstanceRole_IdentityType string + +const ( + DatabaseInstanceRole_IdentityType_Unspecified DatabaseInstanceRole_IdentityType = "" + // A role without a Databricks identity. + DatabaseInstanceRole_IdentityType_PgOnly DatabaseInstanceRole_IdentityType = "PG_ONLY" + // A user in a Databricks workspace. + DatabaseInstanceRole_IdentityType_User DatabaseInstanceRole_IdentityType = "USER" + // A service principal in a Databricks workspace. + DatabaseInstanceRole_IdentityType_ServicePrincipal DatabaseInstanceRole_IdentityType = "SERVICE_PRINCIPAL" + // A group in a Databricks workspace. + DatabaseInstanceRole_IdentityType_Group DatabaseInstanceRole_IdentityType = "GROUP" +) + +// Roles that the DatabaseInstanceRole can be a member of. +type DatabaseInstanceRole_MembershipRole string + +const ( + DatabaseInstanceRole_MembershipRole_Unspecified DatabaseInstanceRole_MembershipRole = "" + // Indicates membership in DATABRICKS_SUPERUSER, the highest set of privileges + // exposed to customers. + DatabaseInstanceRole_MembershipRole_DatabricksSuperuser DatabaseInstanceRole_MembershipRole = "DATABRICKS_SUPERUSER" +) + +type ProvisioningInfo_State string + +const ( + ProvisioningInfo_State_Unspecified ProvisioningInfo_State = "" + ProvisioningInfo_State_Provisioning ProvisioningInfo_State = "PROVISIONING" + ProvisioningInfo_State_Active ProvisioningInfo_State = "ACTIVE" + ProvisioningInfo_State_Failed ProvisioningInfo_State = "FAILED" + ProvisioningInfo_State_Deleting ProvisioningInfo_State = "DELETING" + ProvisioningInfo_State_Updating ProvisioningInfo_State = "UPDATING" + ProvisioningInfo_State_Degraded ProvisioningInfo_State = "DEGRADED" +) + +// Might add WRITE in the future +type RequestedClaims_PermissionSet string + +const ( + RequestedClaims_PermissionSet_Unspecified RequestedClaims_PermissionSet = "" + RequestedClaims_PermissionSet_ReadOnly RequestedClaims_PermissionSet = "READ_ONLY" +) + +// PostgreSQL-specific target types that can override the default Delta-to-PG +// mapping. +type SyncedTableSpec_PgSpecificType string + +const ( + SyncedTableSpec_PgSpecificType_Unspecified SyncedTableSpec_PgSpecificType = "" + // Maps the column to the pgvector vector type. + SyncedTableSpec_PgSpecificType_PgSpecificTypeVector SyncedTableSpec_PgSpecificType = "PG_SPECIFIC_TYPE_VECTOR" + // Maps the column to the pgvector half-precision halfvec type. + SyncedTableSpec_PgSpecificType_PgSpecificTypeHalfvec SyncedTableSpec_PgSpecificType = "PG_SPECIFIC_TYPE_HALFVEC" + // Maps the column to a length-bounded character varying(N) type. + SyncedTableSpec_PgSpecificType_PgSpecificTypeVarchar SyncedTableSpec_PgSpecificType = "PG_SPECIFIC_TYPE_VARCHAR" +) + +type CreateDatabaseCatalogRequest struct { + Catalog *DatabaseCatalog +} + +type CreateDatabaseInstanceRequest struct { + // Instance to create. + DatabaseInstance *DatabaseInstance +} + +type CreateDatabaseInstanceRoleRequest struct { + InstanceName *string + DatabaseInstanceRole *DatabaseInstanceRole + DatabaseInstanceName *string +} + +type CreateDatabaseTableRequest struct { + Table *DatabaseTable +} + +type CreateSyncedDatabaseTableRequest struct { + SyncedTable *SyncedDatabaseTable +} + +type CustomTag struct { + // The key of the custom tag. + Key *string + // The value of the custom tag. + Value *string +} + +type DatabaseCatalog struct { + // The name of the catalog in UC. + Name *string `fieldmask:"name"` + // The name of the DatabaseInstance housing the database. + DatabaseInstanceName *string `fieldmask:"database_instance_name"` + // The name of the database (in an instance) associated with the catalog. + DatabaseName *string `fieldmask:"database_name"` + Uid *string `fieldmask:"uid"` + CreateDatabaseIfNotExists *bool `fieldmask:"create_database_if_not_exists"` +} + +type DatabaseCredential struct { + Token *string + ExpirationTime *types.Time +} + +// A DatabaseInstance represents a logical Postgres instance, comprised of both +// compute and storage.. +type DatabaseInstance struct { + // An immutable UUID identifier for the instance. + Uid *string `fieldmask:"uid"` + // The name of the instance. This is the unique identifier for the instance. + Name *string `fieldmask:"name"` + // The email of the creator of the instance. + Creator *string `fieldmask:"creator"` + // The DNS endpoint to connect to the instance for read+write access. + ReadWriteDns *string `fieldmask:"read_write_dns"` + // The timestamp when the instance was created. + CreationTime *types.Time `fieldmask:"creation_time"` + // The current state of the instance. + State DatabaseInstance_State `fieldmask:"state"` + // The version of Postgres running on the instance. + PgVersion *string `fieldmask:"pg_version"` + // The sku of the instance. Valid values are "CU_1", "CU_2", "CU_4", "CU_8". + Capacity *string `fieldmask:"capacity"` + // Deprecated. The sku of the instance; this field will always match the value + // of capacity. This is an output only field that contains the value computed + // from the input field combined with server side defaults. Use the field + // without the effective_ prefix to set the value. + EffectiveCapacity *string `fieldmask:"effective_capacity"` + // Whether to stop the instance. An input only param, see effective_stopped for + // the output. + Stopped *bool `fieldmask:"stopped"` + // Whether the instance is stopped. This is an output only field that contains + // the value computed from the input field combined with server side defaults. + // Use the field without the effective_ prefix to set the value. + EffectiveStopped *bool `fieldmask:"effective_stopped"` + // The number of nodes in the instance, composed of 1 primary and 0 or more + // secondaries. Defaults to 1 primary and 0 secondaries. This field is input + // only, see effective_node_count for the output. + NodeCount *int `fieldmask:"node_count"` + // The number of nodes in the instance, composed of 1 primary and 0 or more + // secondaries. Defaults to 1 primary and 0 secondaries. This is an output only + // field that contains the value computed from the input field combined with + // server side defaults. Use the field without the effective_ prefix to set the + // value. + EffectiveNodeCount *int `fieldmask:"effective_node_count"` + // Whether to enable secondaries to serve read-only traffic. Defaults to false. + EnableReadableSecondaries *bool `fieldmask:"enable_readable_secondaries"` + // Whether secondaries serving read-only traffic are enabled. Defaults to false. + // This is an output only field that contains the value computed from the input + // field combined with server side defaults. Use the field without the + // effective_ prefix to set the value. + EffectiveEnableReadableSecondaries *bool `fieldmask:"effective_enable_readable_secondaries"` + // The DNS endpoint to connect to the instance for read only access. This is + // only available if enable_readable_secondaries is true. + ReadOnlyDns *string `fieldmask:"read_only_dns"` + // The retention window for the instance. This is the time window in days for + // which the historical data is retained. The default value is 7 days. Valid + // values are 2 to 35 days. + RetentionWindowInDays *int `fieldmask:"retention_window_in_days"` + // The retention window for the instance. This is the time window in days for + // which the historical data is retained. This is an output only field that + // contains the value computed from the input field combined with server side + // defaults. Use the field without the effective_ prefix to set the value. + EffectiveRetentionWindowInDays *int `fieldmask:"effective_retention_window_in_days"` + // The ref of the parent instance. This is only available if the instance is + // child instance. Input: For specifying the parent instance to create a child + // instance. Optional. Output: Only populated if provided as input to create a + // child instance. + ParentInstanceRef *DatabaseInstanceRef `fieldmask:"parent_instance_ref"` + // The refs of the child instances. This is only available if the instance is + // parent instance. + ChildInstanceRefs []DatabaseInstanceRef `fieldmask:"child_instance_refs"` + // Whether to enable PG native password login on the instance. Defaults to + // false. + EnablePgNativeLogin *bool `fieldmask:"enable_pg_native_login"` + // Whether the instance has PG native password login enabled. This is an output + // only field that contains the value computed from the input field combined + // with server side defaults. Use the field without the effective_ prefix to set + // the value. + EffectiveEnablePgNativeLogin *bool `fieldmask:"effective_enable_pg_native_login"` + // The desired usage policy to associate with the instance. + UsagePolicyId *string `fieldmask:"usage_policy_id"` + // The policy that is applied to the instance. This is an output only field that + // contains the value computed from the input field combined with server side + // defaults. Use the field without the effective_ prefix to set the value. + EffectiveUsagePolicyId *string `fieldmask:"effective_usage_policy_id"` + // Custom tags associated with the instance. This field is only included on + // create and update responses. + CustomTags []CustomTag `fieldmask:"custom_tags"` + // The recorded custom tags associated with the instance. This is an output only + // field that contains the value computed from the input field combined with + // server side defaults. Use the field without the effective_ prefix to set the + // value. + EffectiveCustomTags []CustomTag `fieldmask:"effective_custom_tags"` +} + +// DatabaseInstanceRef is a reference to a database instance. It is used in the +// DatabaseInstance object to refer to the parent instance of an instance and to +// refer the child instances of an instance. To specify as a parent instance +// during creation of an instance, the lsn and branch_time fields are optional. +// If not specified, the child instance will be created from the latest lsn of +// the parent. If both lsn and branch_time are specified, the lsn will be used +// to create the child instance.. +type DatabaseInstanceRef struct { + // Id of the ref database instance. + Uid *string `fieldmask:"uid"` + // Name of the ref database instance. + Name *string `fieldmask:"name"` + // User-specified WAL LSN of the ref database instance. + // + // Input: For specifying the WAL LSN to create a child instance. Optional. + // Output: Only populated if provided as input to create a child instance. + Lsn *string `fieldmask:"lsn"` + // For a parent ref instance, this is the LSN on the parent instance from which + // the instance was created. For a child ref instance, this is the LSN on the + // instance from which the child instance was created. This is an output only + // field that contains the value computed from the input field combined with + // server side defaults. Use the field without the effective_ prefix to set the + // value. + EffectiveLsn *string `fieldmask:"effective_lsn"` + // Branch time of the ref database instance. For a parent ref instance, this is + // the point in time on the parent instance from which the instance was created. + // For a child ref instance, this is the point in time on the instance from + // which the child instance was created. Input: For specifying the point in time + // to create a child instance. Optional. Output: Only populated if provided as + // input to create a child instance. + BranchTime *types.Time `fieldmask:"branch_time"` +} + +// A DatabaseInstanceRole represents a Postgres role in a database instance.. +type DatabaseInstanceRole struct { + // The name of the role. This is the unique identifier for the role in an + // instance. + Name *string + // The type of the role. + IdentityType DatabaseInstanceRole_IdentityType + // An enum value for a standard role that this role is a member of. + MembershipRole DatabaseInstanceRole_MembershipRole + // The desired API-exposed Postgres role attribute to associate with the role. + // Optional. + Attributes *DatabaseInstanceRole_Attributes + // The attributes that are applied to the role. This is an output only field + // that contains the value computed from the input field combined with server + // side defaults. Use the field without the effective_ prefix to set the value. + EffectiveAttributes *DatabaseInstanceRole_Attributes + InstanceName *string +} + +// Attributes that can be granted to a Postgres role. We are only implementing a +// subset for now, see xref: +// https://www.postgresql.org/docs/16/sql-createrole.html The values follow +// Postgres keyword naming e.g. CREATEDB, BYPASSRLS, etc. which is why they +// don't include typical underscores between words. We were requested to make +// this a nested object/struct representation since these are knobs from an +// external spec.. +type DatabaseInstanceRole_Attributes struct { + Createdb *bool + Createrole *bool + Bypassrls *bool +} + +type DatabaseTable struct { + // Full three-part (catalog, schema, table) name of the table. + Name *string + // Name of the target database instance. This is required when creating database + // tables in standard catalogs. This is optional when creating database tables + // in registered catalogs. If this field is specified when creating database + // tables in registered catalogs, the database instance name MUST match that of + // the registered catalog (or the request will be rejected). + DatabaseInstanceName *string + // Target Postgres database object (logical database) name for this table. + // + // When creating a table in a standard catalog, this field is required. In this + // scenario, specifying this field will allow targeting an arbitrary postgres + // database. + // + // Registration of database tables via /database/tables is currently only + // supported in standard catalogs. + LogicalDatabaseName *string +} + +type DeleteDatabaseCatalogRequest struct { + Name *string +} + +type DeleteDatabaseInstanceRequest struct { + // Name of the instance to delete. + Name *string + // By default, an instance cannot be deleted if it has descendant instances + // created via PITR. If this flag is specified as true, all descendent instances + // will be deleted as well. + Force *bool + // Deprecated. Omitting the field or setting it to true will result in the field + // being hard deleted. Setting a value of false will throw a bad request. + Purge *bool +} + +type DeleteDatabaseInstanceRoleRequest struct { + InstanceName *string + Name *string + ReassignOwnedTo *string + // This is the AIP standard name for the equivalent of Postgres' `IF EXISTS` + // option + AllowMissing *bool +} + +type DeleteDatabaseTableRequest struct { + Name *string +} + +type DeleteSyncedDatabaseTableRequest struct { + Name *string + // Optional. When set to true, the actual PostgreSQL table will be dropped from + // the database. + PurgeData *bool +} + +type DeltaTableSyncInfo struct { + // The Delta Lake commit version that was last successfully synced. + DeltaCommitVersion *int64 `fieldmask:"delta_commit_version"` + // The timestamp when the above Delta version was committed in the source Delta + // table. Note: This is the Delta commit time, not the time the data was written + // to the synced table. + DeltaCommitTimestamp *types.Time `fieldmask:"delta_commit_timestamp"` +} + +type FindDatabaseInstanceByUidRequest struct { + // UID of the cluster to get. + Uid *string +} + +// Generates a credential that can be used to access database instances. +type GenerateDatabaseCredentialRequest struct { + RequestId *string + // Instances to request a credential for. At least one of instance_names or + // claims must be specified. + InstanceNames []string + // A set of UC permissions to add to the credential. We verify that the caller + // has the necessary permissions in UC and include a reference in the token. + // Postgres uses that token to give the connecting user additional grants to the + // Postgres resources that correspond to the UC resources. The UC resources need + // to be something that have a Postgres counterpart. For example, a synced table + // or a table in a UC database catalog. + Claims []RequestedClaims +} + +type GetDatabaseCatalogRequest struct { + Name *string +} + +type GetDatabaseInstanceRequest struct { + // Name of the cluster to get. + Name *string +} + +type GetDatabaseInstanceRoleRequest struct { + InstanceName *string + Name *string +} + +type GetDatabaseTableRequest struct { + Name *string +} + +type GetSyncedDatabaseTableRequest struct { + Name *string +} + +type ListDatabaseCatalogsRequest struct { + // Name of the instance to get database catalogs for. + InstanceName *string + // Pagination token to go to the next page of synced database tables. Requests + // first page if absent. + PageToken *string + // Upper bound for items returned. + PageSize *int +} + +type ListDatabaseCatalogsResponse struct { + DatabaseCatalogs []DatabaseCatalog + // Pagination token to request the next page of database catalogs. + NextPageToken *string +} + +type ListDatabaseInstanceRolesRequest struct { + InstanceName *string + // Pagination token to go to the next page of Database Instances. Requests first + // page if absent. + PageToken *string + // Upper bound for items returned. + PageSize *int +} + +type ListDatabaseInstanceRolesResponse struct { + // List of database instance roles. + DatabaseInstanceRoles []DatabaseInstanceRole + // Pagination token to request the next page of instances. + NextPageToken *string +} + +type ListDatabaseInstancesRequest struct { + // Pagination token to go to the next page of Database Instances. Requests first + // page if absent. + PageToken *string + // Upper bound for items returned. The maximum value is 100. + PageSize *int +} + +type ListDatabaseInstancesResponse struct { + // List of instances. + DatabaseInstances []DatabaseInstance + // Pagination token to request the next page of instances. + NextPageToken *string +} + +type ListSyncedDatabaseTablesRequest struct { + // Name of the instance to get synced tables for. + InstanceName *string + // Pagination token to go to the next page of synced database tables. Requests + // first page if absent. + PageToken *string + // Upper bound for items returned. + PageSize *int +} + +type ListSyncedDatabaseTablesResponse struct { + SyncedTables []SyncedDatabaseTable + // Pagination token to request the next page of synced tables. + NextPageToken *string +} + +// Custom fields that user can set for pipeline while creating +// SyncedDatabaseTable. Note that other fields of pipeline are still inferred by +// table def internally. +type NewPipelineSpec struct { + // This field needs to be specified if the destination catalog is a managed + // postgres catalog. + // + // UC catalog for the pipeline to store intermediate files (checkpoints, event + // logs etc). This needs to be a standard catalog where the user has permissions + // to create Delta tables. + StorageCatalog *string `fieldmask:"storage_catalog"` + // This field needs to be specified if the destination catalog is a managed + // postgres catalog. + // + // UC schema for the pipeline to store intermediate files (checkpoints, event + // logs etc). This needs to be in the standard catalog where the user has + // permissions to create Delta tables. + StorageSchema *string `fieldmask:"storage_schema"` + // Budget policy to set on the newly created pipeline. + BudgetPolicyId *string `fieldmask:"budget_policy_id"` +} + +// Copied over from managed-catalog/api/messages/common.proto to decouple SDK +// packages. xref go/unified-api-packages-dd. +type ProvisioningInfo struct { +} + +type RequestedClaims struct { + PermissionSet RequestedClaims_PermissionSet + Resources []RequestedResource +} + +type RequestedResource struct { + // Might add UC_SCHEMA & UC_CATALOG later + ResourceName isRequestedResource_ResourceName +} + +type isRequestedResource_ResourceName interface { + isRequestedResource_ResourceName() +} + +// RequestedResource_ResourceName_UnspecifiedResourceName selects UnspecifiedResourceName for RequestedResource.ResourceName. +type RequestedResource_ResourceName_UnspecifiedResourceName struct { + UnspecifiedResourceName string +} + +func (*RequestedResource_ResourceName_UnspecifiedResourceName) isRequestedResource_ResourceName() {} + +// RequestedResource_ResourceName_TableName selects TableName for RequestedResource.ResourceName. +type RequestedResource_ResourceName_TableName struct { + TableName string +} + +func (*RequestedResource_ResourceName_TableName) isRequestedResource_ResourceName() {} + +type SyncedDatabaseTable struct { + // Full three-part (catalog, schema, table) name of the table. + Name *string `fieldmask:"name"` + // Name of the target database instance. This is required when creating synced + // database tables in standard catalogs. This is optional when creating synced + // database tables in registered catalogs. If this field is specified when + // creating synced database tables in registered catalogs, the database instance + // name MUST match that of the registered catalog (or the request will be + // rejected). + DatabaseInstanceName *string `fieldmask:"database_instance_name"` + // The name of the database instance that this table is registered to. This + // field is always returned, and for tables inside database catalogs is inferred + // database instance associated with the catalog. This is an output only field + // that contains the value computed from the input field combined with server + // side defaults. Use the field without the effective_ prefix to set the value. + EffectiveDatabaseInstanceName *string `fieldmask:"effective_database_instance_name"` + // Target Postgres database object (logical database) name for this table. + // + // When creating a synced table in a registered Postgres catalog, the target + // Postgres database name is inferred to be that of the registered catalog. If + // this field is specified in this scenario, the Postgres database name MUST + // match that of the registered catalog (or the request will be rejected). + // + // When creating a synced table in a standard catalog, this field is required. + // In this scenario, specifying this field will allow targeting an arbitrary + // postgres database. Note that this has implications for the + // `create_database_objects_is_missing` field in `spec`. + LogicalDatabaseName *string `fieldmask:"logical_database_name"` + // The name of the logical database that this table is registered to. This is an + // output only field that contains the value computed from the input field + // combined with server side defaults. Use the field without the effective_ + // prefix to set the value. + EffectiveLogicalDatabaseName *string `fieldmask:"effective_logical_database_name"` + Spec *SyncedTableSpec `fieldmask:"spec"` + // The provisioning state of the synced table entity in Unity Catalog. This is + // distinct from the state of the data synchronization pipeline (i.e. the table + // may be in "ACTIVE" but the pipeline may be in "PROVISIONING" as it runs + // asynchronously). + UnityCatalogProvisioningState ProvisioningInfo_State `fieldmask:"unity_catalog_provisioning_state"` + // Synced Table data synchronization status + DataSynchronizationStatus *SyncedTableStatus `fieldmask:"data_synchronization_status"` +} + +// Detailed status of a synced table. Shown if the synced table is in the +// SYNCED_CONTINUOUS_UPDATE or the SYNCED_UPDATING_PIPELINE_RESOURCES state.. +type SyncedTableContinuousUpdateStatus struct { + // The last source table Delta version that was successfully synced to the + // synced table. + LastProcessedCommitVersion *int64 `fieldmask:"last_processed_commit_version"` + // The end timestamp of the last time any data was synchronized from the source + // table to the synced table. This is when the data is available in the synced + // table. + Timestamp *types.Time `fieldmask:"timestamp"` + // Progress of the initial data synchronization. + InitialPipelineSyncProgress *SyncedTablePipelineProgress `fieldmask:"initial_pipeline_sync_progress"` +} + +// Detailed status of a synced table. Shown if the synced table is in the +// OFFLINE_FAILED or the SYNCED_PIPELINE_FAILED state.. +type SyncedTableFailedStatus struct { + // The last source table Delta version that was successfully synced to the + // synced table. The last source table Delta version that was synced to the + // synced table. Only populated if the table is still synced and available for + // serving. + LastProcessedCommitVersion *int64 `fieldmask:"last_processed_commit_version"` + // The end timestamp of the last time any data was synchronized from the source + // table to the synced table. Only populated if the table is still synced and + // available for serving. + Timestamp *types.Time `fieldmask:"timestamp"` +} + +// Progress information of the Synced Table data synchronization pipeline.. +type SyncedTablePipelineProgress struct { + // The source table Delta version that was last processed by the pipeline. The + // pipeline may not have completely processed this version yet. + LatestVersionCurrentlyProcessing *int64 `fieldmask:"latest_version_currently_processing"` + // The number of rows that have been synced in this update. + SyncedRowCount *int64 `fieldmask:"synced_row_count"` + // The total number of rows that need to be synced in this update. This number + // may be an estimate. + TotalRowCount *int64 `fieldmask:"total_row_count"` + // The completion ratio of this update. This is a number between 0 and 1. + SyncProgressCompletion *float64 `fieldmask:"sync_progress_completion"` + // The estimated time remaining to complete this update in seconds. + EstimatedCompletionTimeSeconds *float64 `fieldmask:"estimated_completion_time_seconds"` + // The current phase of the data synchronization pipeline. + ProvisioningPhase ProvisioningPhase `fieldmask:"provisioning_phase"` +} + +type SyncedTablePosition struct { + // The starting timestamp of the most recent successful synchronization from the + // source table to the destination (synced) table. Note this is the starting + // timestamp of the sync operation, not the end time. E.g., for a batch, this is + // the time when the sync operation started. + SyncStartTimestamp *types.Time `fieldmask:"sync_start_timestamp"` + // The end timestamp of the most recent successful synchronization. This is the + // time when the data is available in the synced table. + SyncEndTimestamp *types.Time `fieldmask:"sync_end_timestamp"` + // Information about the source system at the time of the last sync. + SourceSyncInfo isSyncedTablePosition_SourceSyncInfo + _ [0]syncedTablePositionSourceSyncInfoFieldMaskMetadata `fieldmask_oneof:"SourceSyncInfo"` +} + +type isSyncedTablePosition_SourceSyncInfo interface { + isSyncedTablePosition_SourceSyncInfo() +} + +// SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo selects DeltaTableSyncInfo for SyncedTablePosition.SourceSyncInfo. +type SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo struct { + DeltaTableSyncInfo DeltaTableSyncInfo `fieldmask:"delta_table_sync_info"` +} + +func (*SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo) isSyncedTablePosition_SourceSyncInfo() { +} + +type syncedTablePositionSourceSyncInfoFieldMaskMetadata struct { + *SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo +} + +// Detailed status of a synced table. Shown if the synced table is in the +// PROVISIONING_PIPELINE_RESOURCES or the PROVISIONING_INITIAL_SNAPSHOT state.. +type SyncedTableProvisioningStatus struct { + // Details about initial data synchronization. Only populated when in the + // PROVISIONING_INITIAL_SNAPSHOT state. + InitialPipelineSyncProgress *SyncedTablePipelineProgress `fieldmask:"initial_pipeline_sync_progress"` +} + +// Specification of a synced database table.. +type SyncedTableSpec struct { + // Scheduling policy of the underlying pipeline. + SchedulingPolicy SyncedTableSchedulingPolicy `fieldmask:"scheduling_policy"` + // Three-part (catalog, schema, table) name of the source Delta table. + SourceTableFullName *string `fieldmask:"source_table_full_name"` + // Primary Key columns to be used for data insert/update in the destination. + PrimaryKeyColumns []string `fieldmask:"primary_key_columns"` + // Time series key to deduplicate (tie-break) rows with the same primary key. + TimeseriesKey *string `fieldmask:"timeseries_key"` + // At most one of existing_pipeline_id and new_pipeline_spec should be defined. + // + // If existing_pipeline_id is defined, the synced table will be bin packed into + // the existing pipeline referenced. This avoids creating a new pipeline and + // allows sharing existing compute. In this case, the scheduling_policy of this + // synced table must match the scheduling policy of the existing pipeline. + ExistingPipelineId *string `fieldmask:"existing_pipeline_id"` + // If true, the synced table's logical database and schema resources in PG will + // be created if they do not already exist. + CreateDatabaseObjectsIfMissing *bool `fieldmask:"create_database_objects_if_missing"` + // At most one of existing_pipeline_id and new_pipeline_spec should be defined. + // + // If new_pipeline_spec is defined, a new pipeline is created for this synced + // table. The location pointed to is used to store intermediate files + // (checkpoints, event logs etc). The caller must have write permissions to + // create Delta tables in the specified catalog and schema. Again, note this + // requires write permissions, whereas the source table only requires read + // permissions. + NewPipelineSpec *NewPipelineSpec `fieldmask:"new_pipeline_spec"` + // When true, enables accelerated sync mode for the initial data load. This + // significantly improves performance for large tables. Requires workspace-level + // enablement. + AcceleratedSync *bool `fieldmask:"accelerated_sync"` + // Override the default Delta->PG type mapping for specific columns. A + // TypeOverride with PG_SPECIFIC_TYPE_UNSPECIFIED is rejected; a valid pg_type + // must be set. + TypeOverrides []SyncedTableSpec_TypeOverride `fieldmask:"type_overrides"` +} + +// Overrides the default Delta-to-PostgreSQL type mapping for a single column.. +type SyncedTableSpec_TypeOverride struct { + // Name of the source column whose target PostgreSQL type should be overridden. + ColumnName *string + // PostgreSQL-specific target type to use for the column. + PgType SyncedTableSpec_PgSpecificType + // Size parameter for the target type, for types that take one (e.g. vector + // dimension, varchar length). Required when the chosen pg_type needs a size. + Size *int +} + +// Status of a synced table.. +type SyncedTableStatus struct { + // The state of the synced table. + DetailedState SyncedTableState `fieldmask:"detailed_state"` + // A text description of the current state of the synced table. + Message *string `fieldmask:"message"` + // The detailed status based on the synced table state. + DetailedStatus isSyncedTableStatus_DetailedStatus + // ID of the associated pipeline. The pipeline ID may have been provided by the + // client (in the case of bin packing), or generated by the server (when + // creating a new pipeline). + PipelineId *string `fieldmask:"pipeline_id"` + // Summary of the last successful synchronization from source to destination. + // + // Will always be present if there has been a successful sync. Even if the most + // recent syncs have failed. + // + // Limitation: The only exception is if the synced table is doing a FULL + // REFRESH, then the last sync information will not be available until the full + // refresh is complete. This limitation will be addressed in a future version. + // + // This top-level field is a convenience for consumers who want easy access to + // last sync information without having to traverse detailed_status. + LastSync *SyncedTablePosition `fieldmask:"last_sync"` + _ [0]syncedTableStatusDetailedStatusFieldMaskMetadata `fieldmask_oneof:"DetailedStatus"` +} + +type isSyncedTableStatus_DetailedStatus interface { + isSyncedTableStatus_DetailedStatus() +} + +// SyncedTableStatus_DetailedStatus_ProvisioningStatus selects ProvisioningStatus for SyncedTableStatus.DetailedStatus. +type SyncedTableStatus_DetailedStatus_ProvisioningStatus struct { + ProvisioningStatus SyncedTableProvisioningStatus `fieldmask:"provisioning_status"` +} + +func (*SyncedTableStatus_DetailedStatus_ProvisioningStatus) isSyncedTableStatus_DetailedStatus() {} + +// SyncedTableStatus_DetailedStatus_ContinuousUpdateStatus selects ContinuousUpdateStatus for SyncedTableStatus.DetailedStatus. +type SyncedTableStatus_DetailedStatus_ContinuousUpdateStatus struct { + ContinuousUpdateStatus SyncedTableContinuousUpdateStatus `fieldmask:"continuous_update_status"` +} + +func (*SyncedTableStatus_DetailedStatus_ContinuousUpdateStatus) isSyncedTableStatus_DetailedStatus() { +} + +// SyncedTableStatus_DetailedStatus_TriggeredUpdateStatus selects TriggeredUpdateStatus for SyncedTableStatus.DetailedStatus. +type SyncedTableStatus_DetailedStatus_TriggeredUpdateStatus struct { + TriggeredUpdateStatus SyncedTableTriggeredUpdateStatus `fieldmask:"triggered_update_status"` +} + +func (*SyncedTableStatus_DetailedStatus_TriggeredUpdateStatus) isSyncedTableStatus_DetailedStatus() {} + +// SyncedTableStatus_DetailedStatus_FailedStatus selects FailedStatus for SyncedTableStatus.DetailedStatus. +type SyncedTableStatus_DetailedStatus_FailedStatus struct { + FailedStatus SyncedTableFailedStatus `fieldmask:"failed_status"` +} + +func (*SyncedTableStatus_DetailedStatus_FailedStatus) isSyncedTableStatus_DetailedStatus() {} + +type syncedTableStatusDetailedStatusFieldMaskMetadata struct { + *SyncedTableStatus_DetailedStatus_ProvisioningStatus + *SyncedTableStatus_DetailedStatus_ContinuousUpdateStatus + *SyncedTableStatus_DetailedStatus_TriggeredUpdateStatus + *SyncedTableStatus_DetailedStatus_FailedStatus +} + +// Detailed status of a synced table. Shown if the synced table is in the +// SYNCED_TRIGGERED_UPDATE or the SYNCED_NO_PENDING_UPDATE state.. +type SyncedTableTriggeredUpdateStatus struct { + // The last source table Delta version that was successfully synced to the + // synced table. + LastProcessedCommitVersion *int64 `fieldmask:"last_processed_commit_version"` + // The end timestamp of the last time any data was synchronized from the source + // table to the synced table. This is when the data is available in the synced + // table. + Timestamp *types.Time `fieldmask:"timestamp"` + // Progress of the active data synchronization pipeline. + TriggeredUpdateProgress *SyncedTablePipelineProgress `fieldmask:"triggered_update_progress"` +} + +type UpdateDatabaseCatalogRequest struct { + // Note that updating a database catalog is not yet supported. + DatabaseCatalog *DatabaseCatalog + // The list of fields to update. Setting this field is not yet supported. + UpdateMask *types.FieldMask[DatabaseCatalog] +} + +type UpdateDatabaseInstanceRequest struct { + DatabaseInstance *DatabaseInstance + // The list of fields to update. If unspecified, all fields will be updated when + // possible. To wipe out custom_tags, specify custom_tags in the update_mask + // with an empty custom_tags map. + UpdateMask *types.FieldMask[DatabaseInstance] +} + +type UpdateSyncedDatabaseTableRequest struct { + // Note that updating a synced database table is not yet supported. + SyncedTable *SyncedDatabaseTable + // The list of fields to update. Setting this field is not yet supported. + UpdateMask *types.FieldMask[SyncedDatabaseTable] +} diff --git a/database/v1/wire.go b/database/v1/wire.go new file mode 100755 index 0000000..9944272 --- /dev/null +++ b/database/v1/wire.go @@ -0,0 +1,1356 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package database + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createDatabaseCatalogRequestWire struct { + Catalog *databaseCatalogWire `json:"catalog,omitempty"` +} + +func createDatabaseCatalogRequestToWire(v *CreateDatabaseCatalogRequest) (*createDatabaseCatalogRequestWire, error) { + if v == nil { + return nil, nil + } + catalogWireValue, err := databaseCatalogToWire(v.Catalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateDatabaseCatalogRequest.Catalog", err) + } + return &createDatabaseCatalogRequestWire{ + Catalog: catalogWireValue, + }, nil +} + +type createDatabaseInstanceRequestWire struct { + DatabaseInstance *databaseInstanceWire `json:"database_instance,omitempty"` +} + +func createDatabaseInstanceRequestToWire(v *CreateDatabaseInstanceRequest) (*createDatabaseInstanceRequestWire, error) { + if v == nil { + return nil, nil + } + databaseInstanceWireValue, err := databaseInstanceToWire(v.DatabaseInstance) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateDatabaseInstanceRequest.DatabaseInstance", err) + } + return &createDatabaseInstanceRequestWire{ + DatabaseInstance: databaseInstanceWireValue, + }, nil +} + +type createDatabaseInstanceRoleRequestWire struct { + InstanceName *string `json:"instance_name,omitempty"` + DatabaseInstanceRole *databaseInstanceRoleWire `json:"database_instance_role,omitempty"` + DatabaseInstanceName *string `json:"database_instance_name,omitempty"` +} + +func createDatabaseInstanceRoleRequestToWire(v *CreateDatabaseInstanceRoleRequest) (*createDatabaseInstanceRoleRequestWire, error) { + if v == nil { + return nil, nil + } + databaseInstanceRoleWireValue, err := databaseInstanceRoleToWire(v.DatabaseInstanceRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateDatabaseInstanceRoleRequest.DatabaseInstanceRole", err) + } + return &createDatabaseInstanceRoleRequestWire{ + InstanceName: v.InstanceName, + DatabaseInstanceRole: databaseInstanceRoleWireValue, + DatabaseInstanceName: v.DatabaseInstanceName, + }, nil +} + +type createDatabaseTableRequestWire struct { + Table *databaseTableWire `json:"table,omitempty"` +} + +func createDatabaseTableRequestToWire(v *CreateDatabaseTableRequest) (*createDatabaseTableRequestWire, error) { + if v == nil { + return nil, nil + } + tableWireValue, err := databaseTableToWire(v.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateDatabaseTableRequest.Table", err) + } + return &createDatabaseTableRequestWire{ + Table: tableWireValue, + }, nil +} + +type createSyncedDatabaseTableRequestWire struct { + SyncedTable *syncedDatabaseTableWire `json:"synced_table,omitempty"` +} + +func createSyncedDatabaseTableRequestToWire(v *CreateSyncedDatabaseTableRequest) (*createSyncedDatabaseTableRequestWire, error) { + if v == nil { + return nil, nil + } + syncedTableWireValue, err := syncedDatabaseTableToWire(v.SyncedTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateSyncedDatabaseTableRequest.SyncedTable", err) + } + return &createSyncedDatabaseTableRequestWire{ + SyncedTable: syncedTableWireValue, + }, nil +} + +type customTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func customTagToWire(v *CustomTag) (*customTagWire, error) { + if v == nil { + return nil, nil + } + return &customTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func customTagFromWire(w *customTagWire) (*CustomTag, error) { + if w == nil { + return nil, nil + } + return &CustomTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type databaseCatalogWire struct { + Name *string `json:"name,omitempty"` + DatabaseInstanceName *string `json:"database_instance_name,omitempty"` + DatabaseName *string `json:"database_name,omitempty"` + Uid *string `json:"uid,omitempty"` + CreateDatabaseIfNotExists *bool `json:"create_database_if_not_exists,omitempty"` +} + +func databaseCatalogToWire(v *DatabaseCatalog) (*databaseCatalogWire, error) { + if v == nil { + return nil, nil + } + return &databaseCatalogWire{ + Name: v.Name, + DatabaseInstanceName: v.DatabaseInstanceName, + DatabaseName: v.DatabaseName, + Uid: v.Uid, + CreateDatabaseIfNotExists: v.CreateDatabaseIfNotExists, + }, nil +} + +func databaseCatalogFromWire(w *databaseCatalogWire) (*DatabaseCatalog, error) { + if w == nil { + return nil, nil + } + return &DatabaseCatalog{ + Name: w.Name, + DatabaseInstanceName: w.DatabaseInstanceName, + DatabaseName: w.DatabaseName, + Uid: w.Uid, + CreateDatabaseIfNotExists: w.CreateDatabaseIfNotExists, + }, nil +} + +type databaseCredentialWire struct { + Token *string `json:"token,omitempty"` + ExpirationTime *types.Time `json:"expiration_time,omitempty"` +} + +func databaseCredentialFromWire(w *databaseCredentialWire) (*DatabaseCredential, error) { + if w == nil { + return nil, nil + } + return &DatabaseCredential{ + Token: w.Token, + ExpirationTime: w.ExpirationTime, + }, nil +} + +type databaseInstanceWire struct { + Uid *string `json:"uid,omitempty"` + Name *string `json:"name,omitempty"` + Creator *string `json:"creator,omitempty"` + ReadWriteDns *string `json:"read_write_dns,omitempty"` + CreationTime *types.Time `json:"creation_time,omitempty"` + State DatabaseInstance_State `json:"state,omitempty"` + PgVersion *string `json:"pg_version,omitempty"` + Capacity *string `json:"capacity,omitempty"` + EffectiveCapacity *string `json:"effective_capacity,omitempty"` + Stopped *bool `json:"stopped,omitempty"` + EffectiveStopped *bool `json:"effective_stopped,omitempty"` + NodeCount *int `json:"node_count,omitempty"` + EffectiveNodeCount *int `json:"effective_node_count,omitempty"` + EnableReadableSecondaries *bool `json:"enable_readable_secondaries,omitempty"` + EffectiveEnableReadableSecondaries *bool `json:"effective_enable_readable_secondaries,omitempty"` + ReadOnlyDns *string `json:"read_only_dns,omitempty"` + RetentionWindowInDays *int `json:"retention_window_in_days,omitempty"` + EffectiveRetentionWindowInDays *int `json:"effective_retention_window_in_days,omitempty"` + ParentInstanceRef *databaseInstanceRefWire `json:"parent_instance_ref,omitempty"` + ChildInstanceRefs []databaseInstanceRefWire `json:"child_instance_refs,omitempty"` + EnablePgNativeLogin *bool `json:"enable_pg_native_login,omitempty"` + EffectiveEnablePgNativeLogin *bool `json:"effective_enable_pg_native_login,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + EffectiveUsagePolicyId *string `json:"effective_usage_policy_id,omitempty"` + CustomTags []customTagWire `json:"custom_tags,omitempty"` + EffectiveCustomTags []customTagWire `json:"effective_custom_tags,omitempty"` +} + +func databaseInstanceToWire(v *DatabaseInstance) (*databaseInstanceWire, error) { + if v == nil { + return nil, nil + } + parentInstanceRefWireValue, err := databaseInstanceRefToWire(v.ParentInstanceRef) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstance.ParentInstanceRef", err) + } + childInstanceRefsWireValue, err := convertSlice(v.ChildInstanceRefs, databaseInstanceRefToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstance.ChildInstanceRefs", err) + } + customTagsWireValue, err := convertSlice(v.CustomTags, customTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstance.CustomTags", err) + } + effectiveCustomTagsWireValue, err := convertSlice(v.EffectiveCustomTags, customTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstance.EffectiveCustomTags", err) + } + return &databaseInstanceWire{ + Uid: v.Uid, + Name: v.Name, + Creator: v.Creator, + ReadWriteDns: v.ReadWriteDns, + CreationTime: v.CreationTime, + State: v.State, + PgVersion: v.PgVersion, + Capacity: v.Capacity, + EffectiveCapacity: v.EffectiveCapacity, + Stopped: v.Stopped, + EffectiveStopped: v.EffectiveStopped, + NodeCount: v.NodeCount, + EffectiveNodeCount: v.EffectiveNodeCount, + EnableReadableSecondaries: v.EnableReadableSecondaries, + EffectiveEnableReadableSecondaries: v.EffectiveEnableReadableSecondaries, + ReadOnlyDns: v.ReadOnlyDns, + RetentionWindowInDays: v.RetentionWindowInDays, + EffectiveRetentionWindowInDays: v.EffectiveRetentionWindowInDays, + ParentInstanceRef: parentInstanceRefWireValue, + ChildInstanceRefs: childInstanceRefsWireValue, + EnablePgNativeLogin: v.EnablePgNativeLogin, + EffectiveEnablePgNativeLogin: v.EffectiveEnablePgNativeLogin, + UsagePolicyId: v.UsagePolicyId, + EffectiveUsagePolicyId: v.EffectiveUsagePolicyId, + CustomTags: customTagsWireValue, + EffectiveCustomTags: effectiveCustomTagsWireValue, + }, nil +} + +func databaseInstanceFromWire(w *databaseInstanceWire) (*DatabaseInstance, error) { + if w == nil { + return nil, nil + } + parentInstanceRefPublicValue, err := databaseInstanceRefFromWire(w.ParentInstanceRef) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstance.ParentInstanceRef", err) + } + childInstanceRefsPublicValue, err := convertSlice(w.ChildInstanceRefs, databaseInstanceRefFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstance.ChildInstanceRefs", err) + } + customTagsPublicValue, err := convertSlice(w.CustomTags, customTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstance.CustomTags", err) + } + effectiveCustomTagsPublicValue, err := convertSlice(w.EffectiveCustomTags, customTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstance.EffectiveCustomTags", err) + } + return &DatabaseInstance{ + Uid: w.Uid, + Name: w.Name, + Creator: w.Creator, + ReadWriteDns: w.ReadWriteDns, + CreationTime: w.CreationTime, + State: w.State, + PgVersion: w.PgVersion, + Capacity: w.Capacity, + EffectiveCapacity: w.EffectiveCapacity, + Stopped: w.Stopped, + EffectiveStopped: w.EffectiveStopped, + NodeCount: w.NodeCount, + EffectiveNodeCount: w.EffectiveNodeCount, + EnableReadableSecondaries: w.EnableReadableSecondaries, + EffectiveEnableReadableSecondaries: w.EffectiveEnableReadableSecondaries, + ReadOnlyDns: w.ReadOnlyDns, + RetentionWindowInDays: w.RetentionWindowInDays, + EffectiveRetentionWindowInDays: w.EffectiveRetentionWindowInDays, + ParentInstanceRef: parentInstanceRefPublicValue, + ChildInstanceRefs: childInstanceRefsPublicValue, + EnablePgNativeLogin: w.EnablePgNativeLogin, + EffectiveEnablePgNativeLogin: w.EffectiveEnablePgNativeLogin, + UsagePolicyId: w.UsagePolicyId, + EffectiveUsagePolicyId: w.EffectiveUsagePolicyId, + CustomTags: customTagsPublicValue, + EffectiveCustomTags: effectiveCustomTagsPublicValue, + }, nil +} + +type databaseInstanceRefWire struct { + Uid *string `json:"uid,omitempty"` + Name *string `json:"name,omitempty"` + Lsn *string `json:"lsn,omitempty"` + EffectiveLsn *string `json:"effective_lsn,omitempty"` + BranchTime *types.Time `json:"branch_time,omitempty"` +} + +func databaseInstanceRefToWire(v *DatabaseInstanceRef) (*databaseInstanceRefWire, error) { + if v == nil { + return nil, nil + } + return &databaseInstanceRefWire{ + Uid: v.Uid, + Name: v.Name, + Lsn: v.Lsn, + EffectiveLsn: v.EffectiveLsn, + BranchTime: v.BranchTime, + }, nil +} + +func databaseInstanceRefFromWire(w *databaseInstanceRefWire) (*DatabaseInstanceRef, error) { + if w == nil { + return nil, nil + } + return &DatabaseInstanceRef{ + Uid: w.Uid, + Name: w.Name, + Lsn: w.Lsn, + EffectiveLsn: w.EffectiveLsn, + BranchTime: w.BranchTime, + }, nil +} + +type databaseInstanceRoleWire struct { + Name *string `json:"name,omitempty"` + IdentityType DatabaseInstanceRole_IdentityType `json:"identity_type,omitempty"` + MembershipRole DatabaseInstanceRole_MembershipRole `json:"membership_role,omitempty"` + Attributes *databaseInstanceRole_AttributesWire `json:"attributes,omitempty"` + EffectiveAttributes *databaseInstanceRole_AttributesWire `json:"effective_attributes,omitempty"` + InstanceName *string `json:"instance_name,omitempty"` +} + +func databaseInstanceRoleToWire(v *DatabaseInstanceRole) (*databaseInstanceRoleWire, error) { + if v == nil { + return nil, nil + } + attributesWireValue, err := databaseInstanceRole_AttributesToWire(v.Attributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstanceRole.Attributes", err) + } + effectiveAttributesWireValue, err := databaseInstanceRole_AttributesToWire(v.EffectiveAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstanceRole.EffectiveAttributes", err) + } + return &databaseInstanceRoleWire{ + Name: v.Name, + IdentityType: v.IdentityType, + MembershipRole: v.MembershipRole, + Attributes: attributesWireValue, + EffectiveAttributes: effectiveAttributesWireValue, + InstanceName: v.InstanceName, + }, nil +} + +func databaseInstanceRoleFromWire(w *databaseInstanceRoleWire) (*DatabaseInstanceRole, error) { + if w == nil { + return nil, nil + } + attributesPublicValue, err := databaseInstanceRole_AttributesFromWire(w.Attributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstanceRole.Attributes", err) + } + effectiveAttributesPublicValue, err := databaseInstanceRole_AttributesFromWire(w.EffectiveAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatabaseInstanceRole.EffectiveAttributes", err) + } + return &DatabaseInstanceRole{ + Name: w.Name, + IdentityType: w.IdentityType, + MembershipRole: w.MembershipRole, + Attributes: attributesPublicValue, + EffectiveAttributes: effectiveAttributesPublicValue, + InstanceName: w.InstanceName, + }, nil +} + +type databaseInstanceRole_AttributesWire struct { + Createdb *bool `json:"createdb,omitempty"` + Createrole *bool `json:"createrole,omitempty"` + Bypassrls *bool `json:"bypassrls,omitempty"` +} + +func databaseInstanceRole_AttributesToWire(v *DatabaseInstanceRole_Attributes) (*databaseInstanceRole_AttributesWire, error) { + if v == nil { + return nil, nil + } + return &databaseInstanceRole_AttributesWire{ + Createdb: v.Createdb, + Createrole: v.Createrole, + Bypassrls: v.Bypassrls, + }, nil +} + +func databaseInstanceRole_AttributesFromWire(w *databaseInstanceRole_AttributesWire) (*DatabaseInstanceRole_Attributes, error) { + if w == nil { + return nil, nil + } + return &DatabaseInstanceRole_Attributes{ + Createdb: w.Createdb, + Createrole: w.Createrole, + Bypassrls: w.Bypassrls, + }, nil +} + +type databaseTableWire struct { + Name *string `json:"name,omitempty"` + DatabaseInstanceName *string `json:"database_instance_name,omitempty"` + LogicalDatabaseName *string `json:"logical_database_name,omitempty"` +} + +func databaseTableToWire(v *DatabaseTable) (*databaseTableWire, error) { + if v == nil { + return nil, nil + } + return &databaseTableWire{ + Name: v.Name, + DatabaseInstanceName: v.DatabaseInstanceName, + LogicalDatabaseName: v.LogicalDatabaseName, + }, nil +} + +func databaseTableFromWire(w *databaseTableWire) (*DatabaseTable, error) { + if w == nil { + return nil, nil + } + return &DatabaseTable{ + Name: w.Name, + DatabaseInstanceName: w.DatabaseInstanceName, + LogicalDatabaseName: w.LogicalDatabaseName, + }, nil +} + +type deleteDatabaseInstanceRequestWire struct { + Name *string `json:"name,omitempty"` + Force *bool `json:"force,omitempty"` + Purge *bool `json:"purge,omitempty"` +} + +func deleteDatabaseInstanceRequestToWire(v *DeleteDatabaseInstanceRequest) (*deleteDatabaseInstanceRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteDatabaseInstanceRequestWire{ + Name: v.Name, + Force: v.Force, + Purge: v.Purge, + }, nil +} + +type deleteDatabaseInstanceRoleRequestWire struct { + InstanceName *string `json:"instance_name,omitempty"` + Name *string `json:"name,omitempty"` + ReassignOwnedTo *string `json:"reassign_owned_to,omitempty"` + AllowMissing *bool `json:"allow_missing,omitempty"` +} + +func deleteDatabaseInstanceRoleRequestToWire(v *DeleteDatabaseInstanceRoleRequest) (*deleteDatabaseInstanceRoleRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteDatabaseInstanceRoleRequestWire{ + InstanceName: v.InstanceName, + Name: v.Name, + ReassignOwnedTo: v.ReassignOwnedTo, + AllowMissing: v.AllowMissing, + }, nil +} + +type deleteSyncedDatabaseTableRequestWire struct { + Name *string `json:"name,omitempty"` + PurgeData *bool `json:"purge_data,omitempty"` +} + +func deleteSyncedDatabaseTableRequestToWire(v *DeleteSyncedDatabaseTableRequest) (*deleteSyncedDatabaseTableRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteSyncedDatabaseTableRequestWire{ + Name: v.Name, + PurgeData: v.PurgeData, + }, nil +} + +type deltaTableSyncInfoWire struct { + DeltaCommitVersion *int64 `json:"delta_commit_version,omitempty"` + DeltaCommitTimestamp *types.Time `json:"delta_commit_timestamp,omitempty"` +} + +func deltaTableSyncInfoToWire(v *DeltaTableSyncInfo) (*deltaTableSyncInfoWire, error) { + if v == nil { + return nil, nil + } + return &deltaTableSyncInfoWire{ + DeltaCommitVersion: v.DeltaCommitVersion, + DeltaCommitTimestamp: v.DeltaCommitTimestamp, + }, nil +} + +func deltaTableSyncInfoFromWire(w *deltaTableSyncInfoWire) (*DeltaTableSyncInfo, error) { + if w == nil { + return nil, nil + } + return &DeltaTableSyncInfo{ + DeltaCommitVersion: w.DeltaCommitVersion, + DeltaCommitTimestamp: w.DeltaCommitTimestamp, + }, nil +} + +type findDatabaseInstanceByUidRequestWire struct { + Uid *string `json:"uid,omitempty"` +} + +func findDatabaseInstanceByUidRequestToWire(v *FindDatabaseInstanceByUidRequest) (*findDatabaseInstanceByUidRequestWire, error) { + if v == nil { + return nil, nil + } + return &findDatabaseInstanceByUidRequestWire{ + Uid: v.Uid, + }, nil +} + +type generateDatabaseCredentialRequestWire struct { + RequestId *string `json:"request_id,omitempty"` + InstanceNames []string `json:"instance_names,omitempty"` + Claims []requestedClaimsWire `json:"claims,omitempty"` +} + +func generateDatabaseCredentialRequestToWire(v *GenerateDatabaseCredentialRequest) (*generateDatabaseCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + claimsWireValue, err := convertSlice(v.Claims, requestedClaimsToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateDatabaseCredentialRequest.Claims", err) + } + return &generateDatabaseCredentialRequestWire{ + RequestId: v.RequestId, + InstanceNames: v.InstanceNames, + Claims: claimsWireValue, + }, nil +} + +type listDatabaseCatalogsRequestWire struct { + InstanceName *string `json:"instance_name,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listDatabaseCatalogsRequestToWire(v *ListDatabaseCatalogsRequest) (*listDatabaseCatalogsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listDatabaseCatalogsRequestWire{ + InstanceName: v.InstanceName, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listDatabaseCatalogsResponseWire struct { + DatabaseCatalogs []databaseCatalogWire `json:"database_catalogs,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listDatabaseCatalogsResponseFromWire(w *listDatabaseCatalogsResponseWire) (*ListDatabaseCatalogsResponse, error) { + if w == nil { + return nil, nil + } + databaseCatalogsPublicValue, err := convertSlice(w.DatabaseCatalogs, databaseCatalogFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListDatabaseCatalogsResponse.DatabaseCatalogs", err) + } + return &ListDatabaseCatalogsResponse{ + DatabaseCatalogs: databaseCatalogsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listDatabaseInstanceRolesRequestWire struct { + InstanceName *string `json:"instance_name,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listDatabaseInstanceRolesRequestToWire(v *ListDatabaseInstanceRolesRequest) (*listDatabaseInstanceRolesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listDatabaseInstanceRolesRequestWire{ + InstanceName: v.InstanceName, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listDatabaseInstanceRolesResponseWire struct { + DatabaseInstanceRoles []databaseInstanceRoleWire `json:"database_instance_roles,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listDatabaseInstanceRolesResponseFromWire(w *listDatabaseInstanceRolesResponseWire) (*ListDatabaseInstanceRolesResponse, error) { + if w == nil { + return nil, nil + } + databaseInstanceRolesPublicValue, err := convertSlice(w.DatabaseInstanceRoles, databaseInstanceRoleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListDatabaseInstanceRolesResponse.DatabaseInstanceRoles", err) + } + return &ListDatabaseInstanceRolesResponse{ + DatabaseInstanceRoles: databaseInstanceRolesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listDatabaseInstancesRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listDatabaseInstancesRequestToWire(v *ListDatabaseInstancesRequest) (*listDatabaseInstancesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listDatabaseInstancesRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listDatabaseInstancesResponseWire struct { + DatabaseInstances []databaseInstanceWire `json:"database_instances,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listDatabaseInstancesResponseFromWire(w *listDatabaseInstancesResponseWire) (*ListDatabaseInstancesResponse, error) { + if w == nil { + return nil, nil + } + databaseInstancesPublicValue, err := convertSlice(w.DatabaseInstances, databaseInstanceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListDatabaseInstancesResponse.DatabaseInstances", err) + } + return &ListDatabaseInstancesResponse{ + DatabaseInstances: databaseInstancesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listSyncedDatabaseTablesRequestWire struct { + InstanceName *string `json:"instance_name,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listSyncedDatabaseTablesRequestToWire(v *ListSyncedDatabaseTablesRequest) (*listSyncedDatabaseTablesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSyncedDatabaseTablesRequestWire{ + InstanceName: v.InstanceName, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listSyncedDatabaseTablesResponseWire struct { + SyncedTables []syncedDatabaseTableWire `json:"synced_tables,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listSyncedDatabaseTablesResponseFromWire(w *listSyncedDatabaseTablesResponseWire) (*ListSyncedDatabaseTablesResponse, error) { + if w == nil { + return nil, nil + } + syncedTablesPublicValue, err := convertSlice(w.SyncedTables, syncedDatabaseTableFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListSyncedDatabaseTablesResponse.SyncedTables", err) + } + return &ListSyncedDatabaseTablesResponse{ + SyncedTables: syncedTablesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type newPipelineSpecWire struct { + StorageCatalog *string `json:"storage_catalog,omitempty"` + StorageSchema *string `json:"storage_schema,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` +} + +func newPipelineSpecToWire(v *NewPipelineSpec) (*newPipelineSpecWire, error) { + if v == nil { + return nil, nil + } + return &newPipelineSpecWire{ + StorageCatalog: v.StorageCatalog, + StorageSchema: v.StorageSchema, + BudgetPolicyId: v.BudgetPolicyId, + }, nil +} + +func newPipelineSpecFromWire(w *newPipelineSpecWire) (*NewPipelineSpec, error) { + if w == nil { + return nil, nil + } + return &NewPipelineSpec{ + StorageCatalog: w.StorageCatalog, + StorageSchema: w.StorageSchema, + BudgetPolicyId: w.BudgetPolicyId, + }, nil +} + +type requestedClaimsWire struct { + PermissionSet RequestedClaims_PermissionSet `json:"permission_set,omitempty"` + Resources []requestedResourceWire `json:"resources,omitempty"` +} + +func requestedClaimsToWire(v *RequestedClaims) (*requestedClaimsWire, error) { + if v == nil { + return nil, nil + } + resourcesWireValue, err := convertSlice(v.Resources, requestedResourceToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RequestedClaims.Resources", err) + } + return &requestedClaimsWire{ + PermissionSet: v.PermissionSet, + Resources: resourcesWireValue, + }, nil +} + +type requestedResourceWire struct { + UnspecifiedResourceName *string `json:"unspecified_resource_name,omitempty"` + TableName *string `json:"table_name,omitempty"` +} + +func requestedResourceToWire(v *RequestedResource) (*requestedResourceWire, error) { + if v == nil { + return nil, nil + } + var resourceNameUnspecifiedResourceNameWire *string + var resourceNameTableNameWire *string + switch value := v.ResourceName.(type) { + case nil: + case *RequestedResource_ResourceName_UnspecifiedResourceName: + if value != nil { + resourceNameUnspecifiedResourceNameWire = new(value.UnspecifiedResourceName) + } + case *RequestedResource_ResourceName_TableName: + if value != nil { + resourceNameTableNameWire = new(value.TableName) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "RequestedResource.ResourceName", value) + } + return &requestedResourceWire{ + UnspecifiedResourceName: resourceNameUnspecifiedResourceNameWire, + TableName: resourceNameTableNameWire, + }, nil +} + +type syncedDatabaseTableWire struct { + Name *string `json:"name,omitempty"` + DatabaseInstanceName *string `json:"database_instance_name,omitempty"` + EffectiveDatabaseInstanceName *string `json:"effective_database_instance_name,omitempty"` + LogicalDatabaseName *string `json:"logical_database_name,omitempty"` + EffectiveLogicalDatabaseName *string `json:"effective_logical_database_name,omitempty"` + Spec *syncedTableSpecWire `json:"spec,omitempty"` + UnityCatalogProvisioningState ProvisioningInfo_State `json:"unity_catalog_provisioning_state,omitempty"` + DataSynchronizationStatus *syncedTableStatusWire `json:"data_synchronization_status,omitempty"` +} + +func syncedDatabaseTableToWire(v *SyncedDatabaseTable) (*syncedDatabaseTableWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := syncedTableSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedDatabaseTable.Spec", err) + } + dataSynchronizationStatusWireValue, err := syncedTableStatusToWire(v.DataSynchronizationStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedDatabaseTable.DataSynchronizationStatus", err) + } + return &syncedDatabaseTableWire{ + Name: v.Name, + DatabaseInstanceName: v.DatabaseInstanceName, + EffectiveDatabaseInstanceName: v.EffectiveDatabaseInstanceName, + LogicalDatabaseName: v.LogicalDatabaseName, + EffectiveLogicalDatabaseName: v.EffectiveLogicalDatabaseName, + Spec: specWireValue, + UnityCatalogProvisioningState: v.UnityCatalogProvisioningState, + DataSynchronizationStatus: dataSynchronizationStatusWireValue, + }, nil +} + +func syncedDatabaseTableFromWire(w *syncedDatabaseTableWire) (*SyncedDatabaseTable, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := syncedTableSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedDatabaseTable.Spec", err) + } + dataSynchronizationStatusPublicValue, err := syncedTableStatusFromWire(w.DataSynchronizationStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedDatabaseTable.DataSynchronizationStatus", err) + } + return &SyncedDatabaseTable{ + Name: w.Name, + DatabaseInstanceName: w.DatabaseInstanceName, + EffectiveDatabaseInstanceName: w.EffectiveDatabaseInstanceName, + LogicalDatabaseName: w.LogicalDatabaseName, + EffectiveLogicalDatabaseName: w.EffectiveLogicalDatabaseName, + Spec: specPublicValue, + UnityCatalogProvisioningState: w.UnityCatalogProvisioningState, + DataSynchronizationStatus: dataSynchronizationStatusPublicValue, + }, nil +} + +type syncedTableContinuousUpdateStatusWire struct { + LastProcessedCommitVersion *int64 `json:"last_processed_commit_version,omitempty"` + Timestamp *types.Time `json:"timestamp,omitempty"` + InitialPipelineSyncProgress *syncedTablePipelineProgressWire `json:"initial_pipeline_sync_progress,omitempty"` +} + +func syncedTableContinuousUpdateStatusToWire(v *SyncedTableContinuousUpdateStatus) (*syncedTableContinuousUpdateStatusWire, error) { + if v == nil { + return nil, nil + } + initialPipelineSyncProgressWireValue, err := syncedTablePipelineProgressToWire(v.InitialPipelineSyncProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableContinuousUpdateStatus.InitialPipelineSyncProgress", err) + } + return &syncedTableContinuousUpdateStatusWire{ + LastProcessedCommitVersion: v.LastProcessedCommitVersion, + Timestamp: v.Timestamp, + InitialPipelineSyncProgress: initialPipelineSyncProgressWireValue, + }, nil +} + +func syncedTableContinuousUpdateStatusFromWire(w *syncedTableContinuousUpdateStatusWire) (*SyncedTableContinuousUpdateStatus, error) { + if w == nil { + return nil, nil + } + initialPipelineSyncProgressPublicValue, err := syncedTablePipelineProgressFromWire(w.InitialPipelineSyncProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableContinuousUpdateStatus.InitialPipelineSyncProgress", err) + } + return &SyncedTableContinuousUpdateStatus{ + LastProcessedCommitVersion: w.LastProcessedCommitVersion, + Timestamp: w.Timestamp, + InitialPipelineSyncProgress: initialPipelineSyncProgressPublicValue, + }, nil +} + +type syncedTableFailedStatusWire struct { + LastProcessedCommitVersion *int64 `json:"last_processed_commit_version,omitempty"` + Timestamp *types.Time `json:"timestamp,omitempty"` +} + +func syncedTableFailedStatusToWire(v *SyncedTableFailedStatus) (*syncedTableFailedStatusWire, error) { + if v == nil { + return nil, nil + } + return &syncedTableFailedStatusWire{ + LastProcessedCommitVersion: v.LastProcessedCommitVersion, + Timestamp: v.Timestamp, + }, nil +} + +func syncedTableFailedStatusFromWire(w *syncedTableFailedStatusWire) (*SyncedTableFailedStatus, error) { + if w == nil { + return nil, nil + } + return &SyncedTableFailedStatus{ + LastProcessedCommitVersion: w.LastProcessedCommitVersion, + Timestamp: w.Timestamp, + }, nil +} + +type syncedTablePipelineProgressWire struct { + LatestVersionCurrentlyProcessing *int64 `json:"latest_version_currently_processing,omitempty"` + SyncedRowCount *int64 `json:"synced_row_count,omitempty"` + TotalRowCount *int64 `json:"total_row_count,omitempty"` + SyncProgressCompletion *float64 `json:"sync_progress_completion,omitempty"` + EstimatedCompletionTimeSeconds *float64 `json:"estimated_completion_time_seconds,omitempty"` + ProvisioningPhase ProvisioningPhase `json:"provisioning_phase,omitempty"` +} + +func syncedTablePipelineProgressToWire(v *SyncedTablePipelineProgress) (*syncedTablePipelineProgressWire, error) { + if v == nil { + return nil, nil + } + return &syncedTablePipelineProgressWire{ + LatestVersionCurrentlyProcessing: v.LatestVersionCurrentlyProcessing, + SyncedRowCount: v.SyncedRowCount, + TotalRowCount: v.TotalRowCount, + SyncProgressCompletion: v.SyncProgressCompletion, + EstimatedCompletionTimeSeconds: v.EstimatedCompletionTimeSeconds, + ProvisioningPhase: v.ProvisioningPhase, + }, nil +} + +func syncedTablePipelineProgressFromWire(w *syncedTablePipelineProgressWire) (*SyncedTablePipelineProgress, error) { + if w == nil { + return nil, nil + } + return &SyncedTablePipelineProgress{ + LatestVersionCurrentlyProcessing: w.LatestVersionCurrentlyProcessing, + SyncedRowCount: w.SyncedRowCount, + TotalRowCount: w.TotalRowCount, + SyncProgressCompletion: w.SyncProgressCompletion, + EstimatedCompletionTimeSeconds: w.EstimatedCompletionTimeSeconds, + ProvisioningPhase: w.ProvisioningPhase, + }, nil +} + +type syncedTablePositionWire struct { + SyncStartTimestamp *types.Time `json:"sync_start_timestamp,omitempty"` + SyncEndTimestamp *types.Time `json:"sync_end_timestamp,omitempty"` + DeltaTableSyncInfo *deltaTableSyncInfoWire `json:"delta_table_sync_info,omitempty"` +} + +func syncedTablePositionToWire(v *SyncedTablePosition) (*syncedTablePositionWire, error) { + if v == nil { + return nil, nil + } + var sourceSyncInfoDeltaTableSyncInfoWire *deltaTableSyncInfoWire + switch value := v.SourceSyncInfo.(type) { + case nil: + case *SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo: + if value != nil { + sourceSyncInfoDeltaTableSyncInfoConverted, err := deltaTableSyncInfoToWire(&value.DeltaTableSyncInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTablePosition.SourceSyncInfo.DeltaTableSyncInfo", err) + } + sourceSyncInfoDeltaTableSyncInfoWire = sourceSyncInfoDeltaTableSyncInfoConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SyncedTablePosition.SourceSyncInfo", value) + } + return &syncedTablePositionWire{ + SyncStartTimestamp: v.SyncStartTimestamp, + SyncEndTimestamp: v.SyncEndTimestamp, + DeltaTableSyncInfo: sourceSyncInfoDeltaTableSyncInfoWire, + }, nil +} + +func syncedTablePositionFromWire(w *syncedTablePositionWire) (*SyncedTablePosition, error) { + if w == nil { + return nil, nil + } + sourceSyncInfoMembers := 0 + if w.DeltaTableSyncInfo != nil { + sourceSyncInfoMembers++ + } + if sourceSyncInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SyncedTablePosition.SourceSyncInfo") + } + var sourceSyncInfoSelection isSyncedTablePosition_SourceSyncInfo + switch { + case w.DeltaTableSyncInfo != nil: + sourceSyncInfoDeltaTableSyncInfoConverted, err := deltaTableSyncInfoFromWire(w.DeltaTableSyncInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTablePosition.SourceSyncInfo.DeltaTableSyncInfo", err) + } + sourceSyncInfoSelection = &SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo{DeltaTableSyncInfo: *sourceSyncInfoDeltaTableSyncInfoConverted} + } + return &SyncedTablePosition{ + SyncStartTimestamp: w.SyncStartTimestamp, + SyncEndTimestamp: w.SyncEndTimestamp, + SourceSyncInfo: sourceSyncInfoSelection, + }, nil +} + +type syncedTableProvisioningStatusWire struct { + InitialPipelineSyncProgress *syncedTablePipelineProgressWire `json:"initial_pipeline_sync_progress,omitempty"` +} + +func syncedTableProvisioningStatusToWire(v *SyncedTableProvisioningStatus) (*syncedTableProvisioningStatusWire, error) { + if v == nil { + return nil, nil + } + initialPipelineSyncProgressWireValue, err := syncedTablePipelineProgressToWire(v.InitialPipelineSyncProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableProvisioningStatus.InitialPipelineSyncProgress", err) + } + return &syncedTableProvisioningStatusWire{ + InitialPipelineSyncProgress: initialPipelineSyncProgressWireValue, + }, nil +} + +func syncedTableProvisioningStatusFromWire(w *syncedTableProvisioningStatusWire) (*SyncedTableProvisioningStatus, error) { + if w == nil { + return nil, nil + } + initialPipelineSyncProgressPublicValue, err := syncedTablePipelineProgressFromWire(w.InitialPipelineSyncProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableProvisioningStatus.InitialPipelineSyncProgress", err) + } + return &SyncedTableProvisioningStatus{ + InitialPipelineSyncProgress: initialPipelineSyncProgressPublicValue, + }, nil +} + +type syncedTableSpecWire struct { + SchedulingPolicy SyncedTableSchedulingPolicy `json:"scheduling_policy,omitempty"` + SourceTableFullName *string `json:"source_table_full_name,omitempty"` + PrimaryKeyColumns []string `json:"primary_key_columns,omitempty"` + TimeseriesKey *string `json:"timeseries_key,omitempty"` + ExistingPipelineId *string `json:"existing_pipeline_id,omitempty"` + CreateDatabaseObjectsIfMissing *bool `json:"create_database_objects_if_missing,omitempty"` + NewPipelineSpec *newPipelineSpecWire `json:"new_pipeline_spec,omitempty"` + AcceleratedSync *bool `json:"accelerated_sync,omitempty"` + TypeOverrides []syncedTableSpec_TypeOverrideWire `json:"type_overrides,omitempty"` +} + +func syncedTableSpecToWire(v *SyncedTableSpec) (*syncedTableSpecWire, error) { + if v == nil { + return nil, nil + } + newPipelineSpecWireValue, err := newPipelineSpecToWire(v.NewPipelineSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableSpec.NewPipelineSpec", err) + } + typeOverridesWireValue, err := convertSlice(v.TypeOverrides, syncedTableSpec_TypeOverrideToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableSpec.TypeOverrides", err) + } + return &syncedTableSpecWire{ + SchedulingPolicy: v.SchedulingPolicy, + SourceTableFullName: v.SourceTableFullName, + PrimaryKeyColumns: v.PrimaryKeyColumns, + TimeseriesKey: v.TimeseriesKey, + ExistingPipelineId: v.ExistingPipelineId, + CreateDatabaseObjectsIfMissing: v.CreateDatabaseObjectsIfMissing, + NewPipelineSpec: newPipelineSpecWireValue, + AcceleratedSync: v.AcceleratedSync, + TypeOverrides: typeOverridesWireValue, + }, nil +} + +func syncedTableSpecFromWire(w *syncedTableSpecWire) (*SyncedTableSpec, error) { + if w == nil { + return nil, nil + } + newPipelineSpecPublicValue, err := newPipelineSpecFromWire(w.NewPipelineSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableSpec.NewPipelineSpec", err) + } + typeOverridesPublicValue, err := convertSlice(w.TypeOverrides, syncedTableSpec_TypeOverrideFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableSpec.TypeOverrides", err) + } + return &SyncedTableSpec{ + SchedulingPolicy: w.SchedulingPolicy, + SourceTableFullName: w.SourceTableFullName, + PrimaryKeyColumns: w.PrimaryKeyColumns, + TimeseriesKey: w.TimeseriesKey, + ExistingPipelineId: w.ExistingPipelineId, + CreateDatabaseObjectsIfMissing: w.CreateDatabaseObjectsIfMissing, + NewPipelineSpec: newPipelineSpecPublicValue, + AcceleratedSync: w.AcceleratedSync, + TypeOverrides: typeOverridesPublicValue, + }, nil +} + +type syncedTableSpec_TypeOverrideWire struct { + ColumnName *string `json:"column_name,omitempty"` + PgType SyncedTableSpec_PgSpecificType `json:"pg_type,omitempty"` + Size *int `json:"size,omitempty"` +} + +func syncedTableSpec_TypeOverrideToWire(v *SyncedTableSpec_TypeOverride) (*syncedTableSpec_TypeOverrideWire, error) { + if v == nil { + return nil, nil + } + return &syncedTableSpec_TypeOverrideWire{ + ColumnName: v.ColumnName, + PgType: v.PgType, + Size: v.Size, + }, nil +} + +func syncedTableSpec_TypeOverrideFromWire(w *syncedTableSpec_TypeOverrideWire) (*SyncedTableSpec_TypeOverride, error) { + if w == nil { + return nil, nil + } + return &SyncedTableSpec_TypeOverride{ + ColumnName: w.ColumnName, + PgType: w.PgType, + Size: w.Size, + }, nil +} + +type syncedTableStatusWire struct { + DetailedState SyncedTableState `json:"detailed_state,omitempty"` + Message *string `json:"message,omitempty"` + ProvisioningStatus *syncedTableProvisioningStatusWire `json:"provisioning_status,omitempty"` + ContinuousUpdateStatus *syncedTableContinuousUpdateStatusWire `json:"continuous_update_status,omitempty"` + TriggeredUpdateStatus *syncedTableTriggeredUpdateStatusWire `json:"triggered_update_status,omitempty"` + FailedStatus *syncedTableFailedStatusWire `json:"failed_status,omitempty"` + PipelineId *string `json:"pipeline_id,omitempty"` + LastSync *syncedTablePositionWire `json:"last_sync,omitempty"` +} + +func syncedTableStatusToWire(v *SyncedTableStatus) (*syncedTableStatusWire, error) { + if v == nil { + return nil, nil + } + lastSyncWireValue, err := syncedTablePositionToWire(v.LastSync) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableStatus.LastSync", err) + } + var detailedStatusProvisioningStatusWire *syncedTableProvisioningStatusWire + var detailedStatusContinuousUpdateStatusWire *syncedTableContinuousUpdateStatusWire + var detailedStatusTriggeredUpdateStatusWire *syncedTableTriggeredUpdateStatusWire + var detailedStatusFailedStatusWire *syncedTableFailedStatusWire + switch value := v.DetailedStatus.(type) { + case nil: + case *SyncedTableStatus_DetailedStatus_ProvisioningStatus: + if value != nil { + detailedStatusProvisioningStatusConverted, err := syncedTableProvisioningStatusToWire(&value.ProvisioningStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableStatus.DetailedStatus.ProvisioningStatus", err) + } + detailedStatusProvisioningStatusWire = detailedStatusProvisioningStatusConverted + } + case *SyncedTableStatus_DetailedStatus_ContinuousUpdateStatus: + if value != nil { + detailedStatusContinuousUpdateStatusConverted, err := syncedTableContinuousUpdateStatusToWire(&value.ContinuousUpdateStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableStatus.DetailedStatus.ContinuousUpdateStatus", err) + } + detailedStatusContinuousUpdateStatusWire = detailedStatusContinuousUpdateStatusConverted + } + case *SyncedTableStatus_DetailedStatus_TriggeredUpdateStatus: + if value != nil { + detailedStatusTriggeredUpdateStatusConverted, err := syncedTableTriggeredUpdateStatusToWire(&value.TriggeredUpdateStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableStatus.DetailedStatus.TriggeredUpdateStatus", err) + } + detailedStatusTriggeredUpdateStatusWire = detailedStatusTriggeredUpdateStatusConverted + } + case *SyncedTableStatus_DetailedStatus_FailedStatus: + if value != nil { + detailedStatusFailedStatusConverted, err := syncedTableFailedStatusToWire(&value.FailedStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableStatus.DetailedStatus.FailedStatus", err) + } + detailedStatusFailedStatusWire = detailedStatusFailedStatusConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SyncedTableStatus.DetailedStatus", value) + } + return &syncedTableStatusWire{ + DetailedState: v.DetailedState, + Message: v.Message, + ProvisioningStatus: detailedStatusProvisioningStatusWire, + ContinuousUpdateStatus: detailedStatusContinuousUpdateStatusWire, + TriggeredUpdateStatus: detailedStatusTriggeredUpdateStatusWire, + FailedStatus: detailedStatusFailedStatusWire, + PipelineId: v.PipelineId, + LastSync: lastSyncWireValue, + }, nil +} + +func syncedTableStatusFromWire(w *syncedTableStatusWire) (*SyncedTableStatus, error) { + if w == nil { + return nil, nil + } + detailedStatusMembers := 0 + if w.ProvisioningStatus != nil { + detailedStatusMembers++ + } + if w.ContinuousUpdateStatus != nil { + detailedStatusMembers++ + } + if w.TriggeredUpdateStatus != nil { + detailedStatusMembers++ + } + if w.FailedStatus != nil { + detailedStatusMembers++ + } + if detailedStatusMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SyncedTableStatus.DetailedStatus") + } + lastSyncPublicValue, err := syncedTablePositionFromWire(w.LastSync) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableStatus.LastSync", err) + } + var detailedStatusSelection isSyncedTableStatus_DetailedStatus + switch { + case w.ProvisioningStatus != nil: + detailedStatusProvisioningStatusConverted, err := syncedTableProvisioningStatusFromWire(w.ProvisioningStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableStatus.DetailedStatus.ProvisioningStatus", err) + } + detailedStatusSelection = &SyncedTableStatus_DetailedStatus_ProvisioningStatus{ProvisioningStatus: *detailedStatusProvisioningStatusConverted} + case w.ContinuousUpdateStatus != nil: + detailedStatusContinuousUpdateStatusConverted, err := syncedTableContinuousUpdateStatusFromWire(w.ContinuousUpdateStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableStatus.DetailedStatus.ContinuousUpdateStatus", err) + } + detailedStatusSelection = &SyncedTableStatus_DetailedStatus_ContinuousUpdateStatus{ContinuousUpdateStatus: *detailedStatusContinuousUpdateStatusConverted} + case w.TriggeredUpdateStatus != nil: + detailedStatusTriggeredUpdateStatusConverted, err := syncedTableTriggeredUpdateStatusFromWire(w.TriggeredUpdateStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableStatus.DetailedStatus.TriggeredUpdateStatus", err) + } + detailedStatusSelection = &SyncedTableStatus_DetailedStatus_TriggeredUpdateStatus{TriggeredUpdateStatus: *detailedStatusTriggeredUpdateStatusConverted} + case w.FailedStatus != nil: + detailedStatusFailedStatusConverted, err := syncedTableFailedStatusFromWire(w.FailedStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableStatus.DetailedStatus.FailedStatus", err) + } + detailedStatusSelection = &SyncedTableStatus_DetailedStatus_FailedStatus{FailedStatus: *detailedStatusFailedStatusConverted} + } + return &SyncedTableStatus{ + DetailedState: w.DetailedState, + Message: w.Message, + PipelineId: w.PipelineId, + LastSync: lastSyncPublicValue, + DetailedStatus: detailedStatusSelection, + }, nil +} + +type syncedTableTriggeredUpdateStatusWire struct { + LastProcessedCommitVersion *int64 `json:"last_processed_commit_version,omitempty"` + Timestamp *types.Time `json:"timestamp,omitempty"` + TriggeredUpdateProgress *syncedTablePipelineProgressWire `json:"triggered_update_progress,omitempty"` +} + +func syncedTableTriggeredUpdateStatusToWire(v *SyncedTableTriggeredUpdateStatus) (*syncedTableTriggeredUpdateStatusWire, error) { + if v == nil { + return nil, nil + } + triggeredUpdateProgressWireValue, err := syncedTablePipelineProgressToWire(v.TriggeredUpdateProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableTriggeredUpdateStatus.TriggeredUpdateProgress", err) + } + return &syncedTableTriggeredUpdateStatusWire{ + LastProcessedCommitVersion: v.LastProcessedCommitVersion, + Timestamp: v.Timestamp, + TriggeredUpdateProgress: triggeredUpdateProgressWireValue, + }, nil +} + +func syncedTableTriggeredUpdateStatusFromWire(w *syncedTableTriggeredUpdateStatusWire) (*SyncedTableTriggeredUpdateStatus, error) { + if w == nil { + return nil, nil + } + triggeredUpdateProgressPublicValue, err := syncedTablePipelineProgressFromWire(w.TriggeredUpdateProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTableTriggeredUpdateStatus.TriggeredUpdateProgress", err) + } + return &SyncedTableTriggeredUpdateStatus{ + LastProcessedCommitVersion: w.LastProcessedCommitVersion, + Timestamp: w.Timestamp, + TriggeredUpdateProgress: triggeredUpdateProgressPublicValue, + }, nil +} + +type updateDatabaseCatalogRequestWire struct { + DatabaseCatalog *databaseCatalogWire `json:"database_catalog,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateDatabaseCatalogRequestToWire(v *UpdateDatabaseCatalogRequest) (*updateDatabaseCatalogRequestWire, error) { + if v == nil { + return nil, nil + } + databaseCatalogWireValue, err := databaseCatalogToWire(v.DatabaseCatalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateDatabaseCatalogRequest.DatabaseCatalog", err) + } + return &updateDatabaseCatalogRequestWire{ + DatabaseCatalog: databaseCatalogWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateDatabaseInstanceRequestWire struct { + DatabaseInstance *databaseInstanceWire `json:"database_instance,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateDatabaseInstanceRequestToWire(v *UpdateDatabaseInstanceRequest) (*updateDatabaseInstanceRequestWire, error) { + if v == nil { + return nil, nil + } + databaseInstanceWireValue, err := databaseInstanceToWire(v.DatabaseInstance) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateDatabaseInstanceRequest.DatabaseInstance", err) + } + return &updateDatabaseInstanceRequestWire{ + DatabaseInstance: databaseInstanceWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateSyncedDatabaseTableRequestWire struct { + SyncedTable *syncedDatabaseTableWire `json:"synced_table,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateSyncedDatabaseTableRequestToWire(v *UpdateSyncedDatabaseTableRequest) (*updateSyncedDatabaseTableRequestWire, error) { + if v == nil { + return nil, nil + } + syncedTableWireValue, err := syncedDatabaseTableToWire(v.SyncedTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateSyncedDatabaseTableRequest.SyncedTable", err) + } + return &updateSyncedDatabaseTableRequestWire{ + SyncedTable: syncedTableWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/dataclassification/.package.json b/dataclassification/.package.json new file mode 100644 index 0000000..5b90a64 --- /dev/null +++ b/dataclassification/.package.json @@ -0,0 +1,3 @@ +{ + "package": "dataclassification" +} diff --git a/dataclassification/CHANGELOG.md b/dataclassification/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/dataclassification/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/dataclassification/README.md b/dataclassification/README.md new file mode 100644 index 0000000..65b225d --- /dev/null +++ b/dataclassification/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/dataclassification + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/dataclassification@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/dataclassification/v1" + +client, err := dataclassification.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/dataclassification/go.mod b/dataclassification/go.mod new file mode 100644 index 0000000..80c896b --- /dev/null +++ b/dataclassification/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/dataclassification + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/dataclassification/internal/version.go b/dataclassification/internal/version.go new file mode 100644 index 0000000..4ba2755 --- /dev/null +++ b/dataclassification/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-dataclassification" + +const Version = "0.0.1-dev.1" diff --git a/dataclassification/v1/client.go b/dataclassification/v1/client.go new file mode 100755 index 0000000..7695338 --- /dev/null +++ b/dataclassification/v1/client.go @@ -0,0 +1,332 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package dataclassification + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/dataclassification/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create Data Classification configuration for a catalog. +// +// Creates a new config resource, which enables Data Classification for the +// specified catalog. - The config must not already exist for the catalog. +func (c *internalClient) CreateCatalogConfig(ctx context.Context, req *CreateCatalogConfigRequest, opts ...call.Option) (*CatalogConfig, error) { + wireReq, err := createCatalogConfigRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.CatalogConfig) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/data-classification/v1/") + pb.singleSegment(*req.Parent) + pb.literal("/config") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CatalogConfig + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp catalogConfigWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = catalogConfigFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete Data Classification configuration for a catalog. +func (c *internalClient) DeleteCatalogConfig(ctx context.Context, req *DeleteCatalogConfigRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/data-classification/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Get the Data Classification configuration for a catalog. +func (c *internalClient) GetCatalogConfig(ctx context.Context, req *GetCatalogConfigRequest, opts ...call.Option) (*CatalogConfig, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/data-classification/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CatalogConfig + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp catalogConfigWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = catalogConfigFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update the Data Classification configuration for a catalog. - The config must +// already exist for the catalog. - Updates fields specified in the update_mask. +// Use update_mask field to perform partial updates of the configuration. +func (c *internalClient) UpdateCatalogConfig(ctx context.Context, req *UpdateCatalogConfigRequest, opts ...call.Option) (*CatalogConfig, error) { + wireReq, err := updateCatalogConfigRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.CatalogConfig) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/data-classification/v1/") + pb.singleSegment(*req.CatalogConfig.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CatalogConfig + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp catalogConfigWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = catalogConfigFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/dataclassification/v1/genhelper.go b/dataclassification/v1/genhelper.go new file mode 100755 index 0000000..6f31f26 --- /dev/null +++ b/dataclassification/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package dataclassification + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/dataclassification/v1/model.go b/dataclassification/v1/model.go new file mode 100755 index 0000000..cad4e14 --- /dev/null +++ b/dataclassification/v1/model.go @@ -0,0 +1,114 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package dataclassification + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// Auto-tagging mode. +type AutoTaggingConfig_AutoTaggingMode string + +const ( + AutoTaggingConfig_AutoTaggingMode_Unspecified AutoTaggingConfig_AutoTaggingMode = "" + AutoTaggingConfig_AutoTaggingMode_AutoTaggingDisabled AutoTaggingConfig_AutoTaggingMode = "AUTO_TAGGING_DISABLED" + AutoTaggingConfig_AutoTaggingMode_AutoTaggingEnabled AutoTaggingConfig_AutoTaggingMode = "AUTO_TAGGING_ENABLED" +) + +// Auto-tagging configuration for a classification tag. When enabled, detected +// columns are automatically tagged with Unity Catalog tags.. +type AutoTaggingConfig struct { + // The Classification Tag. For built-in classes this is a system tag (e.g., + // "class.name", "class.location"); for custom classes it is a user-defined + // governance tag key. + ClassificationTag *string + // Whether auto-tagging is enabled or disabled for this classification tag. + AutoTaggingMode AutoTaggingConfig_AutoTaggingMode +} + +// Data Classification configuration for a Unity Catalog catalog. This message +// follows the "At Most One Resource" pattern: at most one CatalogConfig exists +// per catalog. - Full CRUD operations are supported: Create enables Data +// Classification, Delete disables it - It has no unique identifier of its own +// and uses its parent catalog's identifier (catalog_name). +type CatalogConfig struct { + // Resource name in the format: catalogs/{catalog_name}/config. + Name *string `fieldmask:"name"` + SelectedSchemas isCatalogConfig_SelectedSchemas + // List of auto-tagging configurations for this catalog. Empty list means no + // auto-tagging is enabled. + AutoTagConfigs []AutoTaggingConfig `fieldmask:"auto_tag_configs"` + _ [0]catalogConfigSelectedSchemasFieldMaskMetadata `fieldmask_oneof:"SelectedSchemas"` +} + +type isCatalogConfig_SelectedSchemas interface { + isCatalogConfig_SelectedSchemas() +} + +// CatalogConfig_SelectedSchemas_IncludedSchemas selects IncludedSchemas for CatalogConfig.SelectedSchemas. +// Schemas to include in the scan, each named relative to the parent catalog. If +// specified, only listed schemas will be scanned. Mutually exclusive with +// `excluded_schemas`: only one may be set per request. If neither +// `included_schemas` nor `excluded_schemas` is set, all schemas are scanned. +type CatalogConfig_SelectedSchemas_IncludedSchemas struct { + IncludedSchemas CatalogConfig_SchemaNames `fieldmask:"included_schemas"` +} + +func (*CatalogConfig_SelectedSchemas_IncludedSchemas) isCatalogConfig_SelectedSchemas() {} + +// CatalogConfig_SelectedSchemas_ExcludedSchemas selects ExcludedSchemas for CatalogConfig.SelectedSchemas. +// Schemas to exclude from the scan, each named relative to the parent catalog. +// If specified, all schemas except the specified ones will be scanned. Mutually +// exclusive with `included_schemas`: only one may be set per request. If +// neither `included_schemas` nor `excluded_schemas` is set, all schemas are +// scanned. +type CatalogConfig_SelectedSchemas_ExcludedSchemas struct { + ExcludedSchemas CatalogConfig_SchemaNames `fieldmask:"excluded_schemas"` +} + +func (*CatalogConfig_SelectedSchemas_ExcludedSchemas) isCatalogConfig_SelectedSchemas() {} + +type catalogConfigSelectedSchemasFieldMaskMetadata struct { + *CatalogConfig_SelectedSchemas_IncludedSchemas + *CatalogConfig_SelectedSchemas_ExcludedSchemas +} + +// Wrapper message for a list of schema names.. +type CatalogConfig_SchemaNames struct { + // Schema names, each relative to the parent catalog. Must not be empty. + Names []string `fieldmask:"names"` +} + +// Create Data Classification configuration for a catalog. Creating a config +// enables Data Classification for the catalog.. +type CreateCatalogConfigRequest struct { + // Parent resource in the format: catalogs/{catalog_name} + Parent *string + // The configuration to create. + CatalogConfig *CatalogConfig +} + +// Delete Data Classification configuration for a catalog. Deleting the config +// disables Data Classification for the catalog.. +type DeleteCatalogConfigRequest struct { + // Resource name in the format: catalogs/{catalog_name}/config + Name *string +} + +// Get Data Classification configuration for a catalog.. +type GetCatalogConfigRequest struct { + // Resource name in the format: catalogs/{catalog_name}/config + Name *string +} + +// Request to update the Data Classification configuration for a catalog. +// +// Uses field mask to support partial updates of the configuration. Only the +// fields specified in the update_mask will be modified.. +type UpdateCatalogConfigRequest struct { + // The configuration to apply to the catalog. The name field in catalog_config + // identifies which resource to update. + CatalogConfig *CatalogConfig + // Field mask specifying which fields to update. + UpdateMask *types.FieldMask[CatalogConfig] +} diff --git a/dataclassification/v1/wire.go b/dataclassification/v1/wire.go new file mode 100755 index 0000000..0eaad5e --- /dev/null +++ b/dataclassification/v1/wire.go @@ -0,0 +1,203 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package dataclassification + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type autoTaggingConfigWire struct { + ClassificationTag *string `json:"classification_tag,omitempty"` + AutoTaggingMode AutoTaggingConfig_AutoTaggingMode `json:"auto_tagging_mode,omitempty"` +} + +func autoTaggingConfigToWire(v *AutoTaggingConfig) (*autoTaggingConfigWire, error) { + if v == nil { + return nil, nil + } + return &autoTaggingConfigWire{ + ClassificationTag: v.ClassificationTag, + AutoTaggingMode: v.AutoTaggingMode, + }, nil +} + +func autoTaggingConfigFromWire(w *autoTaggingConfigWire) (*AutoTaggingConfig, error) { + if w == nil { + return nil, nil + } + return &AutoTaggingConfig{ + ClassificationTag: w.ClassificationTag, + AutoTaggingMode: w.AutoTaggingMode, + }, nil +} + +type catalogConfigWire struct { + Name *string `json:"name,omitempty"` + IncludedSchemas *catalogConfig_SchemaNamesWire `json:"included_schemas,omitempty"` + ExcludedSchemas *catalogConfig_SchemaNamesWire `json:"excluded_schemas,omitempty"` + AutoTagConfigs []autoTaggingConfigWire `json:"auto_tag_configs,omitempty"` +} + +func catalogConfigToWire(v *CatalogConfig) (*catalogConfigWire, error) { + if v == nil { + return nil, nil + } + autoTagConfigsWireValue, err := convertSlice(v.AutoTagConfigs, autoTaggingConfigToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CatalogConfig.AutoTagConfigs", err) + } + var selectedSchemasIncludedSchemasWire *catalogConfig_SchemaNamesWire + var selectedSchemasExcludedSchemasWire *catalogConfig_SchemaNamesWire + switch value := v.SelectedSchemas.(type) { + case nil: + case *CatalogConfig_SelectedSchemas_IncludedSchemas: + if value != nil { + selectedSchemasIncludedSchemasConverted, err := catalogConfig_SchemaNamesToWire(&value.IncludedSchemas) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CatalogConfig.SelectedSchemas.IncludedSchemas", err) + } + selectedSchemasIncludedSchemasWire = selectedSchemasIncludedSchemasConverted + } + case *CatalogConfig_SelectedSchemas_ExcludedSchemas: + if value != nil { + selectedSchemasExcludedSchemasConverted, err := catalogConfig_SchemaNamesToWire(&value.ExcludedSchemas) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CatalogConfig.SelectedSchemas.ExcludedSchemas", err) + } + selectedSchemasExcludedSchemasWire = selectedSchemasExcludedSchemasConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CatalogConfig.SelectedSchemas", value) + } + return &catalogConfigWire{ + Name: v.Name, + IncludedSchemas: selectedSchemasIncludedSchemasWire, + ExcludedSchemas: selectedSchemasExcludedSchemasWire, + AutoTagConfigs: autoTagConfigsWireValue, + }, nil +} + +func catalogConfigFromWire(w *catalogConfigWire) (*CatalogConfig, error) { + if w == nil { + return nil, nil + } + selectedSchemasMembers := 0 + if w.IncludedSchemas != nil { + selectedSchemasMembers++ + } + if w.ExcludedSchemas != nil { + selectedSchemasMembers++ + } + if selectedSchemasMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "CatalogConfig.SelectedSchemas") + } + autoTagConfigsPublicValue, err := convertSlice(w.AutoTagConfigs, autoTaggingConfigFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CatalogConfig.AutoTagConfigs", err) + } + var selectedSchemasSelection isCatalogConfig_SelectedSchemas + switch { + case w.IncludedSchemas != nil: + selectedSchemasIncludedSchemasConverted, err := catalogConfig_SchemaNamesFromWire(w.IncludedSchemas) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CatalogConfig.SelectedSchemas.IncludedSchemas", err) + } + selectedSchemasSelection = &CatalogConfig_SelectedSchemas_IncludedSchemas{IncludedSchemas: *selectedSchemasIncludedSchemasConverted} + case w.ExcludedSchemas != nil: + selectedSchemasExcludedSchemasConverted, err := catalogConfig_SchemaNamesFromWire(w.ExcludedSchemas) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CatalogConfig.SelectedSchemas.ExcludedSchemas", err) + } + selectedSchemasSelection = &CatalogConfig_SelectedSchemas_ExcludedSchemas{ExcludedSchemas: *selectedSchemasExcludedSchemasConverted} + } + return &CatalogConfig{ + Name: w.Name, + AutoTagConfigs: autoTagConfigsPublicValue, + SelectedSchemas: selectedSchemasSelection, + }, nil +} + +type catalogConfig_SchemaNamesWire struct { + Names []string `json:"names,omitempty"` +} + +func catalogConfig_SchemaNamesToWire(v *CatalogConfig_SchemaNames) (*catalogConfig_SchemaNamesWire, error) { + if v == nil { + return nil, nil + } + return &catalogConfig_SchemaNamesWire{ + Names: v.Names, + }, nil +} + +func catalogConfig_SchemaNamesFromWire(w *catalogConfig_SchemaNamesWire) (*CatalogConfig_SchemaNames, error) { + if w == nil { + return nil, nil + } + return &CatalogConfig_SchemaNames{ + Names: w.Names, + }, nil +} + +type createCatalogConfigRequestWire struct { + Parent *string `json:"parent,omitempty"` + CatalogConfig *catalogConfigWire `json:"catalog_config,omitempty"` +} + +func createCatalogConfigRequestToWire(v *CreateCatalogConfigRequest) (*createCatalogConfigRequestWire, error) { + if v == nil { + return nil, nil + } + catalogConfigWireValue, err := catalogConfigToWire(v.CatalogConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCatalogConfigRequest.CatalogConfig", err) + } + return &createCatalogConfigRequestWire{ + Parent: v.Parent, + CatalogConfig: catalogConfigWireValue, + }, nil +} + +type updateCatalogConfigRequestWire struct { + CatalogConfig *catalogConfigWire `json:"catalog_config,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateCatalogConfigRequestToWire(v *UpdateCatalogConfigRequest) (*updateCatalogConfigRequestWire, error) { + if v == nil { + return nil, nil + } + catalogConfigWireValue, err := catalogConfigToWire(v.CatalogConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCatalogConfigRequest.CatalogConfig", err) + } + return &updateCatalogConfigRequestWire{ + CatalogConfig: catalogConfigWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/dataquality/.package.json b/dataquality/.package.json new file mode 100644 index 0000000..6871191 --- /dev/null +++ b/dataquality/.package.json @@ -0,0 +1,3 @@ +{ + "package": "dataquality" +} diff --git a/dataquality/CHANGELOG.md b/dataquality/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/dataquality/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/dataquality/README.md b/dataquality/README.md new file mode 100644 index 0000000..0bb92b3 --- /dev/null +++ b/dataquality/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/dataquality + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/dataquality@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/dataquality/v1" + +client, err := dataquality.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/dataquality/go.mod b/dataquality/go.mod new file mode 100644 index 0000000..2f2a640 --- /dev/null +++ b/dataquality/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/dataquality + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/dataquality/internal/version.go b/dataquality/internal/version.go new file mode 100644 index 0000000..3db83fc --- /dev/null +++ b/dataquality/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-dataquality" + +const Version = "0.0.1-dev.1" diff --git a/dataquality/v1/client.go b/dataquality/v1/client.go new file mode 100755 index 0000000..28c5b51 --- /dev/null +++ b/dataquality/v1/client.go @@ -0,0 +1,1004 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package dataquality + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/dataquality/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Cancels a data quality monitor refresh. Currently only supported for the +// `table` `object_type`. The call must be made in the same workspace as where +// the monitor was created. +// +// The caller must have either of the following sets of permissions: 1. +// **MANAGE** and **USE_CATALOG** on the table's parent catalog. 2. +// **USE_CATALOG** on the table's parent catalog, and **MANAGE** and +// **USE_SCHEMA** on the table's parent schema. 3. **USE_CATALOG** on the +// table's parent catalog, **USE_SCHEMA** on the table's parent schema, and +// **MANAGE** on the table. +func (c *internalClient) CancelRefresh(ctx context.Context, req *CancelRefreshRequest, opts ...call.Option) (*CancelRefreshResponse, error) { + wireReq, err := cancelRefreshRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/data-quality/v1/monitors/") + pb.singleSegment(*req.ObjectType) + pb.literal("/") + pb.singleSegment(*req.ObjectId) + pb.literal("/refreshes/") + pb.singleSegment(*req.RefreshId) + pb.literal("/cancel") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CancelRefreshResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cancelRefreshResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cancelRefreshResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a data quality monitor on a Unity Catalog object. The caller must +// provide either `anomaly_detection_config` for a schema monitor or +// `data_profiling_config` for a table monitor. +// +// For the `table` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the table's parent +// catalog, **USE_SCHEMA** on the table's parent schema, and **SELECT** on the +// table 2. **USE_CATALOG** on the table's parent catalog, **MANAGE** and +// **USE_SCHEMA** on the table's parent schema, and **SELECT** on the table. 3. +// **USE_CATALOG** on the table's parent catalog, **USE_SCHEMA** on the table's +// parent schema, and **MANAGE** and **SELECT** on the table. +// +// Workspace assets, such as the dashboard, will be created in the workspace +// where this call was made. +// +// For the `schema` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the schema's parent +// catalog. 2. **USE_CATALOG** on the schema's parent catalog, and **MANAGE** +// and **USE_SCHEMA** on the schema. +func (c *internalClient) CreateMonitor(ctx context.Context, req *CreateMonitorRequest, opts ...call.Option) (*Monitor, error) { + wireReq, err := createMonitorRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Monitor) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/data-quality/v1/monitors" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Monitor + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp monitorWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = monitorFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a refresh. Currently only supported for the `table` `object_type`. +// The call must be made in the same workspace as where the monitor was created. +// +// The caller must have either of the following sets of permissions: 1. +// **MANAGE** and **USE_CATALOG** on the table's parent catalog. 2. +// **USE_CATALOG** on the table's parent catalog, and **MANAGE** and +// **USE_SCHEMA** on the table's parent schema. 3. **USE_CATALOG** on the +// table's parent catalog, **USE_SCHEMA** on the table's parent schema, and +// **MANAGE** on the table. +func (c *internalClient) CreateRefresh(ctx context.Context, req *CreateRefreshRequest, opts ...call.Option) (*Refresh, error) { + wireReq, err := createRefreshRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Refresh) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/data-quality/v1/monitors/") + pb.singleSegment(*req.Refresh.ObjectType) + pb.literal("/") + pb.singleSegment(*req.Refresh.ObjectId) + pb.literal("/refreshes") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Refresh + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp refreshWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = refreshFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a data quality monitor on Unity Catalog object. +// +// For the `table` `object_type`, the caller must have either of the following +// sets of permissions: **MANAGE** and **USE_CATALOG** on the table's parent +// catalog. **USE_CATALOG** on the table's parent catalog, and **MANAGE** and +// **USE_SCHEMA** on the table's parent schema. **USE_CATALOG** on the table's +// parent catalog, **USE_SCHEMA** on the table's parent schema, and **MANAGE** +// on the table. +// +// Note that the metric tables and dashboard will not be deleted as part of this +// call; those assets must be manually cleaned up (if desired). +// +// For the `schema` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the schema's parent +// catalog. 2. **USE_CATALOG** on the schema's parent catalog, and **MANAGE** +// and **USE_SCHEMA** on the schema. +func (c *internalClient) DeleteMonitor(ctx context.Context, req *DeleteMonitorRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/data-quality/v1/monitors/") + pb.singleSegment(*req.ObjectType) + pb.literal("/") + pb.singleSegment(*req.ObjectId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// (Unimplemented) Delete a refresh +func (c *internalClient) DeleteRefresh(ctx context.Context, req *DeleteRefreshRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/data-quality/v1/monitors/") + pb.singleSegment(*req.ObjectType) + pb.literal("/") + pb.singleSegment(*req.ObjectId) + pb.literal("/refreshes/") + pb.singleSegment(*req.RefreshId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Read a data quality monitor on a Unity Catalog object. +// +// For the `table` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the table's parent +// catalog. 2. **USE_CATALOG** on the table's parent catalog, and **MANAGE** and +// **USE_SCHEMA** on the table's parent schema. 3. **USE_CATALOG** on the +// table's parent catalog, **USE_SCHEMA** on the table's parent schema, and +// **SELECT** on the table. +// +// For the `schema` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the schema's parent +// catalog. 2. **USE_CATALOG** on the schema's parent catalog, and +// **USE_SCHEMA** on the schema. +// +// The returned information includes configuration values on the entity and +// parent entity as well as information on assets created by the monitor. Some +// information (e.g. dashboard) may be filtered out if the caller is in a +// different workspace than where the monitor was created. +func (c *internalClient) GetMonitor(ctx context.Context, req *GetMonitorRequest, opts ...call.Option) (*Monitor, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/data-quality/v1/monitors/") + pb.singleSegment(*req.ObjectType) + pb.literal("/") + pb.singleSegment(*req.ObjectId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Monitor + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp monitorWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = monitorFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get data quality monitor refresh. The call must be made in the same workspace +// as where the monitor was created. +// +// For the `table` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the table's parent +// catalog. 2. **USE_CATALOG** on the table's parent catalog, and **MANAGE** and +// **USE_SCHEMA** on the table's parent schema. 3. **USE_CATALOG** on the +// table's parent catalog, **USE_SCHEMA** on the table's parent schema, and +// **SELECT** on the table. +// +// For the `schema` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the schema's parent +// catalog. 2. **USE_CATALOG** on the schema's parent catalog, and +// **USE_SCHEMA** on the schema. +func (c *internalClient) GetRefresh(ctx context.Context, req *GetRefreshRequest, opts ...call.Option) (*Refresh, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/data-quality/v1/monitors/") + pb.singleSegment(*req.ObjectType) + pb.literal("/") + pb.singleSegment(*req.ObjectId) + pb.literal("/refreshes/") + pb.singleSegment(*req.RefreshId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Refresh + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp refreshWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = refreshFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// (Unimplemented) List data quality monitors. +func (c *internalClient) ListMonitor(ctx context.Context, req *ListMonitorRequest, opts ...call.Option) (*ListMonitorResponse, error) { + wireReq, err := listMonitorRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/data-quality/v1/monitors" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListMonitorResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listMonitorResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listMonitorResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListMonitorIter returns an iterator that iterates +// over the results of ListMonitor. +// +// For example: +// +// for item, err := range c.ListMonitorIter(ctx, &ListMonitorRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListMonitor call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListMonitor directly. +func (c *internalClient) ListMonitorIter(ctx context.Context, req *ListMonitorRequest, opts ...call.Option) iter.Seq2[*Monitor, error] { + return func(yield func(*Monitor, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListMonitorRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListMonitor(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Monitors { + if !yield(&resp.Monitors[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List data quality monitor refreshes. The call must be made in the same +// workspace as where the monitor was created. +// +// For the `table` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the table's parent +// catalog. 2. **USE_CATALOG** on the table's parent catalog, and **MANAGE** and +// **USE_SCHEMA** on the table's parent schema. 3. **USE_CATALOG** on the +// table's parent catalog, **USE_SCHEMA** on the table's parent schema, and +// **SELECT** on the table. +// +// For the `schema` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the schema's parent +// catalog. 2. **USE_CATALOG** on the schema's parent catalog, and +// **USE_SCHEMA** on the schema. +func (c *internalClient) ListRefresh(ctx context.Context, req *ListRefreshRequest, opts ...call.Option) (*ListRefreshResponse, error) { + wireReq, err := listRefreshRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/data-quality/v1/monitors/") + pb.singleSegment(*req.ObjectType) + pb.literal("/") + pb.singleSegment(*req.ObjectId) + pb.literal("/refreshes") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListRefreshResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listRefreshResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listRefreshResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListRefreshIter returns an iterator that iterates +// over the results of ListRefresh. +// +// For example: +// +// for item, err := range c.ListRefreshIter(ctx, &ListRefreshRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListRefresh call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListRefresh directly. +func (c *internalClient) ListRefreshIter(ctx context.Context, req *ListRefreshRequest, opts ...call.Option) iter.Seq2[*Refresh, error] { + return func(yield func(*Refresh, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListRefreshRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListRefresh(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Refreshes { + if !yield(&resp.Refreshes[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Update a data quality monitor on Unity Catalog object. +// +// For the `table` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the table's parent +// catalog. 2. **USE_CATALOG** on the table's parent catalog, and **MANAGE** and +// **USE_SCHEMA** on the table's parent schema. 3. **USE_CATALOG** on the +// table's parent catalog, **USE_SCHEMA** on the table's parent schema, and +// **MANAGE** on the table. +// +// For the `schema` `object_type`, the caller must have either of the following +// sets of permissions: 1. **MANAGE** and **USE_CATALOG** on the schema's parent +// catalog. 2. **USE_CATALOG** on the schema's parent catalog, and **MANAGE** +// and **USE_SCHEMA** on the schema. +func (c *internalClient) UpdateMonitor(ctx context.Context, req *UpdateMonitorRequest, opts ...call.Option) (*Monitor, error) { + wireReq, err := updateMonitorRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Monitor) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/data-quality/v1/monitors/") + pb.singleSegment(*req.ObjectType) + pb.literal("/") + pb.singleSegment(*req.ObjectId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Monitor + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp monitorWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = monitorFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// (Unimplemented) Update a refresh +func (c *internalClient) UpdateRefresh(ctx context.Context, req *UpdateRefreshRequest, opts ...call.Option) (*Refresh, error) { + wireReq, err := updateRefreshRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Refresh) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/data-quality/v1/monitors/") + pb.singleSegment(*req.ObjectType) + pb.literal("/") + pb.singleSegment(*req.ObjectId) + pb.literal("/refreshes/") + pb.singleSegment(*req.RefreshId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Refresh + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp refreshWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = refreshFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/dataquality/v1/genhelper.go b/dataquality/v1/genhelper.go new file mode 100755 index 0000000..25e969e --- /dev/null +++ b/dataquality/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package dataquality + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/dataquality/v1/model.go b/dataquality/v1/model.go new file mode 100755 index 0000000..f7851cc --- /dev/null +++ b/dataquality/v1/model.go @@ -0,0 +1,584 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package dataquality + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// The granularity for aggregating data into time windows based on their +// timestamp. +type AggregationGranularity string + +const ( + AggregationGranularity_Unspecified AggregationGranularity = "" + // 5 minutes. + AggregationGranularity_AggregationGranularity5Minutes AggregationGranularity = "AGGREGATION_GRANULARITY_5_MINUTES" + // 30 minutes. + AggregationGranularity_AggregationGranularity30Minutes AggregationGranularity = "AGGREGATION_GRANULARITY_30_MINUTES" + // 1 hour. + AggregationGranularity_AggregationGranularity1Hour AggregationGranularity = "AGGREGATION_GRANULARITY_1_HOUR" + // 1 day. + AggregationGranularity_AggregationGranularity1Day AggregationGranularity = "AGGREGATION_GRANULARITY_1_DAY" + // 1 week. + AggregationGranularity_AggregationGranularity1Week AggregationGranularity = "AGGREGATION_GRANULARITY_1_WEEK" + // 2 weeks. + AggregationGranularity_AggregationGranularity2Weeks AggregationGranularity = "AGGREGATION_GRANULARITY_2_WEEKS" + // 3 weeks. + AggregationGranularity_AggregationGranularity3Weeks AggregationGranularity = "AGGREGATION_GRANULARITY_3_WEEKS" + // 4 weeks. + AggregationGranularity_AggregationGranularity4Weeks AggregationGranularity = "AGGREGATION_GRANULARITY_4_WEEKS" + // 1 month. + AggregationGranularity_AggregationGranularity1Month AggregationGranularity = "AGGREGATION_GRANULARITY_1_MONTH" + // 1 year. + AggregationGranularity_AggregationGranularity1Year AggregationGranularity = "AGGREGATION_GRANULARITY_1_YEAR" +) + +// The data quality monitoring workflow cron schedule pause status. +type CronSchedulePauseStatus string + +const ( + CronSchedulePauseStatus_Unspecified CronSchedulePauseStatus = "" + // The cron schedule is not paused. + CronSchedulePauseStatus_CronSchedulePauseStatusUnpaused CronSchedulePauseStatus = "CRON_SCHEDULE_PAUSE_STATUS_UNPAUSED" + // The cron schedule is paused. + CronSchedulePauseStatus_CronSchedulePauseStatusPaused CronSchedulePauseStatus = "CRON_SCHEDULE_PAUSE_STATUS_PAUSED" +) + +// The custom metric type. +type DataProfilingCustomMetricType string + +const ( + DataProfilingCustomMetricType_Unspecified DataProfilingCustomMetricType = "" + // Only depend on the existing columns in the table. + DataProfilingCustomMetricType_DataProfilingCustomMetricTypeAggregate DataProfilingCustomMetricType = "DATA_PROFILING_CUSTOM_METRIC_TYPE_AGGREGATE" + // Only depend on previously computed aggregate metrics. + DataProfilingCustomMetricType_DataProfilingCustomMetricTypeDerived DataProfilingCustomMetricType = "DATA_PROFILING_CUSTOM_METRIC_TYPE_DERIVED" + // Depend on previously computed aggregate or derived metrics. + DataProfilingCustomMetricType_DataProfilingCustomMetricTypeDrift DataProfilingCustomMetricType = "DATA_PROFILING_CUSTOM_METRIC_TYPE_DRIFT" +) + +// The status of the data profiling monitor. +type DataProfilingStatus string + +const ( + DataProfilingStatus_Unspecified DataProfilingStatus = "" + DataProfilingStatus_DataProfilingStatusActive DataProfilingStatus = "DATA_PROFILING_STATUS_ACTIVE" + DataProfilingStatus_DataProfilingStatusPending DataProfilingStatus = "DATA_PROFILING_STATUS_PENDING" + DataProfilingStatus_DataProfilingStatusDeletePending DataProfilingStatus = "DATA_PROFILING_STATUS_DELETE_PENDING" + DataProfilingStatus_DataProfilingStatusError DataProfilingStatus = "DATA_PROFILING_STATUS_ERROR" + DataProfilingStatus_DataProfilingStatusFailed DataProfilingStatus = "DATA_PROFILING_STATUS_FAILED" +) + +// Inference problem type the model aims to solve. +type InferenceProblemType string + +const ( + InferenceProblemType_Unspecified InferenceProblemType = "" + // Classification inference problem. + InferenceProblemType_InferenceProblemTypeClassification InferenceProblemType = "INFERENCE_PROBLEM_TYPE_CLASSIFICATION" + // Regression inference problem. + InferenceProblemType_InferenceProblemTypeRegression InferenceProblemType = "INFERENCE_PROBLEM_TYPE_REGRESSION" +) + +// The state of the refresh. +type RefreshState string + +const ( + RefreshState_Unspecified RefreshState = "" + // The refresh is pending. + RefreshState_MonitorRefreshStatePending RefreshState = "MONITOR_REFRESH_STATE_PENDING" + // The refresh is running. + RefreshState_MonitorRefreshStateRunning RefreshState = "MONITOR_REFRESH_STATE_RUNNING" + // The refresh is successful. + RefreshState_MonitorRefreshStateSuccess RefreshState = "MONITOR_REFRESH_STATE_SUCCESS" + // The refresh has failed. + RefreshState_MonitorRefreshStateFailed RefreshState = "MONITOR_REFRESH_STATE_FAILED" + // The refresh is cancelled. + RefreshState_MonitorRefreshStateCanceled RefreshState = "MONITOR_REFRESH_STATE_CANCELED" +) + +// The trigger of the refresh. +type RefreshTrigger string + +const ( + RefreshTrigger_Unspecified RefreshTrigger = "" + // The refresh has been triggered manually. + RefreshTrigger_MonitorRefreshTriggerManual RefreshTrigger = "MONITOR_REFRESH_TRIGGER_MANUAL" + // The refresh has been triggered from a schedule. + RefreshTrigger_MonitorRefreshTriggerSchedule RefreshTrigger = "MONITOR_REFRESH_TRIGGER_SCHEDULE" + // The refresh has been triggered from a data change. + RefreshTrigger_MonitorRefreshTriggerDataChange RefreshTrigger = "MONITOR_REFRESH_TRIGGER_DATA_CHANGE" +) + +// Anomaly Detection Configurations.. +type AnomalyDetectionConfig struct { + // List of fully qualified table names to exclude from anomaly detection. + ExcludedTableFullNames []string `fieldmask:"excluded_table_full_names"` +} + +// Request to cancel a refresh.. +type CancelRefreshRequest struct { + // The type of the monitored object. Can be one of the following: `schema` or + // `table`. + ObjectType *string + // The UUID of the request object. It is `schema_id` for `schema`, and + // `table_id` for `table`. + // + // Find the `schema_id` from either: 1. The [schema_id] of the `Schemas` + // resource. 2. In [Catalog Explorer] > select the `schema` > go to the + // `Details` tab > the `Schema ID` field. + // + // Find the `table_id` from either: 1. The [table_id] of the `Tables` resource. + // 2. In [Catalog Explorer] > select the `table` > go to the `Details` tab > the + // `Table ID` field. + // + // [Catalog Explorer]: https://docs.databricks.com/aws/en/catalog-explorer/ + // [schema_id]: https://docs.databricks.com/api/workspace/schemas/get#schema_id + // [table_id]: https://docs.databricks.com/api/workspace/tables/get#table_id + ObjectId *string + // Unique id of the refresh operation. + RefreshId *int64 +} + +// Response to cancelling a refresh.. +type CancelRefreshResponse struct { + // The refresh to cancel. + Refresh *Refresh +} + +// Request to create a Monitor.. +type CreateMonitorRequest struct { + // The monitor to create. + Monitor *Monitor +} + +// Request to create a refresh.. +type CreateRefreshRequest struct { + // The refresh to create + Refresh *Refresh +} + +// The data quality monitoring workflow cron schedule.. +type CronSchedule struct { + // The expression that determines when to run the monitor. See [examples]. + // + // [examples]: https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html + QuartzCronExpression *string `fieldmask:"quartz_cron_expression"` + // A Java timezone id. The schedule for a job will be resolved with respect to + // this timezone. See `Java TimeZone + // `_ for + // details. The timezone id (e.g., ``America/Los_Angeles``) in which to evaluate + // the quartz expression. + TimezoneId *string `fieldmask:"timezone_id"` + // Read only field that indicates whether the schedule is paused or not. + PauseStatus CronSchedulePauseStatus `fieldmask:"pause_status"` +} + +// Data Profiling Configurations.. +type DataProfilingConfig struct { + // ID of the schema where output tables are created. + OutputSchemaId *string `fieldmask:"output_schema_id"` + // Field for specifying the absolute path to a custom directory to store + // data-monitoring assets. Normally prepopulated to a default user location via + // UI and Python APIs. + AssetsDir *string `fieldmask:"assets_dir"` + // (--[Create:REQ Update:REQ]--) Analysis config which is used to determine + // analysis logic. + AnalysisConfig isDataProfilingConfig_AnalysisConfig + // List of column expressions to slice data with for targeted analysis. The data + // is grouped by each expression independently, resulting in a separate slice + // for each predicate and its complements. For example + // `slicing_exprs=[“col_1”, “col_2 > 10”]` will generate the following + // slices: two slices for `col_2 > 10` (True and False), and one slice per + // unique value in `col1`. For high-cardinality columns, only the top 100 unique + // values by frequency will generate slices. + SlicingExprs []string `fieldmask:"slicing_exprs"` + // Custom metrics. + CustomMetrics []DataProfilingCustomMetric `fieldmask:"custom_metrics"` + // Baseline table name. Baseline data is used to compute drift from the data in + // the monitored `table_name`. The baseline table and the monitored table shall + // have the same schema. + BaselineTableName *string `fieldmask:"baseline_table_name"` + // The cron schedule. + Schedule *CronSchedule `fieldmask:"schedule"` + // Field for specifying notification settings. + NotificationSettings *NotificationSettings `fieldmask:"notification_settings"` + // Whether to skip creating a default dashboard summarizing data quality + // metrics. + SkipBuiltinDashboard *bool `fieldmask:"skip_builtin_dashboard"` + // Optional argument to specify the warehouse for dashboard creation. If not + // specified, the first running warehouse will be used. + WarehouseId *string `fieldmask:"warehouse_id"` + // Unity Catalog table to monitor. Format: `catalog.schema.table_name` + MonitoredTableName *string `fieldmask:"monitored_table_name"` + // The data profiling monitor status. + Status DataProfilingStatus `fieldmask:"status"` + // The latest error message for a monitor failure. + LatestMonitorFailureMessage *string `fieldmask:"latest_monitor_failure_message"` + // Table that stores profile metrics data. Format: `catalog.schema.table_name`. + ProfileMetricsTableName *string `fieldmask:"profile_metrics_table_name"` + // Table that stores drift metrics data. Format: `catalog.schema.table_name`. + DriftMetricsTableName *string `fieldmask:"drift_metrics_table_name"` + // Id of dashboard that visualizes the computed metrics. This can be empty if + // the monitor is in PENDING state. + DashboardId *string `fieldmask:"dashboard_id"` + // Represents the current monitor configuration version in use. The version will + // be represented in a numeric fashion (1,2,3...). The field has flexibility to + // take on negative values, which can indicate corrupted monitor_version + // numbers. + MonitorVersion *int64 `fieldmask:"monitor_version"` + // The warehouse for dashboard creation + EffectiveWarehouseId *string `fieldmask:"effective_warehouse_id"` + _ [0]dataProfilingConfigAnalysisConfigFieldMaskMetadata `fieldmask_oneof:"AnalysisConfig"` +} + +type isDataProfilingConfig_AnalysisConfig interface { + isDataProfilingConfig_AnalysisConfig() +} + +// DataProfilingConfig_AnalysisConfig_InferenceLog selects InferenceLog for DataProfilingConfig.AnalysisConfig. +// `Analysis Configuration` for monitoring inference log tables. +type DataProfilingConfig_AnalysisConfig_InferenceLog struct { + InferenceLog InferenceLogConfig `fieldmask:"inference_log"` +} + +func (*DataProfilingConfig_AnalysisConfig_InferenceLog) isDataProfilingConfig_AnalysisConfig() {} + +// DataProfilingConfig_AnalysisConfig_TimeSeries selects TimeSeries for DataProfilingConfig.AnalysisConfig. +// `Analysis Configuration` for monitoring time series tables. +type DataProfilingConfig_AnalysisConfig_TimeSeries struct { + TimeSeries TimeSeriesConfig `fieldmask:"time_series"` +} + +func (*DataProfilingConfig_AnalysisConfig_TimeSeries) isDataProfilingConfig_AnalysisConfig() {} + +// DataProfilingConfig_AnalysisConfig_Snapshot selects Snapshot for DataProfilingConfig.AnalysisConfig. +// `Analysis Configuration` for monitoring snapshot tables. +type DataProfilingConfig_AnalysisConfig_Snapshot struct { + Snapshot SnapshotConfig `fieldmask:"snapshot"` +} + +func (*DataProfilingConfig_AnalysisConfig_Snapshot) isDataProfilingConfig_AnalysisConfig() {} + +type dataProfilingConfigAnalysisConfigFieldMaskMetadata struct { + *DataProfilingConfig_AnalysisConfig_InferenceLog + *DataProfilingConfig_AnalysisConfig_TimeSeries + *DataProfilingConfig_AnalysisConfig_Snapshot +} + +// Custom metric definition.. +type DataProfilingCustomMetric struct { + // Name of the metric in the output tables. + Name *string + // Jinja template for a SQL expression that specifies how to compute the metric. + // See [create metric definition]. + // + // [create metric definition]: https://docs.databricks.com/en/lakehouse-monitoring/custom-metrics.html#create-definition + Definition *string + // A list of column names in the input table the metric should be computed for. + // Can use ``":table"`` to indicate that the metric needs information from + // multiple columns. + InputColumns []string + // The output type of the custom metric. + OutputDataType *string + // The type of the custom metric. + Type DataProfilingCustomMetricType +} + +// Request to delete a Monitor.. +type DeleteMonitorRequest struct { + // The type of the monitored object. Can be one of the following: `schema` or + // `table`. + ObjectType *string + // The UUID of the request object. It is `schema_id` for `schema`, and + // `table_id` for `table`. + // + // Find the `schema_id` from either: 1. The [schema_id] of the `Schemas` + // resource. 2. In [Catalog Explorer] > select the `schema` > go to the + // `Details` tab > the `Schema ID` field. + // + // Find the `table_id` from either: 1. The [table_id] of the `Tables` resource. + // 2. In [Catalog Explorer] > select the `table` > go to the `Details` tab > the + // `Table ID` field. + // + // [Catalog Explorer]: https://docs.databricks.com/aws/en/catalog-explorer/ + // [schema_id]: https://docs.databricks.com/api/workspace/schemas/get#schema_id + // [table_id]: https://docs.databricks.com/api/workspace/tables/get#table_id + ObjectId *string +} + +// Request to delete a ronitor.. +type DeleteRefreshRequest struct { + // The type of the monitored object. Can be one of the following: `schema` or + // `table`. + ObjectType *string + // The UUID of the request object. It is `schema_id` for `schema`, and + // `table_id` for `table`. + // + // Find the `schema_id` from either: 1. The [schema_id] of the `Schemas` + // resource. 2. In [Catalog Explorer] > select the `schema` > go to the + // `Details` tab > the `Schema ID` field. + // + // Find the `table_id` from either: 1. The [table_id] of the `Tables` resource. + // 2. In [Catalog Explorer] > select the `table` > go to the `Details` tab > the + // `Table ID` field. + // + // [Catalog Explorer]: https://docs.databricks.com/aws/en/catalog-explorer/ + // [schema_id]: https://docs.databricks.com/api/workspace/schemas/get#schema_id + // [table_id]: https://docs.databricks.com/api/workspace/tables/get#table_id + ObjectId *string + // Unique id of the refresh operation. + RefreshId *int64 +} + +// Request to get a Monitor.. +type GetMonitorRequest struct { + // The type of the monitored object. Can be one of the following: `schema` or + // `table`. + ObjectType *string + // The UUID of the request object. It is `schema_id` for `schema`, and + // `table_id` for `table`. + // + // Find the `schema_id` from either: 1. The [schema_id] of the `Schemas` + // resource. 2. In [Catalog Explorer] > select the `schema` > go to the + // `Details` tab > the `Schema ID` field. + // + // Find the `table_id` from either: 1. The [table_id] of the `Tables` resource. + // 2. In [Catalog Explorer] > select the `table` > go to the `Details` tab > the + // `Table ID` field. + // + // [Catalog Explorer]: https://docs.databricks.com/aws/en/catalog-explorer/ + // [schema_id]: https://docs.databricks.com/api/workspace/schemas/get#schema_id + // [table_id]: https://docs.databricks.com/api/workspace/tables/get#table_id + ObjectId *string +} + +// Request to get a refresh.. +type GetRefreshRequest struct { + // The type of the monitored object. Can be one of the following: `schema` or + // `table`. + ObjectType *string + // The UUID of the request object. It is `schema_id` for `schema`, and + // `table_id` for `table`. + // + // Find the `schema_id` from either: 1. The [schema_id] of the `Schemas` + // resource. 2. In [Catalog Explorer] > select the `schema` > go to the + // `Details` tab > the `Schema ID` field. + // + // Find the `table_id` from either: 1. The [table_id] of the `Tables` resource. + // 2. In [Catalog Explorer] > select the `table` > go to the `Details` tab > the + // `Table ID` field. + // + // [Catalog Explorer]: https://docs.databricks.com/aws/en/catalog-explorer/ + // [schema_id]: https://docs.databricks.com/api/workspace/schemas/get#schema_id + // [table_id]: https://docs.databricks.com/api/workspace/tables/get#table_id + ObjectId *string + // Unique id of the refresh operation. + RefreshId *int64 +} + +// Inference log configuration.. +type InferenceLogConfig struct { + // Problem type the model aims to solve. + ProblemType InferenceProblemType `fieldmask:"problem_type"` + // Column for the timestamp. + TimestampColumn *string `fieldmask:"timestamp_column"` + // List of granularities to use when aggregating data into time windows based on + // their timestamp. + Granularities []AggregationGranularity `fieldmask:"granularities"` + // Column for the prediction. + PredictionColumn *string `fieldmask:"prediction_column"` + // Column for the label. + LabelColumn *string `fieldmask:"label_column"` + // Column for the model identifier. + ModelIdColumn *string `fieldmask:"model_id_column"` +} + +// Request to list Monitors.. +type ListMonitorRequest struct { + PageToken *string + PageSize *int +} + +// Response for listing Monitors.. +type ListMonitorResponse struct { + Monitors []Monitor + NextPageToken *string +} + +// Request to list refreshes.. +type ListRefreshRequest struct { + // The type of the monitored object. Can be one of the following: `schema` or + // `table`. + ObjectType *string + // The UUID of the request object. It is `schema_id` for `schema`, and + // `table_id` for `table`. + // + // Find the `schema_id` from either: 1. The [schema_id] of the `Schemas` + // resource. 2. In [Catalog Explorer] > select the `schema` > go to the + // `Details` tab > the `Schema ID` field. + // + // Find the `table_id` from either: 1. The [table_id] of the `Tables` resource. + // 2. In [Catalog Explorer] > select the `table` > go to the `Details` tab > the + // `Table ID` field. + // + // [Catalog Explorer]: https://docs.databricks.com/aws/en/catalog-explorer/ + // [schema_id]: https://docs.databricks.com/api/workspace/schemas/get#schema_id + // [table_id]: https://docs.databricks.com/api/workspace/tables/get#table_id + ObjectId *string + PageToken *string + PageSize *int +} + +// Response for listing refreshes.. +type ListRefreshResponse struct { + Refreshes []Refresh + NextPageToken *string +} + +// Monitor for the data quality of unity catalog entities such as schema or +// table.. +type Monitor struct { + // The type of the monitored object. Can be one of the following: `schema` or + // `table`. + ObjectType *string `fieldmask:"object_type"` + // The UUID of the request object. It is `schema_id` for `schema`, and + // `table_id` for `table`. + // + // Find the `schema_id` from either: 1. The [schema_id] of the `Schemas` + // resource. 2. In [Catalog Explorer] > select the `schema` > go to the + // `Details` tab > the `Schema ID` field. + // + // Find the `table_id` from either: 1. The [table_id] of the `Tables` resource. + // 2. In [Catalog Explorer] > select the `table` > go to the `Details` tab > the + // `Table ID` field. + // + // [Catalog Explorer]: https://docs.databricks.com/aws/en/catalog-explorer/ + // [schema_id]: https://docs.databricks.com/api/workspace/schemas/get#schema_id + // [table_id]: https://docs.databricks.com/api/workspace/tables/get#table_id + ObjectId *string `fieldmask:"object_id"` + // Anomaly Detection Configuration, applicable to `schema` object types. + AnomalyDetectionConfig *AnomalyDetectionConfig `fieldmask:"anomaly_detection_config"` + // Data Profiling Configuration, applicable to `table` object types. Exactly one + // `Analysis Configuration` must be present. + DataProfilingConfig *DataProfilingConfig `fieldmask:"data_profiling_config"` +} + +// Destination of the data quality monitoring notification.. +type NotificationDestination struct { + // The list of email addresses to send the notification to. A maximum of 5 email + // addresses is supported. + EmailAddresses []string `fieldmask:"email_addresses"` +} + +// Settings for sending notifications on the data quality monitoring.. +type NotificationSettings struct { + // Destinations to send notifications on failure/timeout. + OnFailure *NotificationDestination `fieldmask:"on_failure"` +} + +// The Refresh object gives information on a refresh of the data quality +// monitoring pipeline.. +type Refresh struct { + // The type of the monitored object. Can be one of the following: `schema` or + // `table`. + ObjectType *string `fieldmask:"object_type"` + // The UUID of the request object. It is `schema_id` for `schema`, and + // `table_id` for `table`. + // + // Find the `schema_id` from either: 1. The [schema_id] of the `Schemas` + // resource. 2. In [Catalog Explorer] > select the `schema` > go to the + // `Details` tab > the `Schema ID` field. + // + // Find the `table_id` from either: 1. The [table_id] of the `Tables` resource. + // 2. In [Catalog Explorer] > select the `table` > go to the `Details` tab > the + // `Table ID` field. + // + // [Catalog Explorer]: https://docs.databricks.com/aws/en/catalog-explorer/ + // [schema_id]: https://docs.databricks.com/api/workspace/schemas/get#schema_id + // [table_id]: https://docs.databricks.com/api/workspace/tables/get#table_id + ObjectId *string `fieldmask:"object_id"` + // Unique id of the refresh operation. + RefreshId *int64 `fieldmask:"refresh_id"` + // The current state of the refresh. + State RefreshState `fieldmask:"state"` + // An optional message to give insight into the current state of the refresh + // (e.g. FAILURE messages). + Message *string `fieldmask:"message"` + // Time when the refresh started (milliseconds since 1/1/1970 UTC). + StartTimeMs *int64 `fieldmask:"start_time_ms"` + // Time when the refresh ended (milliseconds since 1/1/1970 UTC). + EndTimeMs *int64 `fieldmask:"end_time_ms"` + // What triggered the refresh. + Trigger RefreshTrigger `fieldmask:"trigger"` +} + +// Snapshot analysis configuration.. +type SnapshotConfig struct { +} + +// Time series analysis configuration.. +type TimeSeriesConfig struct { + // Column for the timestamp. + TimestampColumn *string `fieldmask:"timestamp_column"` + // List of granularities to use when aggregating data into time windows based on + // their timestamp. + Granularities []AggregationGranularity `fieldmask:"granularities"` +} + +// Request to update a Monitor.. +type UpdateMonitorRequest struct { + // The type of the monitored object. Can be one of the following: `schema` or + // `table`. + ObjectType *string + // The UUID of the request object. It is `schema_id` for `schema`, and + // `table_id` for `table`. + // + // Find the `schema_id` from either: 1. The [schema_id] of the `Schemas` + // resource. 2. In [Catalog Explorer] > select the `schema` > go to the + // `Details` tab > the `Schema ID` field. + // + // Find the `table_id` from either: 1. The [table_id] of the `Tables` resource. + // 2. In [Catalog Explorer] > select the `table` > go to the `Details` tab > the + // `Table ID` field. + // + // [Catalog Explorer]: https://docs.databricks.com/aws/en/catalog-explorer/ + // [schema_id]: https://docs.databricks.com/api/workspace/schemas/get#schema_id + // [table_id]: https://docs.databricks.com/api/workspace/tables/get#table_id + ObjectId *string + // The monitor to update. + Monitor *Monitor + // The field mask to specify which fields to update as a comma-separated list. + // Example value: + // `data_profiling_config.custom_metrics,data_profiling_config.schedule.quartz_cron_expression` + UpdateMask *types.FieldMask[Monitor] +} + +// Request to update a refresh.. +type UpdateRefreshRequest struct { + // The type of the monitored object. Can be one of the following: `schema` or + // `table`. + ObjectType *string + // The UUID of the request object. It is `schema_id` for `schema`, and + // `table_id` for `table`. + // + // Find the `schema_id` from either: 1. The [schema_id] of the `Schemas` + // resource. 2. In [Catalog Explorer] > select the `schema` > go to the + // `Details` tab > the `Schema ID` field. + // + // Find the `table_id` from either: 1. The [table_id] of the `Tables` resource. + // 2. In [Catalog Explorer] > select the `table` > go to the `Details` tab > the + // `Table ID` field. + // + // [Catalog Explorer]: https://docs.databricks.com/aws/en/catalog-explorer/ + // [schema_id]: https://docs.databricks.com/api/workspace/schemas/get#schema_id + // [table_id]: https://docs.databricks.com/api/workspace/tables/get#table_id + ObjectId *string + // Unique id of the refresh operation. + RefreshId *int64 + // The refresh to update. + Refresh *Refresh + // The field mask to specify which fields to update. + UpdateMask *types.FieldMask[Refresh] +} diff --git a/dataquality/v1/wire.go b/dataquality/v1/wire.go new file mode 100755 index 0000000..8d739ab --- /dev/null +++ b/dataquality/v1/wire.go @@ -0,0 +1,692 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package dataquality + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type anomalyDetectionConfigWire struct { + ExcludedTableFullNames []string `json:"excluded_table_full_names,omitempty"` +} + +func anomalyDetectionConfigToWire(v *AnomalyDetectionConfig) (*anomalyDetectionConfigWire, error) { + if v == nil { + return nil, nil + } + return &anomalyDetectionConfigWire{ + ExcludedTableFullNames: v.ExcludedTableFullNames, + }, nil +} + +func anomalyDetectionConfigFromWire(w *anomalyDetectionConfigWire) (*AnomalyDetectionConfig, error) { + if w == nil { + return nil, nil + } + return &AnomalyDetectionConfig{ + ExcludedTableFullNames: w.ExcludedTableFullNames, + }, nil +} + +type cancelRefreshRequestWire struct { + ObjectType *string `json:"object_type,omitempty"` + ObjectId *string `json:"object_id,omitempty"` + RefreshId *int64 `json:"refresh_id,omitempty"` +} + +func cancelRefreshRequestToWire(v *CancelRefreshRequest) (*cancelRefreshRequestWire, error) { + if v == nil { + return nil, nil + } + return &cancelRefreshRequestWire{ + ObjectType: v.ObjectType, + ObjectId: v.ObjectId, + RefreshId: v.RefreshId, + }, nil +} + +type cancelRefreshResponseWire struct { + Refresh *refreshWire `json:"refresh,omitempty"` +} + +func cancelRefreshResponseFromWire(w *cancelRefreshResponseWire) (*CancelRefreshResponse, error) { + if w == nil { + return nil, nil + } + refreshPublicValue, err := refreshFromWire(w.Refresh) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CancelRefreshResponse.Refresh", err) + } + return &CancelRefreshResponse{ + Refresh: refreshPublicValue, + }, nil +} + +type createMonitorRequestWire struct { + Monitor *monitorWire `json:"monitor,omitempty"` +} + +func createMonitorRequestToWire(v *CreateMonitorRequest) (*createMonitorRequestWire, error) { + if v == nil { + return nil, nil + } + monitorWireValue, err := monitorToWire(v.Monitor) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateMonitorRequest.Monitor", err) + } + return &createMonitorRequestWire{ + Monitor: monitorWireValue, + }, nil +} + +type createRefreshRequestWire struct { + Refresh *refreshWire `json:"refresh,omitempty"` +} + +func createRefreshRequestToWire(v *CreateRefreshRequest) (*createRefreshRequestWire, error) { + if v == nil { + return nil, nil + } + refreshWireValue, err := refreshToWire(v.Refresh) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRefreshRequest.Refresh", err) + } + return &createRefreshRequestWire{ + Refresh: refreshWireValue, + }, nil +} + +type cronScheduleWire struct { + QuartzCronExpression *string `json:"quartz_cron_expression,omitempty"` + TimezoneId *string `json:"timezone_id,omitempty"` + PauseStatus CronSchedulePauseStatus `json:"pause_status,omitempty"` +} + +func cronScheduleToWire(v *CronSchedule) (*cronScheduleWire, error) { + if v == nil { + return nil, nil + } + return &cronScheduleWire{ + QuartzCronExpression: v.QuartzCronExpression, + TimezoneId: v.TimezoneId, + PauseStatus: v.PauseStatus, + }, nil +} + +func cronScheduleFromWire(w *cronScheduleWire) (*CronSchedule, error) { + if w == nil { + return nil, nil + } + return &CronSchedule{ + QuartzCronExpression: w.QuartzCronExpression, + TimezoneId: w.TimezoneId, + PauseStatus: w.PauseStatus, + }, nil +} + +type dataProfilingConfigWire struct { + OutputSchemaId *string `json:"output_schema_id,omitempty"` + AssetsDir *string `json:"assets_dir,omitempty"` + InferenceLog *inferenceLogConfigWire `json:"inference_log,omitempty"` + TimeSeries *timeSeriesConfigWire `json:"time_series,omitempty"` + Snapshot *snapshotConfigWire `json:"snapshot,omitempty"` + SlicingExprs []string `json:"slicing_exprs,omitempty"` + CustomMetrics []dataProfilingCustomMetricWire `json:"custom_metrics,omitempty"` + BaselineTableName *string `json:"baseline_table_name,omitempty"` + Schedule *cronScheduleWire `json:"schedule,omitempty"` + NotificationSettings *notificationSettingsWire `json:"notification_settings,omitempty"` + SkipBuiltinDashboard *bool `json:"skip_builtin_dashboard,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + MonitoredTableName *string `json:"monitored_table_name,omitempty"` + Status DataProfilingStatus `json:"status,omitempty"` + LatestMonitorFailureMessage *string `json:"latest_monitor_failure_message,omitempty"` + ProfileMetricsTableName *string `json:"profile_metrics_table_name,omitempty"` + DriftMetricsTableName *string `json:"drift_metrics_table_name,omitempty"` + DashboardId *string `json:"dashboard_id,omitempty"` + MonitorVersion *int64 `json:"monitor_version,omitempty"` + EffectiveWarehouseId *string `json:"effective_warehouse_id,omitempty"` +} + +func dataProfilingConfigToWire(v *DataProfilingConfig) (*dataProfilingConfigWire, error) { + if v == nil { + return nil, nil + } + customMetricsWireValue, err := convertSlice(v.CustomMetrics, dataProfilingCustomMetricToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.CustomMetrics", err) + } + scheduleWireValue, err := cronScheduleToWire(v.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.Schedule", err) + } + notificationSettingsWireValue, err := notificationSettingsToWire(v.NotificationSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.NotificationSettings", err) + } + var analysisConfigInferenceLogWire *inferenceLogConfigWire + var analysisConfigTimeSeriesWire *timeSeriesConfigWire + var analysisConfigSnapshotWire *snapshotConfigWire + switch value := v.AnalysisConfig.(type) { + case nil: + case *DataProfilingConfig_AnalysisConfig_InferenceLog: + if value != nil { + analysisConfigInferenceLogConverted, err := inferenceLogConfigToWire(&value.InferenceLog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.AnalysisConfig.InferenceLog", err) + } + analysisConfigInferenceLogWire = analysisConfigInferenceLogConverted + } + case *DataProfilingConfig_AnalysisConfig_TimeSeries: + if value != nil { + analysisConfigTimeSeriesConverted, err := timeSeriesConfigToWire(&value.TimeSeries) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.AnalysisConfig.TimeSeries", err) + } + analysisConfigTimeSeriesWire = analysisConfigTimeSeriesConverted + } + case *DataProfilingConfig_AnalysisConfig_Snapshot: + if value != nil { + analysisConfigSnapshotConverted, err := snapshotConfigToWire(&value.Snapshot) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.AnalysisConfig.Snapshot", err) + } + analysisConfigSnapshotWire = analysisConfigSnapshotConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "DataProfilingConfig.AnalysisConfig", value) + } + return &dataProfilingConfigWire{ + OutputSchemaId: v.OutputSchemaId, + AssetsDir: v.AssetsDir, + InferenceLog: analysisConfigInferenceLogWire, + TimeSeries: analysisConfigTimeSeriesWire, + Snapshot: analysisConfigSnapshotWire, + SlicingExprs: v.SlicingExprs, + CustomMetrics: customMetricsWireValue, + BaselineTableName: v.BaselineTableName, + Schedule: scheduleWireValue, + NotificationSettings: notificationSettingsWireValue, + SkipBuiltinDashboard: v.SkipBuiltinDashboard, + WarehouseId: v.WarehouseId, + MonitoredTableName: v.MonitoredTableName, + Status: v.Status, + LatestMonitorFailureMessage: v.LatestMonitorFailureMessage, + ProfileMetricsTableName: v.ProfileMetricsTableName, + DriftMetricsTableName: v.DriftMetricsTableName, + DashboardId: v.DashboardId, + MonitorVersion: v.MonitorVersion, + EffectiveWarehouseId: v.EffectiveWarehouseId, + }, nil +} + +func dataProfilingConfigFromWire(w *dataProfilingConfigWire) (*DataProfilingConfig, error) { + if w == nil { + return nil, nil + } + analysisConfigMembers := 0 + if w.InferenceLog != nil { + analysisConfigMembers++ + } + if w.TimeSeries != nil { + analysisConfigMembers++ + } + if w.Snapshot != nil { + analysisConfigMembers++ + } + if analysisConfigMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "DataProfilingConfig.AnalysisConfig") + } + customMetricsPublicValue, err := convertSlice(w.CustomMetrics, dataProfilingCustomMetricFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.CustomMetrics", err) + } + schedulePublicValue, err := cronScheduleFromWire(w.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.Schedule", err) + } + notificationSettingsPublicValue, err := notificationSettingsFromWire(w.NotificationSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.NotificationSettings", err) + } + var analysisConfigSelection isDataProfilingConfig_AnalysisConfig + switch { + case w.InferenceLog != nil: + analysisConfigInferenceLogConverted, err := inferenceLogConfigFromWire(w.InferenceLog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.AnalysisConfig.InferenceLog", err) + } + analysisConfigSelection = &DataProfilingConfig_AnalysisConfig_InferenceLog{InferenceLog: *analysisConfigInferenceLogConverted} + case w.TimeSeries != nil: + analysisConfigTimeSeriesConverted, err := timeSeriesConfigFromWire(w.TimeSeries) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.AnalysisConfig.TimeSeries", err) + } + analysisConfigSelection = &DataProfilingConfig_AnalysisConfig_TimeSeries{TimeSeries: *analysisConfigTimeSeriesConverted} + case w.Snapshot != nil: + analysisConfigSnapshotConverted, err := snapshotConfigFromWire(w.Snapshot) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataProfilingConfig.AnalysisConfig.Snapshot", err) + } + analysisConfigSelection = &DataProfilingConfig_AnalysisConfig_Snapshot{Snapshot: *analysisConfigSnapshotConverted} + } + return &DataProfilingConfig{ + OutputSchemaId: w.OutputSchemaId, + AssetsDir: w.AssetsDir, + SlicingExprs: w.SlicingExprs, + CustomMetrics: customMetricsPublicValue, + BaselineTableName: w.BaselineTableName, + Schedule: schedulePublicValue, + NotificationSettings: notificationSettingsPublicValue, + SkipBuiltinDashboard: w.SkipBuiltinDashboard, + WarehouseId: w.WarehouseId, + MonitoredTableName: w.MonitoredTableName, + Status: w.Status, + LatestMonitorFailureMessage: w.LatestMonitorFailureMessage, + ProfileMetricsTableName: w.ProfileMetricsTableName, + DriftMetricsTableName: w.DriftMetricsTableName, + DashboardId: w.DashboardId, + MonitorVersion: w.MonitorVersion, + EffectiveWarehouseId: w.EffectiveWarehouseId, + AnalysisConfig: analysisConfigSelection, + }, nil +} + +type dataProfilingCustomMetricWire struct { + Name *string `json:"name,omitempty"` + Definition *string `json:"definition,omitempty"` + InputColumns []string `json:"input_columns,omitempty"` + OutputDataType *string `json:"output_data_type,omitempty"` + Type DataProfilingCustomMetricType `json:"type,omitempty"` +} + +func dataProfilingCustomMetricToWire(v *DataProfilingCustomMetric) (*dataProfilingCustomMetricWire, error) { + if v == nil { + return nil, nil + } + return &dataProfilingCustomMetricWire{ + Name: v.Name, + Definition: v.Definition, + InputColumns: v.InputColumns, + OutputDataType: v.OutputDataType, + Type: v.Type, + }, nil +} + +func dataProfilingCustomMetricFromWire(w *dataProfilingCustomMetricWire) (*DataProfilingCustomMetric, error) { + if w == nil { + return nil, nil + } + return &DataProfilingCustomMetric{ + Name: w.Name, + Definition: w.Definition, + InputColumns: w.InputColumns, + OutputDataType: w.OutputDataType, + Type: w.Type, + }, nil +} + +type inferenceLogConfigWire struct { + ProblemType InferenceProblemType `json:"problem_type,omitempty"` + TimestampColumn *string `json:"timestamp_column,omitempty"` + Granularities []AggregationGranularity `json:"granularities,omitempty"` + PredictionColumn *string `json:"prediction_column,omitempty"` + LabelColumn *string `json:"label_column,omitempty"` + ModelIdColumn *string `json:"model_id_column,omitempty"` +} + +func inferenceLogConfigToWire(v *InferenceLogConfig) (*inferenceLogConfigWire, error) { + if v == nil { + return nil, nil + } + return &inferenceLogConfigWire{ + ProblemType: v.ProblemType, + TimestampColumn: v.TimestampColumn, + Granularities: v.Granularities, + PredictionColumn: v.PredictionColumn, + LabelColumn: v.LabelColumn, + ModelIdColumn: v.ModelIdColumn, + }, nil +} + +func inferenceLogConfigFromWire(w *inferenceLogConfigWire) (*InferenceLogConfig, error) { + if w == nil { + return nil, nil + } + return &InferenceLogConfig{ + ProblemType: w.ProblemType, + TimestampColumn: w.TimestampColumn, + Granularities: w.Granularities, + PredictionColumn: w.PredictionColumn, + LabelColumn: w.LabelColumn, + ModelIdColumn: w.ModelIdColumn, + }, nil +} + +type listMonitorRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listMonitorRequestToWire(v *ListMonitorRequest) (*listMonitorRequestWire, error) { + if v == nil { + return nil, nil + } + return &listMonitorRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listMonitorResponseWire struct { + Monitors []monitorWire `json:"monitors,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listMonitorResponseFromWire(w *listMonitorResponseWire) (*ListMonitorResponse, error) { + if w == nil { + return nil, nil + } + monitorsPublicValue, err := convertSlice(w.Monitors, monitorFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListMonitorResponse.Monitors", err) + } + return &ListMonitorResponse{ + Monitors: monitorsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listRefreshRequestWire struct { + ObjectType *string `json:"object_type,omitempty"` + ObjectId *string `json:"object_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listRefreshRequestToWire(v *ListRefreshRequest) (*listRefreshRequestWire, error) { + if v == nil { + return nil, nil + } + return &listRefreshRequestWire{ + ObjectType: v.ObjectType, + ObjectId: v.ObjectId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listRefreshResponseWire struct { + Refreshes []refreshWire `json:"refreshes,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listRefreshResponseFromWire(w *listRefreshResponseWire) (*ListRefreshResponse, error) { + if w == nil { + return nil, nil + } + refreshesPublicValue, err := convertSlice(w.Refreshes, refreshFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListRefreshResponse.Refreshes", err) + } + return &ListRefreshResponse{ + Refreshes: refreshesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type monitorWire struct { + ObjectType *string `json:"object_type,omitempty"` + ObjectId *string `json:"object_id,omitempty"` + AnomalyDetectionConfig *anomalyDetectionConfigWire `json:"anomaly_detection_config,omitempty"` + DataProfilingConfig *dataProfilingConfigWire `json:"data_profiling_config,omitempty"` +} + +func monitorToWire(v *Monitor) (*monitorWire, error) { + if v == nil { + return nil, nil + } + anomalyDetectionConfigWireValue, err := anomalyDetectionConfigToWire(v.AnomalyDetectionConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Monitor.AnomalyDetectionConfig", err) + } + dataProfilingConfigWireValue, err := dataProfilingConfigToWire(v.DataProfilingConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Monitor.DataProfilingConfig", err) + } + return &monitorWire{ + ObjectType: v.ObjectType, + ObjectId: v.ObjectId, + AnomalyDetectionConfig: anomalyDetectionConfigWireValue, + DataProfilingConfig: dataProfilingConfigWireValue, + }, nil +} + +func monitorFromWire(w *monitorWire) (*Monitor, error) { + if w == nil { + return nil, nil + } + anomalyDetectionConfigPublicValue, err := anomalyDetectionConfigFromWire(w.AnomalyDetectionConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Monitor.AnomalyDetectionConfig", err) + } + dataProfilingConfigPublicValue, err := dataProfilingConfigFromWire(w.DataProfilingConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Monitor.DataProfilingConfig", err) + } + return &Monitor{ + ObjectType: w.ObjectType, + ObjectId: w.ObjectId, + AnomalyDetectionConfig: anomalyDetectionConfigPublicValue, + DataProfilingConfig: dataProfilingConfigPublicValue, + }, nil +} + +type notificationDestinationWire struct { + EmailAddresses []string `json:"email_addresses,omitempty"` +} + +func notificationDestinationToWire(v *NotificationDestination) (*notificationDestinationWire, error) { + if v == nil { + return nil, nil + } + return ¬ificationDestinationWire{ + EmailAddresses: v.EmailAddresses, + }, nil +} + +func notificationDestinationFromWire(w *notificationDestinationWire) (*NotificationDestination, error) { + if w == nil { + return nil, nil + } + return &NotificationDestination{ + EmailAddresses: w.EmailAddresses, + }, nil +} + +type notificationSettingsWire struct { + OnFailure *notificationDestinationWire `json:"on_failure,omitempty"` +} + +func notificationSettingsToWire(v *NotificationSettings) (*notificationSettingsWire, error) { + if v == nil { + return nil, nil + } + onFailureWireValue, err := notificationDestinationToWire(v.OnFailure) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NotificationSettings.OnFailure", err) + } + return ¬ificationSettingsWire{ + OnFailure: onFailureWireValue, + }, nil +} + +func notificationSettingsFromWire(w *notificationSettingsWire) (*NotificationSettings, error) { + if w == nil { + return nil, nil + } + onFailurePublicValue, err := notificationDestinationFromWire(w.OnFailure) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NotificationSettings.OnFailure", err) + } + return &NotificationSettings{ + OnFailure: onFailurePublicValue, + }, nil +} + +type refreshWire struct { + ObjectType *string `json:"object_type,omitempty"` + ObjectId *string `json:"object_id,omitempty"` + RefreshId *int64 `json:"refresh_id,omitempty"` + State RefreshState `json:"state,omitempty"` + Message *string `json:"message,omitempty"` + StartTimeMs *int64 `json:"start_time_ms,omitempty"` + EndTimeMs *int64 `json:"end_time_ms,omitempty"` + Trigger RefreshTrigger `json:"trigger,omitempty"` +} + +func refreshToWire(v *Refresh) (*refreshWire, error) { + if v == nil { + return nil, nil + } + return &refreshWire{ + ObjectType: v.ObjectType, + ObjectId: v.ObjectId, + RefreshId: v.RefreshId, + State: v.State, + Message: v.Message, + StartTimeMs: v.StartTimeMs, + EndTimeMs: v.EndTimeMs, + Trigger: v.Trigger, + }, nil +} + +func refreshFromWire(w *refreshWire) (*Refresh, error) { + if w == nil { + return nil, nil + } + return &Refresh{ + ObjectType: w.ObjectType, + ObjectId: w.ObjectId, + RefreshId: w.RefreshId, + State: w.State, + Message: w.Message, + StartTimeMs: w.StartTimeMs, + EndTimeMs: w.EndTimeMs, + Trigger: w.Trigger, + }, nil +} + +type snapshotConfigWire struct { +} + +func snapshotConfigToWire(v *SnapshotConfig) (*snapshotConfigWire, error) { + if v == nil { + return nil, nil + } + return &snapshotConfigWire{}, nil +} + +func snapshotConfigFromWire(w *snapshotConfigWire) (*SnapshotConfig, error) { + if w == nil { + return nil, nil + } + return &SnapshotConfig{}, nil +} + +type timeSeriesConfigWire struct { + TimestampColumn *string `json:"timestamp_column,omitempty"` + Granularities []AggregationGranularity `json:"granularities,omitempty"` +} + +func timeSeriesConfigToWire(v *TimeSeriesConfig) (*timeSeriesConfigWire, error) { + if v == nil { + return nil, nil + } + return &timeSeriesConfigWire{ + TimestampColumn: v.TimestampColumn, + Granularities: v.Granularities, + }, nil +} + +func timeSeriesConfigFromWire(w *timeSeriesConfigWire) (*TimeSeriesConfig, error) { + if w == nil { + return nil, nil + } + return &TimeSeriesConfig{ + TimestampColumn: w.TimestampColumn, + Granularities: w.Granularities, + }, nil +} + +type updateMonitorRequestWire struct { + ObjectType *string `json:"object_type,omitempty"` + ObjectId *string `json:"object_id,omitempty"` + Monitor *monitorWire `json:"monitor,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateMonitorRequestToWire(v *UpdateMonitorRequest) (*updateMonitorRequestWire, error) { + if v == nil { + return nil, nil + } + monitorWireValue, err := monitorToWire(v.Monitor) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateMonitorRequest.Monitor", err) + } + return &updateMonitorRequestWire{ + ObjectType: v.ObjectType, + ObjectId: v.ObjectId, + Monitor: monitorWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateRefreshRequestWire struct { + ObjectType *string `json:"object_type,omitempty"` + ObjectId *string `json:"object_id,omitempty"` + RefreshId *int64 `json:"refresh_id,omitempty"` + Refresh *refreshWire `json:"refresh,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateRefreshRequestToWire(v *UpdateRefreshRequest) (*updateRefreshRequestWire, error) { + if v == nil { + return nil, nil + } + refreshWireValue, err := refreshToWire(v.Refresh) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRefreshRequest.Refresh", err) + } + return &updateRefreshRequestWire{ + ObjectType: v.ObjectType, + ObjectId: v.ObjectId, + RefreshId: v.RefreshId, + Refresh: refreshWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/disasterrecovery/.package.json b/disasterrecovery/.package.json new file mode 100644 index 0000000..3ea9cbd --- /dev/null +++ b/disasterrecovery/.package.json @@ -0,0 +1,3 @@ +{ + "package": "disasterrecovery" +} diff --git a/disasterrecovery/CHANGELOG.md b/disasterrecovery/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/disasterrecovery/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/disasterrecovery/README.md b/disasterrecovery/README.md new file mode 100644 index 0000000..167bfb0 --- /dev/null +++ b/disasterrecovery/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/disasterrecovery + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/disasterrecovery@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/disasterrecovery/v1" + +client, err := disasterrecovery.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/disasterrecovery/go.mod b/disasterrecovery/go.mod new file mode 100644 index 0000000..16f5194 --- /dev/null +++ b/disasterrecovery/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/disasterrecovery + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/disasterrecovery/internal/version.go b/disasterrecovery/internal/version.go new file mode 100644 index 0000000..06968b9 --- /dev/null +++ b/disasterrecovery/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-disasterrecovery" + +const Version = "0.0.1-dev.1" diff --git a/disasterrecovery/v1/client.go b/disasterrecovery/v1/client.go new file mode 100755 index 0000000..44c13e8 --- /dev/null +++ b/disasterrecovery/v1/client.go @@ -0,0 +1,834 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package disasterrecovery + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/disasterrecovery/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a new failover group. +func (c *internalClient) CreateFailoverGroup(ctx context.Context, req *CreateFailoverGroupRequest, opts ...call.Option) (*FailoverGroup, error) { + wireReq, err := createFailoverGroupRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.FailoverGroup) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/disaster-recovery/v1/") + pb.singleSegment(*req.Parent) + pb.literal("/failover-groups") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "validate_only", wireReq.ValidateOnly); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "failover_group_id", wireReq.FailoverGroupId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FailoverGroup + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp failoverGroupWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = failoverGroupFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a new stable URL. +func (c *internalClient) CreateStableUrl(ctx context.Context, req *CreateStableUrlRequest, opts ...call.Option) (*StableUrl, error) { + wireReq, err := createStableUrlRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.StableUrl) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/disaster-recovery/v1/") + pb.singleSegment(*req.Parent) + pb.literal("/stable-urls") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "validate_only", wireReq.ValidateOnly); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "stable_url_id", wireReq.StableUrlId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StableUrl + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp stableUrlWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = stableUrlFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a failover group. +func (c *internalClient) DeleteFailoverGroup(ctx context.Context, req *DeleteFailoverGroupRequest, opts ...call.Option) error { + wireReq, err := deleteFailoverGroupRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/disaster-recovery/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete a stable URL. +func (c *internalClient) DeleteStableUrl(ctx context.Context, req *DeleteStableUrlRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/disaster-recovery/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Initiate a failover to a new primary region. +func (c *internalClient) FailoverFailoverGroup(ctx context.Context, req *FailoverFailoverGroupRequest, opts ...call.Option) (*FailoverGroup, error) { + wireReq, err := failoverFailoverGroupRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/disaster-recovery/v1/") + pb.singleSegment(*req.Name) + pb.literal("/failover") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FailoverGroup + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp failoverGroupWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = failoverGroupFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a failover group. +func (c *internalClient) GetFailoverGroup(ctx context.Context, req *GetFailoverGroupRequest, opts ...call.Option) (*FailoverGroup, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/disaster-recovery/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FailoverGroup + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp failoverGroupWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = failoverGroupFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a stable URL. +func (c *internalClient) GetStableUrl(ctx context.Context, req *GetStableUrlRequest, opts ...call.Option) (*StableUrl, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/disaster-recovery/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StableUrl + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp stableUrlWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = stableUrlFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List failover groups. +// +// List entries are abbreviated: `state` and `replication_point` are not +// populated. Call GetFailoverGroup to retrieve the full resource. +func (c *internalClient) ListFailoverGroups(ctx context.Context, req *ListFailoverGroupsRequest, opts ...call.Option) (*ListFailoverGroupsResponse, error) { + wireReq, err := listFailoverGroupsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/disaster-recovery/v1/") + pb.singleSegment(*req.Parent) + pb.literal("/failover-groups") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListFailoverGroupsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listFailoverGroupsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listFailoverGroupsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListFailoverGroupsIter returns an iterator that iterates +// over the results of ListFailoverGroups. +// +// For example: +// +// for item, err := range c.ListFailoverGroupsIter(ctx, &ListFailoverGroupsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListFailoverGroups call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListFailoverGroups directly. +func (c *internalClient) ListFailoverGroupsIter(ctx context.Context, req *ListFailoverGroupsRequest, opts ...call.Option) iter.Seq2[*FailoverGroup, error] { + return func(yield func(*FailoverGroup, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListFailoverGroupsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListFailoverGroups(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.FailoverGroups { + if !yield(&resp.FailoverGroups[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List stable URLs for an account. +func (c *internalClient) ListStableUrls(ctx context.Context, req *ListStableUrlsRequest, opts ...call.Option) (*ListStableUrlsResponse, error) { + wireReq, err := listStableUrlsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/disaster-recovery/v1/") + pb.singleSegment(*req.Parent) + pb.literal("/stable-urls") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListStableUrlsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listStableUrlsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listStableUrlsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListStableUrlsIter returns an iterator that iterates +// over the results of ListStableUrls. +// +// For example: +// +// for item, err := range c.ListStableUrlsIter(ctx, &ListStableUrlsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListStableUrls call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListStableUrls directly. +func (c *internalClient) ListStableUrlsIter(ctx context.Context, req *ListStableUrlsRequest, opts ...call.Option) iter.Seq2[*StableUrl, error] { + return func(yield func(*StableUrl, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListStableUrlsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListStableUrls(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.StableUrls { + if !yield(&resp.StableUrls[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Update a failover group. +func (c *internalClient) UpdateFailoverGroup(ctx context.Context, req *UpdateFailoverGroupRequest, opts ...call.Option) (*FailoverGroup, error) { + wireReq, err := updateFailoverGroupRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.FailoverGroup) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/disaster-recovery/v1/") + pb.singleSegment(*req.FailoverGroup.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FailoverGroup + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp failoverGroupWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = failoverGroupFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/disasterrecovery/v1/genhelper.go b/disasterrecovery/v1/genhelper.go new file mode 100755 index 0000000..7859a20 --- /dev/null +++ b/disasterrecovery/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package disasterrecovery + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/disasterrecovery/v1/model.go b/disasterrecovery/v1/model.go new file mode 100755 index 0000000..f3e763f --- /dev/null +++ b/disasterrecovery/v1/model.go @@ -0,0 +1,288 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package disasterrecovery + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// The type of failover to perform. +type FailoverFailoverGroupRequest_FailoverType string + +const ( + FailoverFailoverGroupRequest_FailoverType_Unspecified FailoverFailoverGroupRequest_FailoverType = "" + FailoverFailoverGroupRequest_FailoverType_Forced FailoverFailoverGroupRequest_FailoverType = "FORCED" +) + +// The aggregate state of a FailoverGroup. +type FailoverGroup_State string + +const ( + FailoverGroup_State_Unspecified FailoverGroup_State = "" + // FailoverGroup is being created, setup in progress. + FailoverGroup_State_Creating FailoverGroup_State = "CREATING" + // FailoverGroup creation failed. + FailoverGroup_State_CreationFailed FailoverGroup_State = "CREATION_FAILED" + // Initial replication is in progress (bootstrapping data). + FailoverGroup_State_InitialReplication FailoverGroup_State = "INITIAL_REPLICATION" + // Replication up-to-date, ready for failover. + FailoverGroup_State_Active FailoverGroup_State = "ACTIVE" + // Failover or failback in progress. + FailoverGroup_State_FailingOver FailoverGroup_State = "FAILING_OVER" + // Deletion in progress. + FailoverGroup_State_Deleting FailoverGroup_State = "DELETING" + // Failover or failback failed. + FailoverGroup_State_FailoverFailed FailoverGroup_State = "FAILOVER_FAILED" + // Deletion failed. + FailoverGroup_State_DeletionFailed FailoverGroup_State = "DELETION_FAILED" +) + +// Request to create a new failover group.. +type CreateFailoverGroupRequest struct { + // The parent resource. Format: accounts/{account_id}. + Parent *string + // The failover group to create. + FailoverGroup *FailoverGroup + // When true, validates the request without creating the failover group. + ValidateOnly *bool + // Client-provided identifier for the failover group. Used to construct the + // resource name as {parent}/failover-groups/{failover_group_id}. + FailoverGroupId *string +} + +// Request to create a new stable URL for failover-aware workspace access.. +type CreateStableUrlRequest struct { + // The parent resource. Format: accounts/{account_id}. + Parent *string + // The stable URL to create. + StableUrl *StableUrl + // When true, validates the request without creating the stable URL. + ValidateOnly *bool + // Client-provided identifier for the stable URL. Used to construct the resource + // name as {parent}/stable-urls/{stable_url_id}. + StableUrlId *string +} + +// Request to delete a failover group.. +type DeleteFailoverGroupRequest struct { + // The fully qualified resource name of the failover group to delete. Format: + // accounts/{account_id}/failover-groups/{failover_group_id}. + Name *string + // Opaque version string for optimistic locking. If provided, must match the + // current etag. If omitted, the delete proceeds without an etag check. + Etag *string +} + +// Request to delete a stable URL.. +type DeleteStableUrlRequest struct { + // The fully qualified resource name. Format: + // accounts/{account_id}/stable-urls/{stable_url_id}. + Name *string +} + +// Request to failover a failover group to a new primary region.. +type FailoverFailoverGroupRequest struct { + // The fully qualified resource name of the failover group to failover. Format: + // accounts/{account_id}/failover-groups/{failover_group_id}. + Name *string + // The target primary region. Must be one of the participating regions and + // different from the current effective_primary_region. Serves as an idempotency + // check. + TargetPrimaryRegion *string + // Opaque version string for optimistic locking. If provided, must match the + // current etag. If omitted, the failover proceeds regardless of current state. + Etag *string + // The type of failover to perform. + FailoverType FailoverFailoverGroupRequest_FailoverType +} + +// A failover group manages disaster recovery across workspace sets, +// coordinating Unity Catalog and workspace assets replication.. +type FailoverGroup struct { + // Fully qualified resource name in the format + // accounts/{account_id}/failover-groups/{failover_group_id}. + Name *string `fieldmask:"name"` + // Current effective primary region. Replication flows FROM workspaces in this + // region. Changes after a successful failover. + EffectivePrimaryRegion *string `fieldmask:"effective_primary_region"` + // List of all regions participating in this failover group. + Regions []string `fieldmask:"regions"` + // Workspace sets, each containing workspaces that replicate to each other. + WorkspaceSets []WorkspaceSet `fieldmask:"workspace_sets"` + // Unity Catalog replication configuration. + UnityCatalogAssets *UcReplicationConfig `fieldmask:"unity_catalog_assets"` + // Aggregate state of the failover group. + State FailoverGroup_State `fieldmask:"state"` + // Opaque version string for optimistic locking. Server-generated and returned + // in responses. + Etag *string `fieldmask:"etag"` + // Time at which this failover group was created. + CreateTime *types.Time `fieldmask:"create_time"` + // Time at which this failover group was last modified. + UpdateTime *types.Time `fieldmask:"update_time"` + // The latest point in time to which data has been replicated. + ReplicationPoint *types.Time `fieldmask:"replication_point"` + // Initial primary region. Used only in Create requests to set the starting + // primary region. Not returned in responses. + InitialPrimaryRegion *string `fieldmask:"initial_primary_region"` +} + +// Request to get a failover group.. +type GetFailoverGroupRequest struct { + // The fully qualified resource name of the failover group. Format: + // accounts/{account_id}/failover-groups/{failover_group_id}. + Name *string +} + +// Request to get a stable URL.. +type GetStableUrlRequest struct { + // The fully qualified resource name. Format: + // accounts/{account_id}/stable-urls/{stable_url_id}. + Name *string +} + +// Request to list failover groups for an account.. +type ListFailoverGroupsRequest struct { + // The parent resource. Format: accounts/{account_id}. + Parent *string + // Maximum number of failover groups to return per page: - when set to a value + // greater than 0, the page length is the minimum of this value and a server + // configured value; - when set to 0 or unset, the page length is set to a + // server configured value (recommended); - when set to a value less than 0, an + // invalid parameter error is returned. + PageSize *int + // Page token received from a previous ListFailoverGroups call. Provide this to + // retrieve the subsequent page. + PageToken *string +} + +// Response for listing failover groups.. +type ListFailoverGroupsResponse struct { + // The failover groups for this account. + FailoverGroups []FailoverGroup + // A token that can be sent as page_token to retrieve the next page. If omitted, + // there are no subsequent pages. + NextPageToken *string +} + +// Request to list stable URLs for an account.. +type ListStableUrlsRequest struct { + // The parent resource. Format: accounts/{account_id}. + Parent *string + // Maximum number of stable URLs to return per page: - when set to a value + // greater than 0, the page length is the minimum of this value and a server + // configured value; - when set to 0 or unset, the page length is set to a + // server configured value (recommended); - when set to a value less than 0, an + // invalid parameter error is returned. + PageSize *int + // Page token received from a previous ListStableUrls call. Provide this to + // retrieve the subsequent page. + PageToken *string +} + +// Response for listing stable URLs.. +type ListStableUrlsResponse struct { + // The stable URLs for this account. + StableUrls []StableUrl + // A token that can be sent as page_token to retrieve the next page. If omitted, + // there are no subsequent pages. + NextPageToken *string +} + +// A location mapping identified by a name, with URIs per region. The system +// derives replication direction from effective_primary_region.. +type LocationMapping struct { + // Resource name for this location. + Name *string + // URI for each region. Each entry maps a region name to a storage URI. + UriByRegion []LocationMappingEntry +} + +// A single entry in a location mapping, mapping a region to a storage URI. Used +// instead of map for proto2 compatibility.. +type LocationMappingEntry struct { + // The region name. + Region *string + // The storage URI for this region. + Uri *string +} + +// A stable URL provides a failover-aware endpoint for accessing a workspace. +// Its lifecycle is independent of any failover group.. +type StableUrl struct { + // Fully qualified resource name. Format: + // accounts/{account_id}/stable-urls/{stable_url_id}. + Name *string + // The stable URL endpoint. Generated on creation and immutable thereafter. For + // non-Private-Link workspaces this is `https:///?w=`. + // For Private-Link workspaces this is the per-connection hostname. + Url *string + // The workspace this stable URL is initially bound to. Used only in Create + // requests to associate the stable URL with a workspace. Not returned in + // responses. + InitialWorkspaceId *string + // Fully qualified resource name of the FailoverGroup this stable URL is + // currently linked to, in the format + // `accounts/{account_id}/failover-groups/{failover_group_id}`. Empty when the + // stable URL is not attached to any failover group. + FailoverGroupName *string + // The workspace this stable URL currently routes to. Set to + // `initial_workspace_id` at creation, advanced to the failover group's primary + // while attached (including across a failover), and preserved when the stable + // URL is detached from its failover group. Read this to see where an unattached + // stable URL points: after a failover followed by a detach it reflects the + // post-failover primary, not `initial_workspace_id`. + EffectiveWorkspaceId *string + // The stable workspace ID for this stable URL. Generated on creation and + // immutable thereafter; identifies the URL across failovers and is the same + // value embedded in the `url` (as the `w=` query parameter for SPOG URLs, or in + // the `conn-` hostname for Private-Link URLs). + StableWorkspaceId *string +} + +// A Unity Catalog catalog to replicate.. +type UcCatalog struct { + // The name of the UC catalog to replicate. + Name *string +} + +// Unity Catalog replication configuration (top-level, not per-set).. +type UcReplicationConfig struct { + // Location mappings - storage URI per region for each location. + LocationMappings []LocationMapping `fieldmask:"location_mappings"` + // UC catalogs to replicate. + Catalogs []UcCatalog `fieldmask:"catalogs"` + // The workspace set whose workspaces will be used for data replication of all + // UC catalogs' underlying storage. + DataReplicationWorkspaceSet *string `fieldmask:"data_replication_workspace_set"` +} + +// Request to update a failover group.. +type UpdateFailoverGroupRequest struct { + // The failover group with updated fields. The name field identifies the + // resource and is populated from the URL path. + FailoverGroup *FailoverGroup + // Comma-separated list of fields to update. + UpdateMask *types.FieldMask[FailoverGroup] + // Optional opaque version string for optimistic locking, obtained from a prior + // read of the failover group. If provided, the update is rejected unless it + // matches the failover group's current etag. If omitted, the update proceeds + // without an optimistic-lock check. + Etag *string +} + +// A set of workspaces that replicate to each other across regions.. +type WorkspaceSet struct { + // Resource name for this workspace set. + Name *string + // Workspace IDs in this set. The system derives and validates regions. All + // workspaces must be in the Mission Critical tier. + WorkspaceIds []string + // Whether to enable control plane DR (notebooks, jobs, clusters, etc.) for this + // set. Defaults to false. + ReplicateWorkspaceAssets *bool + // Resource names of stable URLs associated with this workspace set. Format: + // accounts/{account_id}/stable-urls/{stable_url_id}. The referenced stable URLs + // must already exist (via CreateStableUrl). + StableUrlNames []string +} diff --git a/disasterrecovery/v1/wire.go b/disasterrecovery/v1/wire.go new file mode 100755 index 0000000..56b5bc5 --- /dev/null +++ b/disasterrecovery/v1/wire.go @@ -0,0 +1,465 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package disasterrecovery + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createFailoverGroupRequestWire struct { + Parent *string `json:"parent,omitempty"` + FailoverGroup *failoverGroupWire `json:"failover_group,omitempty"` + ValidateOnly *bool `json:"validate_only,omitempty"` + FailoverGroupId *string `json:"failover_group_id,omitempty"` +} + +func createFailoverGroupRequestToWire(v *CreateFailoverGroupRequest) (*createFailoverGroupRequestWire, error) { + if v == nil { + return nil, nil + } + failoverGroupWireValue, err := failoverGroupToWire(v.FailoverGroup) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateFailoverGroupRequest.FailoverGroup", err) + } + return &createFailoverGroupRequestWire{ + Parent: v.Parent, + FailoverGroup: failoverGroupWireValue, + ValidateOnly: v.ValidateOnly, + FailoverGroupId: v.FailoverGroupId, + }, nil +} + +type createStableUrlRequestWire struct { + Parent *string `json:"parent,omitempty"` + StableUrl *stableUrlWire `json:"stable_url,omitempty"` + ValidateOnly *bool `json:"validate_only,omitempty"` + StableUrlId *string `json:"stable_url_id,omitempty"` +} + +func createStableUrlRequestToWire(v *CreateStableUrlRequest) (*createStableUrlRequestWire, error) { + if v == nil { + return nil, nil + } + stableUrlWireValue, err := stableUrlToWire(v.StableUrl) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateStableUrlRequest.StableUrl", err) + } + return &createStableUrlRequestWire{ + Parent: v.Parent, + StableUrl: stableUrlWireValue, + ValidateOnly: v.ValidateOnly, + StableUrlId: v.StableUrlId, + }, nil +} + +type deleteFailoverGroupRequestWire struct { + Name *string `json:"name,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +func deleteFailoverGroupRequestToWire(v *DeleteFailoverGroupRequest) (*deleteFailoverGroupRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteFailoverGroupRequestWire{ + Name: v.Name, + Etag: v.Etag, + }, nil +} + +type failoverFailoverGroupRequestWire struct { + Name *string `json:"name,omitempty"` + TargetPrimaryRegion *string `json:"target_primary_region,omitempty"` + Etag *string `json:"etag,omitempty"` + FailoverType FailoverFailoverGroupRequest_FailoverType `json:"failover_type,omitempty"` +} + +func failoverFailoverGroupRequestToWire(v *FailoverFailoverGroupRequest) (*failoverFailoverGroupRequestWire, error) { + if v == nil { + return nil, nil + } + return &failoverFailoverGroupRequestWire{ + Name: v.Name, + TargetPrimaryRegion: v.TargetPrimaryRegion, + Etag: v.Etag, + FailoverType: v.FailoverType, + }, nil +} + +type failoverGroupWire struct { + Name *string `json:"name,omitempty"` + EffectivePrimaryRegion *string `json:"effective_primary_region,omitempty"` + Regions []string `json:"regions,omitempty"` + WorkspaceSets []workspaceSetWire `json:"workspace_sets,omitempty"` + UnityCatalogAssets *ucReplicationConfigWire `json:"unity_catalog_assets,omitempty"` + State FailoverGroup_State `json:"state,omitempty"` + Etag *string `json:"etag,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + ReplicationPoint *types.Time `json:"replication_point,omitempty"` + InitialPrimaryRegion *string `json:"initial_primary_region,omitempty"` +} + +func failoverGroupToWire(v *FailoverGroup) (*failoverGroupWire, error) { + if v == nil { + return nil, nil + } + workspaceSetsWireValue, err := convertSlice(v.WorkspaceSets, workspaceSetToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FailoverGroup.WorkspaceSets", err) + } + unityCatalogAssetsWireValue, err := ucReplicationConfigToWire(v.UnityCatalogAssets) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FailoverGroup.UnityCatalogAssets", err) + } + return &failoverGroupWire{ + Name: v.Name, + EffectivePrimaryRegion: v.EffectivePrimaryRegion, + Regions: v.Regions, + WorkspaceSets: workspaceSetsWireValue, + UnityCatalogAssets: unityCatalogAssetsWireValue, + State: v.State, + Etag: v.Etag, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + ReplicationPoint: v.ReplicationPoint, + InitialPrimaryRegion: v.InitialPrimaryRegion, + }, nil +} + +func failoverGroupFromWire(w *failoverGroupWire) (*FailoverGroup, error) { + if w == nil { + return nil, nil + } + workspaceSetsPublicValue, err := convertSlice(w.WorkspaceSets, workspaceSetFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FailoverGroup.WorkspaceSets", err) + } + unityCatalogAssetsPublicValue, err := ucReplicationConfigFromWire(w.UnityCatalogAssets) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FailoverGroup.UnityCatalogAssets", err) + } + return &FailoverGroup{ + Name: w.Name, + EffectivePrimaryRegion: w.EffectivePrimaryRegion, + Regions: w.Regions, + WorkspaceSets: workspaceSetsPublicValue, + UnityCatalogAssets: unityCatalogAssetsPublicValue, + State: w.State, + Etag: w.Etag, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + ReplicationPoint: w.ReplicationPoint, + InitialPrimaryRegion: w.InitialPrimaryRegion, + }, nil +} + +type listFailoverGroupsRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listFailoverGroupsRequestToWire(v *ListFailoverGroupsRequest) (*listFailoverGroupsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listFailoverGroupsRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listFailoverGroupsResponseWire struct { + FailoverGroups []failoverGroupWire `json:"failover_groups,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listFailoverGroupsResponseFromWire(w *listFailoverGroupsResponseWire) (*ListFailoverGroupsResponse, error) { + if w == nil { + return nil, nil + } + failoverGroupsPublicValue, err := convertSlice(w.FailoverGroups, failoverGroupFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListFailoverGroupsResponse.FailoverGroups", err) + } + return &ListFailoverGroupsResponse{ + FailoverGroups: failoverGroupsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listStableUrlsRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listStableUrlsRequestToWire(v *ListStableUrlsRequest) (*listStableUrlsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listStableUrlsRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listStableUrlsResponseWire struct { + StableUrls []stableUrlWire `json:"stable_urls,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listStableUrlsResponseFromWire(w *listStableUrlsResponseWire) (*ListStableUrlsResponse, error) { + if w == nil { + return nil, nil + } + stableUrlsPublicValue, err := convertSlice(w.StableUrls, stableUrlFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListStableUrlsResponse.StableUrls", err) + } + return &ListStableUrlsResponse{ + StableUrls: stableUrlsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type locationMappingWire struct { + Name *string `json:"name,omitempty"` + UriByRegion []locationMappingEntryWire `json:"uri_by_region,omitempty"` +} + +func locationMappingToWire(v *LocationMapping) (*locationMappingWire, error) { + if v == nil { + return nil, nil + } + uriByRegionWireValue, err := convertSlice(v.UriByRegion, locationMappingEntryToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LocationMapping.UriByRegion", err) + } + return &locationMappingWire{ + Name: v.Name, + UriByRegion: uriByRegionWireValue, + }, nil +} + +func locationMappingFromWire(w *locationMappingWire) (*LocationMapping, error) { + if w == nil { + return nil, nil + } + uriByRegionPublicValue, err := convertSlice(w.UriByRegion, locationMappingEntryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LocationMapping.UriByRegion", err) + } + return &LocationMapping{ + Name: w.Name, + UriByRegion: uriByRegionPublicValue, + }, nil +} + +type locationMappingEntryWire struct { + Region *string `json:"region,omitempty"` + Uri *string `json:"uri,omitempty"` +} + +func locationMappingEntryToWire(v *LocationMappingEntry) (*locationMappingEntryWire, error) { + if v == nil { + return nil, nil + } + return &locationMappingEntryWire{ + Region: v.Region, + Uri: v.Uri, + }, nil +} + +func locationMappingEntryFromWire(w *locationMappingEntryWire) (*LocationMappingEntry, error) { + if w == nil { + return nil, nil + } + return &LocationMappingEntry{ + Region: w.Region, + Uri: w.Uri, + }, nil +} + +type stableUrlWire struct { + Name *string `json:"name,omitempty"` + Url *string `json:"url,omitempty"` + InitialWorkspaceId *string `json:"initial_workspace_id,omitempty"` + FailoverGroupName *string `json:"failover_group_name,omitempty"` + EffectiveWorkspaceId *string `json:"effective_workspace_id,omitempty"` + StableWorkspaceId *string `json:"stable_workspace_id,omitempty"` +} + +func stableUrlToWire(v *StableUrl) (*stableUrlWire, error) { + if v == nil { + return nil, nil + } + return &stableUrlWire{ + Name: v.Name, + Url: v.Url, + InitialWorkspaceId: v.InitialWorkspaceId, + FailoverGroupName: v.FailoverGroupName, + EffectiveWorkspaceId: v.EffectiveWorkspaceId, + StableWorkspaceId: v.StableWorkspaceId, + }, nil +} + +func stableUrlFromWire(w *stableUrlWire) (*StableUrl, error) { + if w == nil { + return nil, nil + } + return &StableUrl{ + Name: w.Name, + Url: w.Url, + InitialWorkspaceId: w.InitialWorkspaceId, + FailoverGroupName: w.FailoverGroupName, + EffectiveWorkspaceId: w.EffectiveWorkspaceId, + StableWorkspaceId: w.StableWorkspaceId, + }, nil +} + +type ucCatalogWire struct { + Name *string `json:"name,omitempty"` +} + +func ucCatalogToWire(v *UcCatalog) (*ucCatalogWire, error) { + if v == nil { + return nil, nil + } + return &ucCatalogWire{ + Name: v.Name, + }, nil +} + +func ucCatalogFromWire(w *ucCatalogWire) (*UcCatalog, error) { + if w == nil { + return nil, nil + } + return &UcCatalog{ + Name: w.Name, + }, nil +} + +type ucReplicationConfigWire struct { + LocationMappings []locationMappingWire `json:"location_mappings,omitempty"` + Catalogs []ucCatalogWire `json:"catalogs,omitempty"` + DataReplicationWorkspaceSet *string `json:"data_replication_workspace_set,omitempty"` +} + +func ucReplicationConfigToWire(v *UcReplicationConfig) (*ucReplicationConfigWire, error) { + if v == nil { + return nil, nil + } + locationMappingsWireValue, err := convertSlice(v.LocationMappings, locationMappingToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UcReplicationConfig.LocationMappings", err) + } + catalogsWireValue, err := convertSlice(v.Catalogs, ucCatalogToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UcReplicationConfig.Catalogs", err) + } + return &ucReplicationConfigWire{ + LocationMappings: locationMappingsWireValue, + Catalogs: catalogsWireValue, + DataReplicationWorkspaceSet: v.DataReplicationWorkspaceSet, + }, nil +} + +func ucReplicationConfigFromWire(w *ucReplicationConfigWire) (*UcReplicationConfig, error) { + if w == nil { + return nil, nil + } + locationMappingsPublicValue, err := convertSlice(w.LocationMappings, locationMappingFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UcReplicationConfig.LocationMappings", err) + } + catalogsPublicValue, err := convertSlice(w.Catalogs, ucCatalogFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UcReplicationConfig.Catalogs", err) + } + return &UcReplicationConfig{ + LocationMappings: locationMappingsPublicValue, + Catalogs: catalogsPublicValue, + DataReplicationWorkspaceSet: w.DataReplicationWorkspaceSet, + }, nil +} + +type updateFailoverGroupRequestWire struct { + FailoverGroup *failoverGroupWire `json:"failover_group,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +func updateFailoverGroupRequestToWire(v *UpdateFailoverGroupRequest) (*updateFailoverGroupRequestWire, error) { + if v == nil { + return nil, nil + } + failoverGroupWireValue, err := failoverGroupToWire(v.FailoverGroup) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateFailoverGroupRequest.FailoverGroup", err) + } + return &updateFailoverGroupRequestWire{ + FailoverGroup: failoverGroupWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + Etag: v.Etag, + }, nil +} + +type workspaceSetWire struct { + Name *string `json:"name,omitempty"` + WorkspaceIds []string `json:"workspace_ids,omitempty"` + ReplicateWorkspaceAssets *bool `json:"replicate_workspace_assets,omitempty"` + StableUrlNames []string `json:"stable_url_names,omitempty"` +} + +func workspaceSetToWire(v *WorkspaceSet) (*workspaceSetWire, error) { + if v == nil { + return nil, nil + } + return &workspaceSetWire{ + Name: v.Name, + WorkspaceIds: v.WorkspaceIds, + ReplicateWorkspaceAssets: v.ReplicateWorkspaceAssets, + StableUrlNames: v.StableUrlNames, + }, nil +} + +func workspaceSetFromWire(w *workspaceSetWire) (*WorkspaceSet, error) { + if w == nil { + return nil, nil + } + return &WorkspaceSet{ + Name: w.Name, + WorkspaceIds: w.WorkspaceIds, + ReplicateWorkspaceAssets: w.ReplicateWorkspaceAssets, + StableUrlNames: w.StableUrlNames, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/environments/.package.json b/environments/.package.json new file mode 100644 index 0000000..c9374a7 --- /dev/null +++ b/environments/.package.json @@ -0,0 +1,3 @@ +{ + "package": "environments" +} diff --git a/environments/CHANGELOG.md b/environments/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/environments/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/environments/README.md b/environments/README.md new file mode 100644 index 0000000..ed7351e --- /dev/null +++ b/environments/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/environments + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/environments@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/environments/v1" + +client, err := environments.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/environments/go.mod b/environments/go.mod new file mode 100644 index 0000000..b14ef4c --- /dev/null +++ b/environments/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/environments + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/environments/internal/version.go b/environments/internal/version.go new file mode 100644 index 0000000..3d73e05 --- /dev/null +++ b/environments/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-environments" + +const Version = "0.0.1-dev.1" diff --git a/environments/v1/client.go b/environments/v1/client.go new file mode 100755 index 0000000..f1d4f04 --- /dev/null +++ b/environments/v1/client.go @@ -0,0 +1,1042 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package environments + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/environments/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new WorkspaceBaseEnvironment. This is a long-running operation. The +// operation will asynchronously generate a materialized environment to optimize +// dependency resolution and is only marked as done when the materialized +// environment has been successfully generated or has failed. +func (c *internalClient) createWorkspaceBaseEnvironmentBase(ctx context.Context, req *CreateWorkspaceBaseEnvironmentRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createWorkspaceBaseEnvironmentRequestToWire(req) + if err != nil { + return nil, err + } + if wireReq.RequestId == nil || *wireReq.RequestId == "" { + wireReq.RequestId = new(generateRequestID()) + } + body, err := json.Marshal(wireReq.WorkspaceBaseEnvironment) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/environments/v1/workspace-base-environments" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "workspace_base_environment_id", wireReq.WorkspaceBaseEnvironmentId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "request_id", wireReq.RequestId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new WorkspaceBaseEnvironment. This is a long-running operation. The +// operation will asynchronously generate a materialized environment to optimize +// dependency resolution and is only marked as done when the materialized +// environment has been successfully generated or has failed. +func (c *internalClient) CreateWorkspaceBaseEnvironment(ctx context.Context, req *CreateWorkspaceBaseEnvironmentRequest, opts ...call.Option) (*CreateWorkspaceBaseEnvironmentOperation, error) { + operation, err := c.createWorkspaceBaseEnvironmentBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateWorkspaceBaseEnvironmentOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// CreateWorkspaceBaseEnvironmentOperation tracks the state of the long-running operation started by CreateWorkspaceBaseEnvironment. +type CreateWorkspaceBaseEnvironmentOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateWorkspaceBaseEnvironmentOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateWorkspaceBaseEnvironmentOperation) Metadata() (*WorkspaceBaseEnvironmentOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata workspaceBaseEnvironmentOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := workspaceBaseEnvironmentOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateWorkspaceBaseEnvironmentOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateWorkspaceBaseEnvironmentOperation) Wait(ctx context.Context, opts ...lro.Option) (*WorkspaceBaseEnvironment, error) { + var result *WorkspaceBaseEnvironment + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response workspaceBaseEnvironmentWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = workspaceBaseEnvironmentFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Deletes a WorkspaceBaseEnvironment. Deleting a base environment may impact +// linked notebooks and jobs. This operation is irreversible and should be +// performed only when you are certain the environment is no longer needed. +func (c *internalClient) DeleteWorkspaceBaseEnvironment(ctx context.Context, req *DeleteWorkspaceBaseEnvironmentRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/environments/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets the default WorkspaceBaseEnvironment configuration for the workspace. +// Returns the current default base environment settings for both CPU and GPU +// compute. +func (c *internalClient) GetDefaultWorkspaceBaseEnvironment(ctx context.Context, req *GetDefaultWorkspaceBaseEnvironmentRequest, opts ...call.Option) (*DefaultWorkspaceBaseEnvironment, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/environments/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DefaultWorkspaceBaseEnvironment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp defaultWorkspaceBaseEnvironmentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = defaultWorkspaceBaseEnvironmentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the status of a long-running operation. Clients can use this method to +// poll the operation result. +func (c *internalClient) getOperation(ctx context.Context, req *GetOperationRequest, opts ...call.Option) (*Operation, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/environments/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves a WorkspaceBaseEnvironment by its name. +func (c *internalClient) GetWorkspaceBaseEnvironment(ctx context.Context, req *GetWorkspaceBaseEnvironmentRequest, opts ...call.Option) (*WorkspaceBaseEnvironment, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/environments/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *WorkspaceBaseEnvironment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp workspaceBaseEnvironmentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = workspaceBaseEnvironmentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists all WorkspaceBaseEnvironments in the workspace. +// +// provides the following base environments: +// +// - `workspace-base-environments/databricks_ai_...`: includes popular AI and +// deep learning packages for serverless GPU compute. - +// `workspace-base-environments/databricks_ml_...`: includes popular ML packages +// for serverless compute. +// +// Databricks-provided base environments are versioned. For example, +// `workspace-base-environments/databricks_ml_v5` corresponds to the ML +// environment built on environment version 5. +func (c *internalClient) ListWorkspaceBaseEnvironments(ctx context.Context, req *ListWorkspaceBaseEnvironmentsRequest, opts ...call.Option) (*ListWorkspaceBaseEnvironmentsResponse, error) { + wireReq, err := listWorkspaceBaseEnvironmentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/environments/v1/workspace-base-environments" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListWorkspaceBaseEnvironmentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listWorkspaceBaseEnvironmentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listWorkspaceBaseEnvironmentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListWorkspaceBaseEnvironmentsIter returns an iterator that iterates +// over the results of ListWorkspaceBaseEnvironments. +// +// For example: +// +// for item, err := range c.ListWorkspaceBaseEnvironmentsIter(ctx, &ListWorkspaceBaseEnvironmentsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListWorkspaceBaseEnvironments call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListWorkspaceBaseEnvironments directly. +func (c *internalClient) ListWorkspaceBaseEnvironmentsIter(ctx context.Context, req *ListWorkspaceBaseEnvironmentsRequest, opts ...call.Option) iter.Seq2[*WorkspaceBaseEnvironment, error] { + return func(yield func(*WorkspaceBaseEnvironment, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListWorkspaceBaseEnvironmentsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListWorkspaceBaseEnvironments(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.WorkspaceBaseEnvironments { + if !yield(&resp.WorkspaceBaseEnvironments[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Refreshes the materialized environment for a WorkspaceBaseEnvironment. This +// is a long-running operation. The operation will asynchronously regenerate the +// materialized environment and is only marked as done when the materialized +// environment has been successfully generated or has failed. The existing +// materialized environment remains available until it expires. +func (c *internalClient) refreshWorkspaceBaseEnvironmentBase(ctx context.Context, req *RefreshWorkspaceBaseEnvironmentRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := refreshWorkspaceBaseEnvironmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/environments/v1/") + pb.singleSegment(*req.Name) + pb.literal("/refresh") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Refreshes the materialized environment for a WorkspaceBaseEnvironment. This +// is a long-running operation. The operation will asynchronously regenerate the +// materialized environment and is only marked as done when the materialized +// environment has been successfully generated or has failed. The existing +// materialized environment remains available until it expires. +func (c *internalClient) RefreshWorkspaceBaseEnvironment(ctx context.Context, req *RefreshWorkspaceBaseEnvironmentRequest, opts ...call.Option) (*RefreshWorkspaceBaseEnvironmentOperation, error) { + operation, err := c.refreshWorkspaceBaseEnvironmentBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &RefreshWorkspaceBaseEnvironmentOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// RefreshWorkspaceBaseEnvironmentOperation tracks the state of the long-running operation started by RefreshWorkspaceBaseEnvironment. +type RefreshWorkspaceBaseEnvironmentOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *RefreshWorkspaceBaseEnvironmentOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *RefreshWorkspaceBaseEnvironmentOperation) Metadata() (*WorkspaceBaseEnvironmentOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata workspaceBaseEnvironmentOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := workspaceBaseEnvironmentOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *RefreshWorkspaceBaseEnvironmentOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *RefreshWorkspaceBaseEnvironmentOperation) Wait(ctx context.Context, opts ...lro.Option) (*WorkspaceBaseEnvironment, error) { + var result *WorkspaceBaseEnvironment + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response workspaceBaseEnvironmentWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = workspaceBaseEnvironmentFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Updates the default WorkspaceBaseEnvironment configuration for the workspace. +// Sets the specified base environments as the workspace defaults for CPU and/or +// GPU compute. +func (c *internalClient) UpdateDefaultWorkspaceBaseEnvironment(ctx context.Context, req *UpdateDefaultWorkspaceBaseEnvironmentRequest, opts ...call.Option) (*DefaultWorkspaceBaseEnvironment, error) { + wireReq, err := updateDefaultWorkspaceBaseEnvironmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.DefaultWorkspaceBaseEnvironment) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/environments/v1/") + pb.singleSegment(*req.DefaultWorkspaceBaseEnvironment.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DefaultWorkspaceBaseEnvironment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp defaultWorkspaceBaseEnvironmentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = defaultWorkspaceBaseEnvironmentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an existing WorkspaceBaseEnvironment. This is a long-running +// operation. The operation will asynchronously regenerate the materialized +// environment and is only marked as done when the materialized environment has +// been successfully generated or has failed. The existing materialized +// environment remains available until it expires. +func (c *internalClient) updateWorkspaceBaseEnvironmentBase(ctx context.Context, req *UpdateWorkspaceBaseEnvironmentRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := updateWorkspaceBaseEnvironmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.WorkspaceBaseEnvironment) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/environments/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an existing WorkspaceBaseEnvironment. This is a long-running +// operation. The operation will asynchronously regenerate the materialized +// environment and is only marked as done when the materialized environment has +// been successfully generated or has failed. The existing materialized +// environment remains available until it expires. +func (c *internalClient) UpdateWorkspaceBaseEnvironment(ctx context.Context, req *UpdateWorkspaceBaseEnvironmentRequest, opts ...call.Option) (*UpdateWorkspaceBaseEnvironmentOperation, error) { + operation, err := c.updateWorkspaceBaseEnvironmentBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &UpdateWorkspaceBaseEnvironmentOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// UpdateWorkspaceBaseEnvironmentOperation tracks the state of the long-running operation started by UpdateWorkspaceBaseEnvironment. +type UpdateWorkspaceBaseEnvironmentOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *UpdateWorkspaceBaseEnvironmentOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *UpdateWorkspaceBaseEnvironmentOperation) Metadata() (*WorkspaceBaseEnvironmentOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata workspaceBaseEnvironmentOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := workspaceBaseEnvironmentOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *UpdateWorkspaceBaseEnvironmentOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *UpdateWorkspaceBaseEnvironmentOperation) Wait(ctx context.Context, opts ...lro.Option) (*WorkspaceBaseEnvironment, error) { + var result *WorkspaceBaseEnvironment + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response workspaceBaseEnvironmentWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = workspaceBaseEnvironmentFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} diff --git a/environments/v1/genhelper.go b/environments/v1/genhelper.go new file mode 100755 index 0000000..da76122 --- /dev/null +++ b/environments/v1/genhelper.go @@ -0,0 +1,264 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package environments + +import ( + "bytes" + "context" + "crypto/rand" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func validateOperationName(operationName *string) error { + if operationName == nil || *operationName == "" { + return errors.New("invalid operation response: missing operation name") + } + return nil +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// generateRequestID returns a random RFC 4122 version 4 UUID string, used as an +// idempotency token when the caller does not supply one. It uses crypto/rand to +// avoid a UUID dependency; a read failure is treated as unrecoverable. +func generateRequestID() string { + var b [16]byte + if _, err := rand.Read(b[:]); err != nil { + panic(fmt.Sprintf("generate request id: %v", err)) + } + b[6] = (b[6] & 0x0f) | 0x40 // version 4 + b[8] = (b[8] & 0x3f) | 0x80 // variant 10 + return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16]) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/environments/v1/model.go b/environments/v1/model.go new file mode 100755 index 0000000..98ffff2 --- /dev/null +++ b/environments/v1/model.go @@ -0,0 +1,657 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package environments + +import ( + "encoding/json" + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +// If changed, also update +// estore/namespaces/defaultbaseenvironments/latest.proto +type BaseEnvironmentType string + +const ( + BaseEnvironmentType_Unspecified BaseEnvironmentType = "" + BaseEnvironmentType_Cpu BaseEnvironmentType = "CPU" + BaseEnvironmentType_Gpu BaseEnvironmentType = "GPU" +) + +// Error codes returned by Databricks APIs to indicate specific failure +// conditions. +type ErrorCode string + +const ( + ErrorCode_Unspecified ErrorCode = "" + // Internal error. This means that some invariants expected by the underlying + // system have been broken. This error code is reserved for serious errors, + // which generally cannot be resolved by the user. + // + // Prefer this over all kinds of detailed error messages (e.g IO_ERROR), unless + // there's some automation that relies on the custom error code. + // + // Maps to: - google.rpc.Code: INTERNAL = 13; - HTTP code: 500 Internal Server + // Error + ErrorCode_InternalError ErrorCode = "INTERNAL_ERROR" + // The service is currently unavailable. This is most likely a transient + // condition, which can be corrected by retrying with a backoff. Note that it is + // not always safe to retry non-idempotent operations. + // + // Prefer this over SERVICE_UNDER_MAINTENANCE, + // WORKSPACE_TEMPORARILY_UNAVAILABLE. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on how to pick this vs RESOURCE_EXHAUSTED. + // + // Maps to: - google.rpc.Code: UNAVAILABLE = 14; - HTTP code: 503 Service + // Unavailable + ErrorCode_TemporarilyUnavailable ErrorCode = "TEMPORARILY_UNAVAILABLE" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Indicates that an IOException has been internally + // thrown. + ErrorCode_IoError ErrorCode = "IO_ERROR" + // The request is invalid. Prefer more specific error code whenever possible. + // Also see similar recommendation for the google.rpc.Code.FAILED_PRECONDITION. + // + // Prefer this error code over MALFORMED_REQUEST, INVALID_STATE, + // UNPARSEABLE_HTTP_ERROR. + // + // Maps to: - google.rpc.Code: FAILED_PRECONDITION = 9; - HTTP code: 400 Bad + // Request + ErrorCode_BadRequest ErrorCode = "BAD_REQUEST" + // An external service is unavailable temporarily as it is being + // updated/re-deployed. Indicates gateway proxy to safely retry the request. + ErrorCode_ServiceUnderMaintenance ErrorCode = "SERVICE_UNDER_MAINTENANCE" + // A workspace is temporarily unavailable as the workspace is being re-assigned. + ErrorCode_WorkspaceTemporarilyUnavailable ErrorCode = "WORKSPACE_TEMPORARILY_UNAVAILABLE" + // The deadline expired before the operation could complete. For operations that + // change the state of the system, this error may be returned even if the + // operation has completed successfully. For example, a successful response from + // a server could have been delayed long enough for the deadline to expire. When + // possible - implementations should make sure further processing of the request + // is aborted, e.g. by throwing an exception instead of making the RPC request, + // making the database query, etc. + // + // Maps to: - google.rpc.Code: DEADLINE_EXCEEDED = 4; - HTTP code: 504 Gateway + // Timeout + ErrorCode_DeadlineExceeded ErrorCode = "DEADLINE_EXCEEDED" + // The operation was canceled by the caller. An example - client closed the + // connection without waiting for a response. + // + // Maps to: - google.rpc.Code: CANCELLED = 1; - HTTP code: 499 Client Closed + // Request + ErrorCode_Cancelled ErrorCode = "CANCELLED" + // The operation is rejected because of either rate limiting or resource quota, + // such as the client has sent too many requests recently or the client has + // allocated too many resources. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on how to pick this vs TEMPORARILY_UNAVAILABLE. + // + // Maps to: - google.rpc.Code: RESOURCE_EXHAUSTED = 8; - HTTP code: 429 Too Many + // Requests + ErrorCode_ResourceExhausted ErrorCode = "RESOURCE_EXHAUSTED" + // The operation was aborted, typically due to a concurrency issue such as a + // sequencer check failure, transaction abort, or transaction conflict. + // + // Maps to: - google.rpc.Code: ABORTED = 10; - HTTP code: 409 Conflict + ErrorCode_Aborted ErrorCode = "ABORTED" + // Operation was performed on a resource that does not exist, e.g. file or + // directory was not found. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_NotFound ErrorCode = "NOT_FOUND" + // Operation was rejected due a conflict with an existing resource, e.g. + // attempted to create file or directory that already exists. + // + // Prefer this over RESOURCE_CONFLICT. + // + // Maps to: - google.rpc.Code: ALREADY_EXISTS = 6; - HTTP code: 409 Conflict + ErrorCode_AlreadyExists ErrorCode = "ALREADY_EXISTS" + // The request does not have valid authentication (AuthN) credentials for the + // operation. + // + // Prefer this over CUSTOMER_UNAUTHORIZED, unless you need to keep consistent + // behavior with legacy code. For authorization (AuthZ) errors use + // PERMISSION_DENIED. Maps to: - google.rpc.Code: UNAUTHENTICATED = 16; - HTTP + // code: 401 Unauthorized + ErrorCode_Unauthenticated ErrorCode = "UNAUTHENTICATED" + // The service is currently unavailable. Please note that the unavailability may + // or may not be transient. That means if this is a non-transient condition, + // retrying it does not work. If the unavailability is certainly a transient + // condition, pleases use `TEMPORARILY_UNAVAILABLE` which signals its transient + // nature explicitly. An example of this error code’s use case is that when + // DNS resolution fails, the DNS resolver does not know whether it is because + // the domain name is completely wrong (non-transient situation) or the domain + // name is valid but the DNS server does not have an entry for this domain name + // yet (transient situation). Hence, `UNAVAILABLE` is suitable for this case. + // + // Maps to: - google.rpc.Code: UNAVAILABLE = 14; - HTTP code: 503 Service + // Unavailable + ErrorCode_Unavailable ErrorCode = "UNAVAILABLE" + // Supplied value for a parameter was invalid (e.g., giving a number for a + // string parameter). + // + // Maps to: - google.rpc.Code: INVALID_ARGUMENT = 3; - HTTP code: 400 Bad + // Request + ErrorCode_InvalidParameterValue ErrorCode = "INVALID_PARAMETER_VALUE" + // Indicates that the given API endpoint does not exist. Legacy, when possible - + // NOT_IMPLEMENTED should be used instead to indicate that API doesn't exist. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_EndpointNotFound ErrorCode = "ENDPOINT_NOT_FOUND" + // Indicates that the given API request was malformed. + ErrorCode_MalformedRequest ErrorCode = "MALFORMED_REQUEST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. If one or more of the inputs to a given RPC are not in + // a valid state for the action. + ErrorCode_InvalidState ErrorCode = "INVALID_STATE" + // The caller does not have permission to execute the specified operation. + // PERMISSION_DENIED must not be used for rejections caused by exhausting some + // resource, use RESOURCE_EXHAUSTED instead for those errors. PERMISSION_DENIED + // must not be used if the caller can not be identified, use + // CUSTOMER_UNAUTHORIZED instead for those errors. This error code does not + // imply the request is valid or the requested entity exists or satisfies other + // pre-conditions. + // + // Maps to: - google.rpc.Code: PERMISSION_DENIED = 7; - HTTP code: 403 Forbidden + ErrorCode_PermissionDenied ErrorCode = "PERMISSION_DENIED" + // NOTE: Deprecated due to inconsistent mapping in legacy code, see + // https://docs.google.com/document/d/17TZIKX_Y39cJMBr333lc-d5dTvvBLSu3DPUyGU5eMJg/edit?disco=AAAAzVGt6FA. + // Prefer using NOT_FOUND or PERMISSION_DENIED. + // + // If a given user/entity is trying to use a feature which has been disabled. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_FeatureDisabled ErrorCode = "FEATURE_DISABLED" + // The request does not have valid authentication (AuthN) credentials for the + // operation. + // + // For authentication (AuthN) errors prefer using UNAUTHENTICATED, unless you + // need to keep consistent behavior with legacy code. For authorization (AuthZ) + // errors use PERMISSION_DENIED. + // + // Important: name is confusing, this error code is for authentication (AuthN) + // errors, not authorization (AuthZ) errors. It maps to 401 Unauthorized and + // suffers from the same confusing naming. See + // https://datatracker.ietf.org/doc/html/rfc7235#section-3.1 - "[...] status + // code indicates that the request has not been applied because it lacks valid + // authentication credentials for the target resource. [...] If the request + // included authentication credentials, then the 401 response indicates that + // authorization has been refused for those credentials." + // + // Also, see https://stackoverflow.com/a/6937030/16352922, it covers it pretty + // well. + // + // Maps to: - google.rpc.Code: UNAUTHENTICATED = 16; - HTTP code: 401 + // Unauthorized + ErrorCode_CustomerUnauthorized ErrorCode = "CUSTOMER_UNAUTHORIZED" + // The operation is rejected because of request rate limit, for example rate + // limiting applied to users, workspaces, IP addresses, etc. + // + // Prefer a more generic RESOURCE_EXHAUSTED for the new use cases. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on the rate limiting vs throttling. + // + // Maps to: - google.rpc.Code: RESOURCE_EXHAUSTED = 8; - HTTP code: 429 Too Many + // Requests + ErrorCode_RequestLimitExceeded ErrorCode = "REQUEST_LIMIT_EXCEEDED" + // Indicates API request was rejected due a conflict with an existing resource. + ErrorCode_ResourceConflict ErrorCode = "RESOURCE_CONFLICT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Indicates that the HTTP response cannot be correctly + // deserialized. This currently is only used in DUST test clients, and not by + // any real service code. + ErrorCode_UnparseableHttpError ErrorCode = "UNPARSEABLE_HTTP_ERROR" + // The operation is not implemented or is not supported/enabled in this service. + // + // Maps to: - google.rpc.Code: UNIMPLEMENTED = 12; - HTTP code: 501 Not + // Implemented + ErrorCode_NotImplemented ErrorCode = "NOT_IMPLEMENTED" + // Unrecoverable data loss or corruption. + // + // One of the major use cases is to indicate that server failed to validate the + // integrity of the request. This error can occur when the checksum specified in + // the `X-Databricks-Checksum` request header (or trailer) doesn't match the + // actual request content checksum. + // + // Note, in case of the severe corruption that results in a malformed request, + // the server may send a generic `400 Bad Request` response rather than sending + // this error code. + // + // Maps to: - google.rpc.Code: DATA_LOSS = 15; - HTTP code: 500 Internal Server + // Error + ErrorCode_DataLoss ErrorCode = "DATA_LOSS" + // If the user attempts to perform an invalid state transition on a shard. + ErrorCode_InvalidStateTransition ErrorCode = "INVALID_STATE_TRANSITION" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Unable to perform the operation because the shard was + // locked by some other operation. + ErrorCode_CouldNotAcquireLock ErrorCode = "COULD_NOT_ACQUIRE_LOCK" + // NOTE: Deprecated, prefer using ALREADY_EXISTS. Unlike ALREADY_EXISTS - this + // maps to HTTP code 400 Bad Request due to legacy reasons, remapping will be a + // backwards incompatible change. + // + // Operation was performed on a resource that already exists. + ErrorCode_ResourceAlreadyExists ErrorCode = "RESOURCE_ALREADY_EXISTS" + // NOTE: Deprecated, prefer using NOT_FOUND - see the note for the + // RESOURCE_ALREADY_EXISTS, because this pair of codes is related and + // RESOURCE_ALREADY_EXISTS has bad mapping to the HTTP codes we added new error + // codes NOT_FOUND and ALREADY_EXISTS, and recommend to use them instead. + // + // Operation was performed on a resource that does not exist. + ErrorCode_ResourceDoesNotExist ErrorCode = "RESOURCE_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_QuotaExceeded ErrorCode = "QUOTA_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxBlockSizeExceeded ErrorCode = "MAX_BLOCK_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxReadSizeExceeded ErrorCode = "MAX_READ_SIZE_EXCEEDED" + ErrorCode_PartialDelete ErrorCode = "PARTIAL_DELETE" + ErrorCode_MaxListSizeExceeded ErrorCode = "MAX_LIST_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DryRunFailed ErrorCode = "DRY_RUN_FAILED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Cluster request was rejected because it would exceed a + // resource limit. + ErrorCode_ResourceLimitExceeded ErrorCode = "RESOURCE_LIMIT_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DirectoryNotEmpty ErrorCode = "DIRECTORY_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DirectoryProtected ErrorCode = "DIRECTORY_PROTECTED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxNotebookSizeExceeded ErrorCode = "MAX_NOTEBOOK_SIZE_EXCEEDED" + ErrorCode_MaxChildNodeSizeExceeded ErrorCode = "MAX_CHILD_NODE_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SearchQueryTooLong ErrorCode = "SEARCH_QUERY_TOO_LONG" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SearchQueryTooShort ErrorCode = "SEARCH_QUERY_TOO_SHORT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ManagedResourceGroupDoesNotExist ErrorCode = "MANAGED_RESOURCE_GROUP_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_PermissionNotPropagated ErrorCode = "PERMISSION_NOT_PROPAGATED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DeploymentTimeout ErrorCode = "DEPLOYMENT_TIMEOUT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitConflict ErrorCode = "GIT_CONFLICT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitUnknownRef ErrorCode = "GIT_UNKNOWN_REF" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitSensitiveTokenDetected ErrorCode = "GIT_SENSITIVE_TOKEN_DETECTED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitUrlNotOnAllowList ErrorCode = "GIT_URL_NOT_ON_ALLOW_LIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitRemoteError ErrorCode = "GIT_REMOTE_ERROR" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProjectsOperationTimeout ErrorCode = "PROJECTS_OPERATION_TIMEOUT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_IpynbFileInRepo ErrorCode = "IPYNB_FILE_IN_REPO" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_InsecurePartnerResponse ErrorCode = "INSECURE_PARTNER_RESPONSE" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MalformedPartnerResponse ErrorCode = "MALFORMED_PARTNER_RESPONSE" + ErrorCode_MetastoreDoesNotExist ErrorCode = "METASTORE_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DacDoesNotExist ErrorCode = "DAC_DOES_NOT_EXIST" + ErrorCode_CatalogDoesNotExist ErrorCode = "CATALOG_DOES_NOT_EXIST" + ErrorCode_SchemaDoesNotExist ErrorCode = "SCHEMA_DOES_NOT_EXIST" + ErrorCode_TableDoesNotExist ErrorCode = "TABLE_DOES_NOT_EXIST" + ErrorCode_ShareDoesNotExist ErrorCode = "SHARE_DOES_NOT_EXIST" + ErrorCode_RecipientDoesNotExist ErrorCode = "RECIPIENT_DOES_NOT_EXIST" + ErrorCode_StorageCredentialDoesNotExist ErrorCode = "STORAGE_CREDENTIAL_DOES_NOT_EXIST" + ErrorCode_ExternalLocationDoesNotExist ErrorCode = "EXTERNAL_LOCATION_DOES_NOT_EXIST" + ErrorCode_PrincipalDoesNotExist ErrorCode = "PRINCIPAL_DOES_NOT_EXIST" + ErrorCode_ProviderDoesNotExist ErrorCode = "PROVIDER_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MetastoreAlreadyExists ErrorCode = "METASTORE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DacAlreadyExists ErrorCode = "DAC_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_CatalogAlreadyExists ErrorCode = "CATALOG_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SchemaAlreadyExists ErrorCode = "SCHEMA_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_TableAlreadyExists ErrorCode = "TABLE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ShareAlreadyExists ErrorCode = "SHARE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_RecipientAlreadyExists ErrorCode = "RECIPIENT_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_StorageCredentialAlreadyExists ErrorCode = "STORAGE_CREDENTIAL_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ExternalLocationAlreadyExists ErrorCode = "EXTERNAL_LOCATION_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProviderAlreadyExists ErrorCode = "PROVIDER_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_CatalogNotEmpty ErrorCode = "CATALOG_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SchemaNotEmpty ErrorCode = "SCHEMA_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MetastoreNotEmpty ErrorCode = "METASTORE_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProviderShareNotAccessible ErrorCode = "PROVIDER_SHARE_NOT_ACCESSIBLE" +) + +// Status of the environment materialization. +type WorkspaceBaseEnvironmentCache_Status string + +const ( + WorkspaceBaseEnvironmentCache_Status_Unspecified WorkspaceBaseEnvironmentCache_Status = "" + // Materialized environment creation is pending. + WorkspaceBaseEnvironmentCache_Status_Pending WorkspaceBaseEnvironmentCache_Status = "PENDING" + // Materialized environment has been successfully created. + WorkspaceBaseEnvironmentCache_Status_Created WorkspaceBaseEnvironmentCache_Status = "CREATED" + // Materialized environment creation failed. + WorkspaceBaseEnvironmentCache_Status_Failed WorkspaceBaseEnvironmentCache_Status = "FAILED" + // Materialized environment has expired. + WorkspaceBaseEnvironmentCache_Status_Expired WorkspaceBaseEnvironmentCache_Status = "EXPIRED" + // Materialized environment is invalid. + WorkspaceBaseEnvironmentCache_Status_Invalid WorkspaceBaseEnvironmentCache_Status = "INVALID" + // Materialized environment is being refreshed. + WorkspaceBaseEnvironmentCache_Status_Refreshing WorkspaceBaseEnvironmentCache_Status = "REFRESHING" +) + +// Databricks Error that is returned by all Databricks APIs.. +type ApiError struct { + ErrorCode ErrorCode + Message *string + StackTrace *string + Details []json.RawMessage +} + +// Request message for CreateWorkspaceBaseEnvironment.. +type CreateWorkspaceBaseEnvironmentRequest struct { + // Required. The workspace base environment to create. + WorkspaceBaseEnvironment *WorkspaceBaseEnvironment + // The ID to use for the workspace base environment, which will become the final + // component of the resource name. This value should be 4-63 characters, and + // valid characters are /[a-z][0-9]-/. + WorkspaceBaseEnvironmentId *string + // A unique identifier for this request. A random UUID is recommended. This + // request is only idempotent if a request_id is provided. + RequestId *string +} + +// A singleton resource representing the default workspace base environment +// configuration. This resource contains the workspace base environments that +// are used as defaults for serverless notebooks and jobs in the workspace, for +// both CPU and GPU compute types.. +type DefaultWorkspaceBaseEnvironment struct { + // The resource name of this singleton resource. Format: + // default-workspace-base-environment + Name *string `fieldmask:"name"` + // The default workspace base environment for CPU compute. Format: + // workspace-base-environments/{workspace_base_environment} + CpuWorkspaceBaseEnvironment *string `fieldmask:"cpu_workspace_base_environment"` + // The default workspace base environment for GPU compute. Format: + // workspace-base-environments/{workspace_base_environment} + GpuWorkspaceBaseEnvironment *string `fieldmask:"gpu_workspace_base_environment"` +} + +// Request message for DeleteWorkspaceBaseEnvironment.. +type DeleteWorkspaceBaseEnvironmentRequest struct { + // Required. The resource name of the workspace base environment to delete. + // Format: workspace-base-environments/{workspace_base_environment} + Name *string +} + +// Environment specification for a WorkspaceBaseEnvironment. Contains the +// environment version and dependencies configuration.. +type EnvironmentSpec struct { + // List of pip dependencies, as supported by the version of pip in this + // environment. Each dependency is a valid pip requirements file line per + // https://pip.pypa.io/en/stable/reference/requirements-file-format/. Allowed + // dependencies include a requirement specifier, an archive URL, a local project + // path (such as WSFS or UC Volumes in ), or a VCS project URL. + Dependencies []string + // Environment version used by the environment. Each version comes with a + // specific Python version and a set of Python packages. The version is a + // string, consisting of an integer. + EnvironmentVersion *string +} + +// Request message for GetDefaultWorkspaceBaseEnvironment.. +type GetDefaultWorkspaceBaseEnvironmentRequest struct { + // A static resource name of the default workspace base environment. Format: + // default-workspace-base-environment + Name *string +} + +// The request message for `GetOperation` method.. +type GetOperationRequest struct { + // The name of the operation resource. + Name *string +} + +// Request message for GetWorkspaceBaseEnvironment.. +type GetWorkspaceBaseEnvironmentRequest struct { + // Required. The resource name of the workspace base environment to retrieve. + // Format: workspace-base-environments/{workspace_base_environment} + Name *string +} + +// Request message for ListWorkspaceBaseEnvironments.. +type ListWorkspaceBaseEnvironmentsRequest struct { + // The maximum number of environments to return per page. Default is 1000. + PageSize *int + // Page token for pagination. Received from a previous + // ListWorkspaceBaseEnvironments call. + PageToken *string +} + +// Response message for ListWorkspaceBaseEnvironments.. +type ListWorkspaceBaseEnvironmentsResponse struct { + // The list of workspace base environments. + WorkspaceBaseEnvironments []WorkspaceBaseEnvironment + // Token to retrieve the next page of results. Empty if there are no more + // results. + NextPageToken *string +} + +// This resource represents a long-running operation that is the result of a +// network API call.. +type Operation struct { + // The server-assigned name, which is only unique within the same service that + // originally returns it. If you use the default HTTP mapping, the `name` should + // be a resource name ending with `operations/{unique_id}`. + Name *string + // Service-specific metadata associated with the operation. It typically + // contains progress information and common metadata such as create time. Some + // services might not provide such metadata. + Metadata json.RawMessage + // If the value is `false`, it means the operation is still in progress. If + // `true`, the operation is completed, and either `error` or `response` is + // available. + Done *bool + // The operation result, which can be either an `error` or a valid `response`. + // If `done` == `false`, neither `error` nor `response` is set. If `done` == + // `true`, exactly one of `error` or `response` can be set. Some services might + // not provide the result. + Result isOperation_Result +} + +type isOperation_Result interface { + isOperation_Result() +} + +// Operation_Result_Error selects Error for Operation.Result. +// The error result of the operation in case of failure or cancellation. +type Operation_Result_Error struct { + Error ApiError +} + +func (*Operation_Result_Error) isOperation_Result() {} + +// Operation_Result_Response selects Response for Operation.Result. +// The normal, successful response of the operation. +type Operation_Result_Response struct { + Response json.RawMessage +} + +func (*Operation_Result_Response) isOperation_Result() {} + +// Request message for RefreshWorkspaceBaseEnvironments.. +type RefreshWorkspaceBaseEnvironmentRequest struct { + // Required. The resource name of the workspace base environment to delete. + // Format: workspace-base-environments/{workspace_base_environment} + Name *string +} + +// Request message for UpdateDefaultWorkspaceBaseEnvironment.. +type UpdateDefaultWorkspaceBaseEnvironmentRequest struct { + // Required. The default workspace base environment configuration to update. + DefaultWorkspaceBaseEnvironment *DefaultWorkspaceBaseEnvironment + // Field mask specifying which fields to update. Use comma as the separator for + // multiple fields (no space). The special value '*' indicates that all fields + // should be updated (full replacement). Valid field paths: + // cpu_workspace_base_environment, gpu_workspace_base_environment + // + // To unset one or both defaults, include the field path(s) in the mask and omit + // them from the request body. To unset both, you must list both paths + // explicitly — the wildcard '*' cannot be used to unset fields. + UpdateMask *types.FieldMask[DefaultWorkspaceBaseEnvironment] +} + +// Request message for UpdateWorkspaceBaseEnvironment.. +type UpdateWorkspaceBaseEnvironmentRequest struct { + Name *string + // Required. The workspace base environment with updated fields. The name field + // is used to identify the environment to update. + WorkspaceBaseEnvironment *WorkspaceBaseEnvironment +} + +// A WorkspaceBaseEnvironment defines a workspace-level environment +// configuration consisting of an environment version and a list of +// dependencies.. +type WorkspaceBaseEnvironment struct { + // The resource name of the workspace base environment. Format: + // workspace-base-environments/{workspace-base-environment} + Name *string + // Human-readable display name for the workspace base environment. + DisplayName *string + // The WSFS or UC Volumes path to the environment YAML file. + Filepath *string + // User ID of the creator. + CreatorUserId *string + // Timestamp when the environment was created. + CreateTime *types.Time + // User ID of the last user who updated the environment. + LastUpdatedUserId *string + // Timestamp when the environment was last updated. + UpdateTime *types.Time + // The status of the materialized workspace base environment. + Status WorkspaceBaseEnvironmentCache_Status + // Status message providing additional details about the environment status. + Message *string + // Whether this is the default environment for the workspace. + IsDefault *bool + // The type of base environment (CPU or GPU). + BaseEnvironmentType BaseEnvironmentType + // The environment specification containing version and dependencies. + Spec *EnvironmentSpec +} + +// Materialized environment information for a WorkspaceBaseEnvironment.. +type WorkspaceBaseEnvironmentCache struct { +} + +// Metadata for the WorkspaceBaseEnvironment long-running operations. This +// message tracks the progress of the workspace base environment long-running +// process.. +type WorkspaceBaseEnvironmentOperationMetadata struct { +} + +// Error returns the LRO error code and message. +func (e *ApiError) Error() string { + message := "unknown error" + if e.Message != nil && *e.Message != "" { + message = *e.Message + } + if e.ErrorCode != "" { + return fmt.Sprintf("[%v] %s", e.ErrorCode, message) + } + return message +} diff --git a/environments/v1/wire.go b/environments/v1/wire.go new file mode 100755 index 0000000..00ad500 --- /dev/null +++ b/environments/v1/wire.go @@ -0,0 +1,325 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package environments + +import ( + "encoding/json" + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type apiErrorWire struct { + ErrorCode ErrorCode `json:"error_code,omitempty"` + Message *string `json:"message,omitempty"` + StackTrace *string `json:"stack_trace,omitempty"` + Details []json.RawMessage `json:"details,omitempty"` +} + +func apiErrorFromWire(w *apiErrorWire) (*ApiError, error) { + if w == nil { + return nil, nil + } + return &ApiError{ + ErrorCode: w.ErrorCode, + Message: w.Message, + StackTrace: w.StackTrace, + Details: w.Details, + }, nil +} + +type createWorkspaceBaseEnvironmentRequestWire struct { + WorkspaceBaseEnvironment *workspaceBaseEnvironmentWire `json:"workspace_base_environment,omitempty"` + WorkspaceBaseEnvironmentId *string `json:"workspace_base_environment_id,omitempty"` + RequestId *string `json:"request_id,omitempty"` +} + +func createWorkspaceBaseEnvironmentRequestToWire(v *CreateWorkspaceBaseEnvironmentRequest) (*createWorkspaceBaseEnvironmentRequestWire, error) { + if v == nil { + return nil, nil + } + workspaceBaseEnvironmentWireValue, err := workspaceBaseEnvironmentToWire(v.WorkspaceBaseEnvironment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateWorkspaceBaseEnvironmentRequest.WorkspaceBaseEnvironment", err) + } + return &createWorkspaceBaseEnvironmentRequestWire{ + WorkspaceBaseEnvironment: workspaceBaseEnvironmentWireValue, + WorkspaceBaseEnvironmentId: v.WorkspaceBaseEnvironmentId, + RequestId: v.RequestId, + }, nil +} + +type defaultWorkspaceBaseEnvironmentWire struct { + Name *string `json:"name,omitempty"` + CpuWorkspaceBaseEnvironment *string `json:"cpu_workspace_base_environment,omitempty"` + GpuWorkspaceBaseEnvironment *string `json:"gpu_workspace_base_environment,omitempty"` +} + +func defaultWorkspaceBaseEnvironmentToWire(v *DefaultWorkspaceBaseEnvironment) (*defaultWorkspaceBaseEnvironmentWire, error) { + if v == nil { + return nil, nil + } + return &defaultWorkspaceBaseEnvironmentWire{ + Name: v.Name, + CpuWorkspaceBaseEnvironment: v.CpuWorkspaceBaseEnvironment, + GpuWorkspaceBaseEnvironment: v.GpuWorkspaceBaseEnvironment, + }, nil +} + +func defaultWorkspaceBaseEnvironmentFromWire(w *defaultWorkspaceBaseEnvironmentWire) (*DefaultWorkspaceBaseEnvironment, error) { + if w == nil { + return nil, nil + } + return &DefaultWorkspaceBaseEnvironment{ + Name: w.Name, + CpuWorkspaceBaseEnvironment: w.CpuWorkspaceBaseEnvironment, + GpuWorkspaceBaseEnvironment: w.GpuWorkspaceBaseEnvironment, + }, nil +} + +type environmentSpecWire struct { + Dependencies []string `json:"dependencies,omitempty"` + EnvironmentVersion *string `json:"environment_version,omitempty"` +} + +func environmentSpecToWire(v *EnvironmentSpec) (*environmentSpecWire, error) { + if v == nil { + return nil, nil + } + return &environmentSpecWire{ + Dependencies: v.Dependencies, + EnvironmentVersion: v.EnvironmentVersion, + }, nil +} + +func environmentSpecFromWire(w *environmentSpecWire) (*EnvironmentSpec, error) { + if w == nil { + return nil, nil + } + return &EnvironmentSpec{ + Dependencies: w.Dependencies, + EnvironmentVersion: w.EnvironmentVersion, + }, nil +} + +type listWorkspaceBaseEnvironmentsRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listWorkspaceBaseEnvironmentsRequestToWire(v *ListWorkspaceBaseEnvironmentsRequest) (*listWorkspaceBaseEnvironmentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listWorkspaceBaseEnvironmentsRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listWorkspaceBaseEnvironmentsResponseWire struct { + WorkspaceBaseEnvironments []workspaceBaseEnvironmentWire `json:"workspace_base_environments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listWorkspaceBaseEnvironmentsResponseFromWire(w *listWorkspaceBaseEnvironmentsResponseWire) (*ListWorkspaceBaseEnvironmentsResponse, error) { + if w == nil { + return nil, nil + } + workspaceBaseEnvironmentsPublicValue, err := convertSlice(w.WorkspaceBaseEnvironments, workspaceBaseEnvironmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListWorkspaceBaseEnvironmentsResponse.WorkspaceBaseEnvironments", err) + } + return &ListWorkspaceBaseEnvironmentsResponse{ + WorkspaceBaseEnvironments: workspaceBaseEnvironmentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type operationWire struct { + Name *string `json:"name,omitempty"` + Metadata json.RawMessage `json:"metadata,omitempty"` + Done *bool `json:"done,omitempty"` + Error *apiErrorWire `json:"error,omitempty"` + Response json.RawMessage `json:"response,omitempty"` +} + +func operationFromWire(w *operationWire) (*Operation, error) { + if w == nil { + return nil, nil + } + resultMembers := 0 + if w.Error != nil { + resultMembers++ + } + if w.Response != nil { + resultMembers++ + } + if resultMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Operation.Result") + } + var resultSelection isOperation_Result + switch { + case w.Error != nil: + resultErrorConverted, err := apiErrorFromWire(w.Error) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Operation.Result.Error", err) + } + resultSelection = &Operation_Result_Error{Error: *resultErrorConverted} + case w.Response != nil: + resultSelection = &Operation_Result_Response{Response: w.Response} + } + return &Operation{ + Name: w.Name, + Metadata: w.Metadata, + Done: w.Done, + Result: resultSelection, + }, nil +} + +type refreshWorkspaceBaseEnvironmentRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func refreshWorkspaceBaseEnvironmentRequestToWire(v *RefreshWorkspaceBaseEnvironmentRequest) (*refreshWorkspaceBaseEnvironmentRequestWire, error) { + if v == nil { + return nil, nil + } + return &refreshWorkspaceBaseEnvironmentRequestWire{ + Name: v.Name, + }, nil +} + +type updateDefaultWorkspaceBaseEnvironmentRequestWire struct { + DefaultWorkspaceBaseEnvironment *defaultWorkspaceBaseEnvironmentWire `json:"default_workspace_base_environment,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateDefaultWorkspaceBaseEnvironmentRequestToWire(v *UpdateDefaultWorkspaceBaseEnvironmentRequest) (*updateDefaultWorkspaceBaseEnvironmentRequestWire, error) { + if v == nil { + return nil, nil + } + defaultWorkspaceBaseEnvironmentWireValue, err := defaultWorkspaceBaseEnvironmentToWire(v.DefaultWorkspaceBaseEnvironment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateDefaultWorkspaceBaseEnvironmentRequest.DefaultWorkspaceBaseEnvironment", err) + } + return &updateDefaultWorkspaceBaseEnvironmentRequestWire{ + DefaultWorkspaceBaseEnvironment: defaultWorkspaceBaseEnvironmentWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateWorkspaceBaseEnvironmentRequestWire struct { + Name *string `json:"name,omitempty"` + WorkspaceBaseEnvironment *workspaceBaseEnvironmentWire `json:"workspace_base_environment,omitempty"` +} + +func updateWorkspaceBaseEnvironmentRequestToWire(v *UpdateWorkspaceBaseEnvironmentRequest) (*updateWorkspaceBaseEnvironmentRequestWire, error) { + if v == nil { + return nil, nil + } + workspaceBaseEnvironmentWireValue, err := workspaceBaseEnvironmentToWire(v.WorkspaceBaseEnvironment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateWorkspaceBaseEnvironmentRequest.WorkspaceBaseEnvironment", err) + } + return &updateWorkspaceBaseEnvironmentRequestWire{ + Name: v.Name, + WorkspaceBaseEnvironment: workspaceBaseEnvironmentWireValue, + }, nil +} + +type workspaceBaseEnvironmentWire struct { + Name *string `json:"name,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Filepath *string `json:"filepath,omitempty"` + CreatorUserId *string `json:"creator_user_id,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + LastUpdatedUserId *string `json:"last_updated_user_id,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Status WorkspaceBaseEnvironmentCache_Status `json:"status,omitempty"` + Message *string `json:"message,omitempty"` + IsDefault *bool `json:"is_default,omitempty"` + BaseEnvironmentType BaseEnvironmentType `json:"base_environment_type,omitempty"` + Spec *environmentSpecWire `json:"spec,omitempty"` +} + +func workspaceBaseEnvironmentToWire(v *WorkspaceBaseEnvironment) (*workspaceBaseEnvironmentWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := environmentSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkspaceBaseEnvironment.Spec", err) + } + return &workspaceBaseEnvironmentWire{ + Name: v.Name, + DisplayName: v.DisplayName, + Filepath: v.Filepath, + CreatorUserId: v.CreatorUserId, + CreateTime: v.CreateTime, + LastUpdatedUserId: v.LastUpdatedUserId, + UpdateTime: v.UpdateTime, + Status: v.Status, + Message: v.Message, + IsDefault: v.IsDefault, + BaseEnvironmentType: v.BaseEnvironmentType, + Spec: specWireValue, + }, nil +} + +func workspaceBaseEnvironmentFromWire(w *workspaceBaseEnvironmentWire) (*WorkspaceBaseEnvironment, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := environmentSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkspaceBaseEnvironment.Spec", err) + } + return &WorkspaceBaseEnvironment{ + Name: w.Name, + DisplayName: w.DisplayName, + Filepath: w.Filepath, + CreatorUserId: w.CreatorUserId, + CreateTime: w.CreateTime, + LastUpdatedUserId: w.LastUpdatedUserId, + UpdateTime: w.UpdateTime, + Status: w.Status, + Message: w.Message, + IsDefault: w.IsDefault, + BaseEnvironmentType: w.BaseEnvironmentType, + Spec: specPublicValue, + }, nil +} + +type workspaceBaseEnvironmentOperationMetadataWire struct { +} + +func workspaceBaseEnvironmentOperationMetadataFromWire(w *workspaceBaseEnvironmentOperationMetadataWire) (*WorkspaceBaseEnvironmentOperationMetadata, error) { + if w == nil { + return nil, nil + } + return &WorkspaceBaseEnvironmentOperationMetadata{}, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/experiments/.package.json b/experiments/.package.json new file mode 100644 index 0000000..073870c --- /dev/null +++ b/experiments/.package.json @@ -0,0 +1,3 @@ +{ + "package": "experiments" +} diff --git a/experiments/CHANGELOG.md b/experiments/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/experiments/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/experiments/README.md b/experiments/README.md new file mode 100644 index 0000000..fce2220 --- /dev/null +++ b/experiments/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/experiments + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/experiments@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/experiments/v1" + +client, err := experiments.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/experiments/go.mod b/experiments/go.mod new file mode 100644 index 0000000..ee27878 --- /dev/null +++ b/experiments/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/experiments + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/experiments/internal/version.go b/experiments/internal/version.go new file mode 100644 index 0000000..8c126ea --- /dev/null +++ b/experiments/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-experiments" + +const Version = "0.0.1-dev.1" diff --git a/experiments/v1/client.go b/experiments/v1/client.go new file mode 100755 index 0000000..05cadf9 --- /dev/null +++ b/experiments/v1/client.go @@ -0,0 +1,2614 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package experiments + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/experiments/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates an experiment with a name. Returns the ID of the newly created +// experiment. Validates that another experiment with the same name does not +// already exist and fails if another experiment with the same name already +// exists. +// +// Throws `RESOURCE_ALREADY_EXISTS` if an experiment with the given name exists. +// Note: In some contexts, this error may be remapped to `ALREADY_EXISTS`. To be +// safe, clients should check for both error codes. +func (c *internalClient) CreateExperiment(ctx context.Context, req *CreateExperimentRequest, opts ...call.Option) (*CreateExperimentResponse, error) { + wireReq, err := createExperimentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/experiments/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateExperimentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createExperimentResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createExperimentResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a logged model. +func (c *internalClient) CreateLoggedModel(ctx context.Context, req *CreateLoggedModelRequest, opts ...call.Option) (*CreateLoggedModelResponse, error) { + wireReq, err := createLoggedModelRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/logged-models" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateLoggedModelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createLoggedModelResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createLoggedModelResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new run within an experiment. A run is usually a single execution +// of a machine learning or data ETL pipeline. MLflow uses runs to track the +// `mlflowParam`, `mlflowMetric`, and `mlflowRunTag` associated with a single +// execution. +func (c *internalClient) CreateRun(ctx context.Context, req *CreateRunRequest, opts ...call.Option) (*CreateRunResponse, error) { + wireReq, err := createRunRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createRunResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createRunResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Marks an experiment and associated metadata, runs, metrics, params, and tags +// for deletion. If the experiment uses FileStore, artifacts associated with the +// experiment are also deleted. +func (c *internalClient) DeleteExperiment(ctx context.Context, req *DeleteExperimentRequest, opts ...call.Option) (*DeleteExperimentResponse, error) { + wireReq, err := deleteExperimentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/experiments/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteExperimentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteExperimentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a logged model. +func (c *internalClient) DeleteLoggedModel(ctx context.Context, req *DeleteLoggedModelRequest, opts ...call.Option) (*DeleteLoggedModelResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/mlflow/logged-models/") + pb.singleSegment(*req.ModelId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteLoggedModelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteLoggedModelResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a tag on a logged model. +func (c *internalClient) DeleteLoggedModelTag(ctx context.Context, req *DeleteLoggedModelTagRequest, opts ...call.Option) (*DeleteLoggedModelTagResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/mlflow/logged-models/") + pb.singleSegment(*req.ModelId) + pb.literal("/tags/") + pb.singleSegment(*req.TagKey) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteLoggedModelTagResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteLoggedModelTagResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Marks a run for deletion. +func (c *internalClient) DeleteRun(ctx context.Context, req *DeleteRunRequest, opts ...call.Option) (*DeleteRunResponse, error) { + wireReq, err := deleteRunRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteRunResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Bulk delete runs in an experiment that were created prior to or at the +// specified timestamp. Deletes at most max_runs per request. To call this API +// from a Databricks Notebook in Python, you can use the client code snippet on +func (c *internalClient) DeleteRuns(ctx context.Context, req *DeleteRunsRequest, opts ...call.Option) (*DeleteRunsResponse, error) { + wireReq, err := deleteRunsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/databricks/runs/delete-runs" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteRunsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp deleteRunsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = deleteRunsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a tag on a run. Tags are run metadata that can be updated during a +// run and after a run completes. +func (c *internalClient) DeleteTag(ctx context.Context, req *DeleteTagRequest, opts ...call.Option) (*DeleteTagResponse, error) { + wireReq, err := deleteTagRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/delete-tag" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteTagResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteTagResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Finalize a logged model. +func (c *internalClient) FinalizeLoggedModel(ctx context.Context, req *FinalizeLoggedModelRequest, opts ...call.Option) (*FinalizeLoggedModelResponse, error) { + wireReq, err := finalizeLoggedModelRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/mlflow/logged-models/") + pb.singleSegment(*req.ModelId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FinalizeLoggedModelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp finalizeLoggedModelResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = finalizeLoggedModelResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets metadata for an experiment. This method works on deleted experiments. +func (c *internalClient) GetExperiment(ctx context.Context, req *GetExperimentRequest, opts ...call.Option) (*GetExperimentResponse, error) { + wireReq, err := getExperimentRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/experiments/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "experiment_id", wireReq.ExperimentId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetExperimentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getExperimentResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getExperimentResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets metadata for an experiment. +// +// This endpoint will return deleted experiments, but prefers the active +// experiment if an active and deleted experiment share the same name. If +// multiple deleted experiments share the same name, the API will return one of +// them. +// +// Throws `RESOURCE_DOES_NOT_EXIST` if no experiment with the specified name +// exists. +func (c *internalClient) GetExperimentByName(ctx context.Context, req *GetExperimentByNameRequest, opts ...call.Option) (*GetExperimentByNameResponse, error) { + wireReq, err := getExperimentByNameRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/experiments/get-by-name" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "experiment_name", wireReq.ExperimentName); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetExperimentByNameResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getExperimentByNameResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getExperimentByNameResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a logged model. +func (c *internalClient) GetLoggedModel(ctx context.Context, req *GetLoggedModelRequest, opts ...call.Option) (*GetLoggedModelResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/mlflow/logged-models/") + pb.singleSegment(*req.ModelId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetLoggedModelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getLoggedModelResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getLoggedModelResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the metadata, metrics, params, and tags for a run. In the case where +// multiple metrics with the same key are logged for a run, return only the +// value with the latest timestamp. +// +// If there are multiple values with the latest timestamp, return the maximum of +// these values. +func (c *internalClient) GetRun(ctx context.Context, req *GetRunRequest, opts ...call.Option) (*GetRunResponse, error) { + wireReq, err := getRunRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "run_id", wireReq.RunId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "run_uuid", wireReq.RunUuid); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getRunResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getRunResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List artifacts for a run. Takes an optional `artifact_path` prefix which if +// specified, the response contains only artifacts with the specified prefix. A +// maximum of 1000 artifacts will be retrieved for UC Volumes. Please call +// `/api/2.0/fs/directories{directory_path}` for listing artifacts in UC +// Volumes, which supports pagination. See [List directory contents | Files +// API](/api/workspace/files/listdirectorycontents). +func (c *internalClient) ListArtifacts(ctx context.Context, req *ListArtifactsRequest, opts ...call.Option) (*ListArtifactsResponse, error) { + wireReq, err := listArtifactsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/artifacts/list" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "run_id", wireReq.RunId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "run_uuid", wireReq.RunUuid); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "path", wireReq.Path); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListArtifactsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listArtifactsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listArtifactsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListArtifactsIter returns an iterator that iterates +// over the results of ListArtifacts. +// +// For example: +// +// for item, err := range c.ListArtifactsIter(ctx, &ListArtifactsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListArtifacts call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListArtifacts directly. +func (c *internalClient) ListArtifactsIter(ctx context.Context, req *ListArtifactsRequest, opts ...call.Option) iter.Seq2[*FileInfo, error] { + return func(yield func(*FileInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListArtifactsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListArtifacts(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Files { + if !yield(&resp.Files[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Gets a list of all experiments. +func (c *internalClient) ListExperiments(ctx context.Context, req *ListExperimentsRequest, opts ...call.Option) (*ListExperimentsResponse, error) { + wireReq, err := listExperimentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/experiments/list" + queryParams := url.Values{} + if wireReq.ViewType != "" { + if err := addQueryValue(queryParams, "view_type", wireReq.ViewType); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListExperimentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listExperimentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listExperimentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListExperimentsIter returns an iterator that iterates +// over the results of ListExperiments. +// +// For example: +// +// for item, err := range c.ListExperimentsIter(ctx, &ListExperimentsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListExperiments call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListExperiments directly. +func (c *internalClient) ListExperimentsIter(ctx context.Context, req *ListExperimentsRequest, opts ...call.Option) iter.Seq2[*Experiment, error] { + return func(yield func(*Experiment, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListExperimentsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListExperiments(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Experiments { + if !yield(&resp.Experiments[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Gets a list of all values for the specified metric for a given run. +func (c *internalClient) ListMetricHistory(ctx context.Context, req *ListMetricHistoryRequest, opts ...call.Option) (*GetMetricHistoryResponse, error) { + wireReq, err := listMetricHistoryRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/metrics/get-history" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "run_id", wireReq.RunId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "run_uuid", wireReq.RunUuid); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "metric_key", wireReq.MetricKey); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetMetricHistoryResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getMetricHistoryResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getMetricHistoryResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListMetricHistoryIter returns an iterator that iterates +// over the results of ListMetricHistory. +// +// For example: +// +// for item, err := range c.ListMetricHistoryIter(ctx, &ListMetricHistoryRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListMetricHistory call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListMetricHistory directly. +func (c *internalClient) ListMetricHistoryIter(ctx context.Context, req *ListMetricHistoryRequest, opts ...call.Option) iter.Seq2[*Metric, error] { + return func(yield func(*Metric, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListMetricHistoryRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListMetricHistory(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Metrics { + if !yield(&resp.Metrics[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Logs a batch of metrics, params, and tags for a run. If any data failed to be +// persisted, the server will respond with an error (non-200 status code). +// +// In case of error (due to internal server error or an invalid request), +// partial data may be written. +// +// You can write metrics, params, and tags in interleaving fashion, but within a +// given entity type are guaranteed to follow the order specified in the request +// body. +// +// The overwrite behavior for metrics, params, and tags is as follows: +// +// * Metrics: metric values are never overwritten. Logging a metric (key, value, +// timestamp) appends to the set of values for the metric with the provided key. +// +// * Tags: tag values can be overwritten by successive writes to the same tag +// key. That is, if multiple tag values with the same key are provided in the +// same API request, the last-provided tag value is written. Logging the same +// tag (key, value) is permitted. Specifically, logging a tag is idempotent. +// +// * Parameters: once written, param values cannot be changed (attempting to +// overwrite a param value will result in an error). However, logging the same +// param (key, value) is permitted. Specifically, logging a param is idempotent. +// +// Request Limits ------------------------------- A single JSON-serialized API +// request may be up to 1 MB in size and contain: +// +// * No more than 1000 metrics, params, and tags in total +// +// * Up to 1000 metrics +// +// * Up to 100 params +// +// * Up to 100 tags +// +// For example, a valid request might contain 900 metrics, 50 params, and 50 +// tags, but logging 900 metrics, 50 params, and 51 tags is invalid. +// +// The following limits also apply to metric, param, and tag keys and values: +// +// * Metric keys, param keys, and tag keys can be up to 250 characters in length +// +// * Parameter and tag values can be up to 250 characters in length +func (c *internalClient) LogBatch(ctx context.Context, req *LogBatchRequest, opts ...call.Option) (*LogBatchResponse, error) { + wireReq, err := logBatchRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/log-batch" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *LogBatchResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &LogBatchResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Logs inputs, such as datasets and models, to an MLflow Run. +func (c *internalClient) LogInputs(ctx context.Context, req *LogInputsRequest, opts ...call.Option) (*LogInputsResponse, error) { + wireReq, err := logInputsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/log-inputs" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *LogInputsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &LogInputsResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Logs params for a logged model. A param is a key-value pair (string key, +// string value). Examples include hyperparameters used for ML model training. A +// param can be logged only once for a logged model, and attempting to overwrite +// an existing param with a different value will result in an error +func (c *internalClient) LogLoggedModelParams(ctx context.Context, req *LogLoggedModelParamsRequest, opts ...call.Option) (*LogLoggedModelParamsResponse, error) { + wireReq, err := logLoggedModelParamsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/mlflow/logged-models/") + pb.singleSegment(*req.ModelId) + pb.literal("/params") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *LogLoggedModelParamsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &LogLoggedModelParamsResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Log a metric for a run. A metric is a key-value pair (string key, float +// value) with an associated timestamp. Examples include the various metrics +// that represent ML model accuracy. A metric can be logged multiple times. +func (c *internalClient) LogMetric(ctx context.Context, req *LogMetricRequest, opts ...call.Option) (*LogMetricResponse, error) { + wireReq, err := logMetricRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/log-metric" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *LogMetricResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &LogMetricResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// **Note:** the [Create a logged +// model](/api/workspace/experiments/createloggedmodel) API replaces this +// endpoint. +// +// Log a model to an MLflow Run. +func (c *internalClient) LogModel(ctx context.Context, req *LogModelRequest, opts ...call.Option) (*LogModelResponse, error) { + wireReq, err := logModelRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/log-model" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *LogModelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &LogModelResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Logs outputs, such as models, from an MLflow Run. +func (c *internalClient) LogOutputs(ctx context.Context, req *LogOutputsRequest, opts ...call.Option) (*LogOutputsResponse, error) { + wireReq, err := logOutputsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/outputs" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *LogOutputsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &LogOutputsResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Logs a param used for a run. A param is a key-value pair (string key, string +// value). Examples include hyperparameters used for ML model training and +// constant dates and values used in an ETL pipeline. A param can be logged only +// once for a run. +func (c *internalClient) LogParam(ctx context.Context, req *LogParamRequest, opts ...call.Option) (*LogParamResponse, error) { + wireReq, err := logParamRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/log-parameter" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *LogParamResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &LogParamResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Restore an experiment marked for deletion. This also restores associated +// metadata, runs, metrics, params, and tags. If experiment uses FileStore, +// underlying artifacts associated with experiment are also restored. +// +// Throws `RESOURCE_DOES_NOT_EXIST` if experiment was never created or was +// permanently deleted. +func (c *internalClient) RestoreExperiment(ctx context.Context, req *RestoreExperimentRequest, opts ...call.Option) (*RestoreExperimentResponse, error) { + wireReq, err := restoreExperimentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/experiments/restore" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RestoreExperimentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &RestoreExperimentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Restores a deleted run. This also restores associated metadata, runs, +// metrics, params, and tags. +// +// Throws `RESOURCE_DOES_NOT_EXIST` if the run was never created or was +// permanently deleted. +func (c *internalClient) RestoreRun(ctx context.Context, req *RestoreRunRequest, opts ...call.Option) (*RestoreRunResponse, error) { + wireReq, err := restoreRunRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/restore" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RestoreRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &RestoreRunResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Bulk restore runs in an experiment that were deleted no earlier than the +// specified timestamp. Restores at most max_runs per request. To call this API +// from a Databricks Notebook in Python, you can use the client code snippet on +func (c *internalClient) RestoreRuns(ctx context.Context, req *RestoreRunsRequest, opts ...call.Option) (*RestoreRunsResponse, error) { + wireReq, err := restoreRunsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/databricks/runs/restore-runs" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RestoreRunsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp restoreRunsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = restoreRunsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Searches for experiments that satisfy specified search criteria. +func (c *internalClient) SearchExperiments(ctx context.Context, req *SearchExperimentsRequest, opts ...call.Option) (*SearchExperimentsResponse, error) { + wireReq, err := searchExperimentsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/experiments/search" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SearchExperimentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp searchExperimentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = searchExperimentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// SearchExperimentsIter returns an iterator that iterates +// over the results of SearchExperiments. +// +// For example: +// +// for item, err := range c.SearchExperimentsIter(ctx, &SearchExperimentsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each SearchExperiments call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// SearchExperiments directly. +func (c *internalClient) SearchExperimentsIter(ctx context.Context, req *SearchExperimentsRequest, opts ...call.Option) iter.Seq2[*Experiment, error] { + return func(yield func(*Experiment, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := SearchExperimentsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.SearchExperiments(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Experiments { + if !yield(&resp.Experiments[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Search for Logged Models that satisfy specified search criteria. +func (c *internalClient) SearchLoggedModels(ctx context.Context, req *SearchLoggedModelsRequest, opts ...call.Option) (*SearchLoggedModelsResponse, error) { + wireReq, err := searchLoggedModelsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/logged-models/search" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SearchLoggedModelsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp searchLoggedModelsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = searchLoggedModelsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Searches for runs that satisfy expressions. +// +// Search expressions can use `mlflowMetric` and `mlflowParam` keys. +func (c *internalClient) SearchRuns(ctx context.Context, req *SearchRunsRequest, opts ...call.Option) (*SearchRunsResponse, error) { + wireReq, err := searchRunsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/search" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SearchRunsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp searchRunsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = searchRunsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// SearchRunsIter returns an iterator that iterates +// over the results of SearchRuns. +// +// For example: +// +// for item, err := range c.SearchRunsIter(ctx, &SearchRunsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each SearchRuns call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// SearchRuns directly. +func (c *internalClient) SearchRunsIter(ctx context.Context, req *SearchRunsRequest, opts ...call.Option) iter.Seq2[*Run, error] { + return func(yield func(*Run, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := SearchRunsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.SearchRuns(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Runs { + if !yield(&resp.Runs[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Sets a tag on an experiment. Experiment tags are metadata that can be +// updated. +func (c *internalClient) SetExperimentTag(ctx context.Context, req *SetExperimentTagRequest, opts ...call.Option) (*SetExperimentTagResponse, error) { + wireReq, err := setExperimentTagRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/experiments/set-experiment-tag" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SetExperimentTagResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &SetExperimentTagResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Set tags for a logged model. +func (c *internalClient) SetLoggedModelTags(ctx context.Context, req *SetLoggedModelTagsRequest, opts ...call.Option) (*SetLoggedModelTagsResponse, error) { + wireReq, err := setLoggedModelTagsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/mlflow/logged-models/") + pb.singleSegment(*req.ModelId) + pb.literal("/tags") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SetLoggedModelTagsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &SetLoggedModelTagsResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Sets a tag on a run. Tags are run metadata that can be updated during a run +// and after a run completes. +func (c *internalClient) SetTag(ctx context.Context, req *SetTagRequest, opts ...call.Option) (*SetTagResponse, error) { + wireReq, err := setTagRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/set-tag" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SetTagResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &SetTagResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates experiment metadata. +func (c *internalClient) UpdateExperiment(ctx context.Context, req *UpdateExperimentRequest, opts ...call.Option) (*UpdateExperimentResponse, error) { + wireReq, err := updateExperimentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/experiments/update" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateExperimentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateExperimentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates run metadata. +func (c *internalClient) UpdateRun(ctx context.Context, req *UpdateRunRequest, opts ...call.Option) (*UpdateRunResponse, error) { + wireReq, err := updateRunRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/runs/update" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateRunResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateRunResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/experiments/v1/genhelper.go b/experiments/v1/genhelper.go new file mode 100755 index 0000000..91058f6 --- /dev/null +++ b/experiments/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package experiments + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/experiments/v1/model.go b/experiments/v1/model.go new file mode 100755 index 0000000..195fd66 --- /dev/null +++ b/experiments/v1/model.go @@ -0,0 +1,927 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package experiments + +// A LoggedModelStatus enum value represents the status of a logged model. +type LoggedModelStatus string + +const ( + LoggedModelStatus_Unspecified LoggedModelStatus = "" + // The LoggedModel has been created, but the LoggedModel files are not + // completely uploaded. + LoggedModelStatus_LoggedModelPending LoggedModelStatus = "LOGGED_MODEL_PENDING" + // The LoggedModel is created, and the LoggedModel files are completely + // uploaded. + LoggedModelStatus_LoggedModelReady LoggedModelStatus = "LOGGED_MODEL_READY" + // The LoggedModel is created, but an error occurred when uploading the + // LoggedModel files such as model weights / agent code. + LoggedModelStatus_LoggedModelUploadFailed LoggedModelStatus = "LOGGED_MODEL_UPLOAD_FAILED" +) + +// Status of a run. +type RunStatus string + +const ( + RunStatus_Unspecified RunStatus = "" + // Run has been initiated. + RunStatus_Running RunStatus = "RUNNING" + // Run is scheduled to run at a later time. + RunStatus_Scheduled RunStatus = "SCHEDULED" + // Run has completed. + RunStatus_Finished RunStatus = "FINISHED" + // Run execution failed. + RunStatus_Failed RunStatus = "FAILED" + // Run killed by user. + RunStatus_Killed RunStatus = "KILLED" +) + +// Qualifier for the view type. +type ViewType string + +const ( + ViewType_Unspecified ViewType = "" + // Default. Return only active. + ViewType_ActiveOnly ViewType = "ACTIVE_ONLY" + // Return only deleted. + ViewType_DeletedOnly ViewType = "DELETED_ONLY" + // Get all. + ViewType_All ViewType = "ALL" +) + +type CreateExperimentRequest struct { + // Experiment name. + Name *string + // Location where all artifacts for the experiment are stored. If not provided, + // the remote server will select an appropriate default. + ArtifactLocation *string + // A collection of tags to set on the experiment. Maximum tag size and number of + // tags per request depends on the storage backend. All storage backends are + // guaranteed to support tag keys up to 250 bytes in size and tag values up to + // 5000 bytes in size. All storage backends are also guaranteed to support up to + // 20 tags per request. + Tags []ExperimentTag + // The location where the experiment's traces are stored. When set, the + // underlying storage is provisioned and the experiment's traces are routed to + // it. When unset, traces are stored in the default MLflow backend. This field + // cannot be updated after the experiment is created. + TraceLocation *ExperimentTraceLocation +} + +type CreateExperimentResponse struct { + // Unique identifier for the experiment. + ExperimentId *string +} + +type CreateLoggedModelRequest struct { + // The ID of the experiment that owns the model. + ExperimentId *string + // The name of the model (optional). If not specified one will be generated. + Name *string + // The type of the model, such as ``"Agent"``, ``"Classifier"``, ``"LLM"``. + ModelType *string + // The ID of the run that created the model. + SourceRunId *string + // Parameters attached to the model. + Params []LoggedModelParameter + // Tags attached to the model. + Tags []LoggedModelTag +} + +type CreateLoggedModelResponse struct { + // The newly created logged model. + Model *LoggedModel +} + +type CreateRunRequest struct { + // ID of the associated experiment. + ExperimentId *string + // ID of the user executing the run. This field is deprecated as of MLflow 1.0, + // and will be removed in a future MLflow release. Use 'mlflow.user' tag + // instead. + UserId *string + // The name of the run. + RunName *string + // Unix timestamp in milliseconds of when the run started. + StartTime *int64 + // Additional metadata for run. + Tags []RunTag +} + +type CreateRunResponse struct { + // The newly created run. + Run *Run +} + +// Dataset. Represents a reference to data used for training, testing, or +// evaluation during the model development process.. +type Dataset struct { + // The name of the dataset. E.g. “my.uc.table@2” “nyc-taxi-dataset”, + // “fantastic-elk-3” + Name *string + // Dataset digest, e.g. an md5 hash of the dataset that uniquely identifies it + // within datasets of the same name. + Digest *string + // The type of the dataset source, e.g. ‘databricks-uc-table’, ‘DBFS’, + // ‘S3’, ... + SourceType *string + // Source information for the dataset. Note that the source may not exactly + // reproduce the dataset if it was transformed / modified before use with + // MLflow. + Source *string + // The schema of the dataset. E.g., MLflow ColSpec JSON for a dataframe, MLflow + // TensorSpec JSON for an ndarray, or another schema format. + Schema *string + // The profile of the dataset. Summary statistics for the dataset, such as the + // number of rows in a table, the mean / std / mode of each column in a table, + // or the number of elements in an array. + Profile *string +} + +// DatasetInput. Represents a dataset and input tags.. +type DatasetInput struct { + // A list of tags for the dataset input, e.g. a “context” tag with value + // “training” + Tags []InputTag + // The dataset being used as a Run input. + Dataset *Dataset +} + +type DeleteExperimentRequest struct { + // ID of the associated experiment. + ExperimentId *string +} + +type DeleteExperimentResponse struct { +} + +type DeleteLoggedModelRequest struct { + // The ID of the logged model to delete. + ModelId *string +} + +type DeleteLoggedModelResponse struct { +} + +type DeleteLoggedModelTagRequest struct { + // The ID of the logged model to delete the tag from. + ModelId *string + // The tag key. + TagKey *string +} + +type DeleteLoggedModelTagResponse struct { +} + +type DeleteRunRequest struct { + // ID of the run to delete. + RunId *string +} + +type DeleteRunResponse struct { +} + +type DeleteRunsRequest struct { + // The ID of the experiment containing the runs to delete. + ExperimentId *string + // The maximum creation timestamp in milliseconds since the UNIX epoch for + // deleting runs. Only runs created prior to or at this timestamp are deleted. + MaxTimestampMillis *int64 + // An optional positive integer indicating the maximum number of runs to delete. + // The maximum allowed value for max_runs is 10000. + MaxRuns *int +} + +type DeleteRunsResponse struct { + // The number of runs deleted. + RunsDeleted *int +} + +type DeleteTagRequest struct { + // ID of the run that the tag was logged under. Must be provided. + RunId *string + // Name of the tag. Maximum size is 255 bytes. Must be provided. + Key *string +} + +type DeleteTagResponse struct { +} + +// An experiment and its metadata.. +type Experiment struct { + // Unique identifier for the experiment. + ExperimentId *string + // Human readable name that identifies the experiment. + Name *string + // Location where artifacts for the experiment are stored. + ArtifactLocation *string + // Current life cycle stage of the experiment: "active" or "deleted". Deleted + // experiments are not returned by APIs. + LifecycleStage *string + // Last update time + LastUpdateTime *int64 + // Creation time + CreationTime *int64 + // Tags: Additional metadata key-value pairs. + Tags []ExperimentTag + // The location where the experiment's traces are stored. Unset when traces are + // stored in the default MLflow backend. This field cannot be updated after the + // experiment is created. + TraceLocation *ExperimentTraceLocation +} + +// A tag for an experiment.. +type ExperimentTag struct { + // The tag key. + Key *string + // The tag value. + Value *string +} + +// The storage location for an experiment's traces.. +type ExperimentTraceLocation struct { + Location isExperimentTraceLocation_Location +} + +type isExperimentTraceLocation_Location interface { + isExperimentTraceLocation_Location() +} + +// ExperimentTraceLocation_Location_UcTraceLocation selects UcTraceLocation for ExperimentTraceLocation.Location. +// A Unity Catalog schema where the experiment's traces are stored as Delta +// tables. +type ExperimentTraceLocation_Location_UcTraceLocation struct { + UcTraceLocation UcTraceLocation +} + +func (*ExperimentTraceLocation_Location_UcTraceLocation) isExperimentTraceLocation_Location() {} + +// Metadata of a single artifact file or directory.. +type FileInfo struct { + // The path relative to the root artifact directory run. + Path *string + // Whether the path is a directory. + IsDir *bool + // The size in bytes of the file. Unset for directories. + FileSize *int64 +} + +type FinalizeLoggedModelRequest struct { + // The ID of the logged model to finalize. + ModelId *string + // Whether or not the model is ready for use. ``"LOGGED_MODEL_UPLOAD_FAILED"`` + // indicates that something went wrong when logging the model weights / agent + // code. + Status LoggedModelStatus +} + +type FinalizeLoggedModelResponse struct { + // The updated logged model. + Model *LoggedModel +} + +type GetExperimentByNameRequest struct { + // Name of the associated experiment. + ExperimentName *string +} + +type GetExperimentByNameResponse struct { + // Experiment details. + Experiment *Experiment +} + +type GetExperimentRequest struct { + // ID of the associated experiment. + ExperimentId *string +} + +type GetExperimentResponse struct { + // Experiment details. + Experiment *Experiment + // A collection of active runs in the experiment. Note: this may not contain all + // of the experiment's active runs. + // + // This field is deprecated. Please use the "Search Runs" API to fetch runs + // within an experiment. + Runs []RunInfo +} + +type GetLoggedModelRequest struct { + // The ID of the logged model to retrieve. + ModelId *string +} + +type GetLoggedModelResponse struct { + // The retrieved logged model. + Model *LoggedModel +} + +type GetMetricHistoryResponse struct { + // All logged values for this metric if `max_results` is not specified in the + // request or if the total count of metrics returned is less than the service + // level pagination threshold. Otherwise, this is one page of results. + Metrics []Metric + // A token that can be used to issue a query for the next page of metric history + // values. A missing token indicates that no additional metrics are available to + // fetch. + NextPageToken *string +} + +type GetRunRequest struct { + // ID of the run to fetch. Must be provided. + RunId *string + // [Deprecated, use `run_id` instead] ID of the run to fetch. This field will be + // removed in a future MLflow version. + RunUuid *string +} + +type GetRunResponse struct { + // Run metadata (name, start time, etc) and data (metrics, params, and tags). + Run *Run +} + +// Tag for a dataset input.. +type InputTag struct { + // The tag key. + Key *string + // The tag value. + Value *string +} + +type ListArtifactsRequest struct { + // ID of the run whose artifacts to list. Must be provided. + RunId *string + // [Deprecated, use `run_id` instead] ID of the run whose artifacts to list. + // This field will be removed in a future MLflow version. + RunUuid *string + // Filter artifacts matching this path (a relative path from the root artifact + // directory). + Path *string + // The token indicating the page of artifact results to fetch. `page_token` is + // not supported when listing artifacts in UC Volumes. A maximum of 1000 + // artifacts will be retrieved for UC Volumes. Please call + // `/api/2.0/fs/directories{directory_path}` for listing artifacts in UC + // Volumes, which supports pagination. See [List directory contents | Files + // API](/api/workspace/files/listdirectorycontents). + PageToken *string +} + +type ListArtifactsResponse struct { + // The root artifact directory for the run. + RootUri *string + // The file location and metadata for artifacts. + Files []FileInfo + // The token that can be used to retrieve the next page of artifact results. + NextPageToken *string +} + +type ListExperimentsRequest struct { + // Qualifier for type of experiments to be returned. If unspecified, return only + // active experiments. + ViewType ViewType + // Maximum number of experiments desired. If `max_results` is unspecified, + // return all experiments. If `max_results` is too large, it'll be automatically + // capped at 1000. Callers of this endpoint are encouraged to pass max_results + // explicitly and leverage page_token to iterate through experiments. + MaxResults *int64 + // Token indicating the page of experiments to fetch + PageToken *string +} + +type ListExperimentsResponse struct { + // Paginated Experiments beginning with the first item on the requested page. + Experiments []Experiment + // Token that can be used to retrieve the next page of experiments. Empty token + // means no more experiment is available for retrieval. + NextPageToken *string +} + +type ListMetricHistoryRequest struct { + // ID of the run from which to fetch metric values. Must be provided. + RunId *string + // [Deprecated, use `run_id` instead] ID of the run from which to fetch metric + // values. This field will be removed in a future MLflow version. + RunUuid *string + // Name of the metric. + MetricKey *string + // Token indicating the page of metric histories to fetch. + PageToken *string + // Maximum number of Metric records to return per paginated request. Default is + // set to 25,000. If set higher than 25,000, a request Exception will be raised. + MaxResults *int +} + +type LogBatchRequest struct { + // ID of the run to log under + RunId *string + // Metrics to log. A single request can contain up to 1000 metrics, and up to + // 1000 metrics, params, and tags in total. + Metrics []Metric + // Params to log. A single request can contain up to 100 params, and up to 1000 + // metrics, params, and tags in total. + Params []Param + // Tags to log. A single request can contain up to 100 tags, and up to 1000 + // metrics, params, and tags in total. + Tags []RunTag +} + +type LogBatchResponse struct { +} + +type LogInputsRequest struct { + // ID of the run to log under + RunId *string + // Dataset inputs + Datasets []DatasetInput + // Model inputs + Models []ModelInput +} + +type LogInputsResponse struct { +} + +type LogLoggedModelParamsRequest struct { + // The ID of the logged model to log params for. + ModelId *string + // Parameters to attach to the model. + Params []LoggedModelParameter +} + +type LogLoggedModelParamsResponse struct { +} + +type LogMetricRequest struct { + // ID of the run under which to log the metric. Must be provided. + RunId *string + // [Deprecated, use `run_id` instead] ID of the run under which to log the + // metric. This field will be removed in a future MLflow version. + RunUuid *string + // Name of the metric. + Key *string + // Double value of the metric being logged. + Value *float64 + // Unix timestamp in milliseconds at the time metric was logged. + Timestamp *int64 + // Step at which to log the metric + Step *int64 + // ID of the logged model associated with the metric, if applicable + ModelId *string + // The name of the dataset associated with the metric. E.g. “my.uc.table@2” + // “nyc-taxi-dataset”, “fantastic-elk-3” + DatasetName *string + // Dataset digest of the dataset associated with the metric, e.g. an md5 hash of + // the dataset that uniquely identifies it within datasets of the same name. + DatasetDigest *string +} + +type LogMetricResponse struct { +} + +type LogModelRequest struct { + // ID of the run to log under + RunId *string + // MLmodel file in json format. + ModelJson *string +} + +type LogModelResponse struct { +} + +type LogOutputsRequest struct { + // The ID of the Run from which to log outputs. + RunId *string + // The model outputs from the Run. + Models []ModelOutput +} + +type LogOutputsResponse struct { +} + +type LogParamRequest struct { + // ID of the run under which to log the param. Must be provided. + RunId *string + // [Deprecated, use `run_id` instead] ID of the run under which to log the + // param. This field will be removed in a future MLflow version. + RunUuid *string + // Name of the param. Maximum size is 255 bytes. + Key *string + // String value of the param being logged. Maximum size is 500 bytes. + Value *string +} + +type LogParamResponse struct { +} + +// A logged model message includes logged model attributes, tags, registration +// info, params, and linked run metrics.. +type LoggedModel struct { + // The logged model attributes such as model ID, status, tags, etc. + Info *LoggedModelInfo + // The params and metrics attached to the logged model. + Data *LoggedModelData +} + +// A LoggedModelData message includes logged model params and linked metrics.. +type LoggedModelData struct { + // Immutable string key-value pairs of the model. + Params []LoggedModelParameter + // Performance metrics linked to the model. + Metrics []Metric +} + +// A LoggedModelInfo includes logged model attributes, tags, and registration +// info.. +type LoggedModelInfo struct { + // The unique identifier for the logged model. + ModelId *string + // The ID of the experiment that owns the model. + ExperimentId *string + // The name of the model. + Name *string + // The timestamp when the model was created in milliseconds since the UNIX + // epoch. + CreationTimestampMs *int64 + // The timestamp when the model was last updated in milliseconds since the UNIX + // epoch. + LastUpdatedTimestampMs *int64 + // The URI of the directory where model artifacts are stored. + ArtifactUri *string + // The status of whether or not the model is ready for use. + Status LoggedModelStatus + // The ID of the user or principal that created the model. + CreatorId *int64 + // The type of model, such as ``"Agent"``, ``"Classifier"``, ``"LLM"``. + ModelType *string + // The ID of the run that created the model. + SourceRunId *string + // Details on the current model status. + StatusMessage *string + // Mutable string key-value pairs set on the model. + Tags []LoggedModelTag +} + +// Parameter associated with a LoggedModel.. +type LoggedModelParameter struct { + // The key identifying this param. + Key *string + // The value of this param. + Value *string +} + +// Tag for a LoggedModel.. +type LoggedModelTag struct { + // The tag key. + Key *string + // The tag value. + Value *string +} + +// Metric associated with a run, represented as a key-value pair.. +type Metric struct { + // The key identifying the metric. + Key *string + // The value of the metric. + Value *float64 + // The timestamp at which the metric was recorded. + Timestamp *int64 + // The step at which the metric was logged. + Step *int64 + // The name of the dataset associated with the metric. E.g. “my.uc.table@2” + // “nyc-taxi-dataset”, “fantastic-elk-3” + DatasetName *string + // The dataset digest of the dataset associated with the metric, e.g. an md5 + // hash of the dataset that uniquely identifies it within datasets of the same + // name. + DatasetDigest *string + // The ID of the logged model or registered model version associated with the + // metric, if applicable. + ModelId *string + // The ID of the run containing the metric. + RunId *string +} + +// Represents a LoggedModel or Registered Model Version input to a Run.. +type ModelInput struct { + // The unique identifier of the model. + ModelId *string +} + +// Represents a LoggedModel output of a Run.. +type ModelOutput struct { + // The unique identifier of the model. + ModelId *string + // The step at which the model was produced. + Step *int64 +} + +// Param associated with a run.. +type Param struct { + // Key identifying this param. + Key *string + // Value associated with this param. + Value *string +} + +type RestoreExperimentRequest struct { + // ID of the associated experiment. + ExperimentId *string +} + +type RestoreExperimentResponse struct { +} + +type RestoreRunRequest struct { + // ID of the run to restore. + RunId *string +} + +type RestoreRunResponse struct { +} + +type RestoreRunsRequest struct { + // The ID of the experiment containing the runs to restore. + ExperimentId *string + // The minimum deletion timestamp in milliseconds since the UNIX epoch for + // restoring runs. Only runs deleted no earlier than this timestamp are + // restored. + MinTimestampMillis *int64 + // An optional positive integer indicating the maximum number of runs to + // restore. The maximum allowed value for max_runs is 10000. + MaxRuns *int +} + +type RestoreRunsResponse struct { + // The number of runs restored. + RunsRestored *int +} + +// A single run.. +type Run struct { + // Run metadata. + Info *RunInfo + // Run data. + Data *RunData + // Run inputs. + Inputs *RunInputs +} + +// Run data (metrics, params, and tags).. +type RunData struct { + // Run metrics. + Metrics []Metric + // Run parameters. + Params []Param + // Additional metadata key-value pairs. + Tags []RunTag +} + +// Metadata of a single run.. +type RunInfo struct { + // Unique identifier for the run. + RunId *string + // [Deprecated, use run_id instead] Unique identifier for the run. This field + // will be removed in a future MLflow version. + RunUuid *string + // The experiment ID. + ExperimentId *string + // The name of the run. + RunName *string + // User who initiated the run. This field is deprecated as of MLflow 1.0, and + // will be removed in a future MLflow release. Use 'mlflow.user' tag instead. + UserId *string + // Current status of the run. + Status RunStatus + // Unix timestamp of when the run started in milliseconds. + StartTime *int64 + // Unix timestamp of when the run ended in milliseconds. + EndTime *int64 + // URI of the directory where artifacts should be uploaded. This can be a local + // path (starting with "/"), or a distributed file system (DFS) path, like + // ``s3://bucket/directory`` or ``dbfs:/my/directory``. If not set, the local + // ``./mlruns`` directory is chosen. + ArtifactUri *string + // Current life cycle stage of the experiment : OneOf("active", "deleted") + LifecycleStage *string +} + +// Run inputs.. +type RunInputs struct { + // Run metrics. + DatasetInputs []DatasetInput + // Model inputs to the Run. + ModelInputs []ModelInput +} + +// Tag for a run.. +type RunTag struct { + // The tag key. + Key *string + // The tag value. + Value *string +} + +type SearchExperimentsRequest struct { + // Maximum number of experiments desired. Max threshold is 3000. + MaxResults *int64 + // Token indicating the page of experiments to fetch + PageToken *string + // String representing a SQL filter condition (e.g. "name ILIKE + // 'my-experiment%'") + Filter *string + // List of columns for ordering search results, which can include experiment + // name and last updated timestamp with an optional "DESC" or "ASC" annotation, + // where "ASC" is the default. Tiebreaks are done by experiment id DESC. + OrderBy []string + // Qualifier for type of experiments to be returned. If unspecified, return only + // active experiments. + ViewType ViewType +} + +type SearchExperimentsResponse struct { + // Experiments that match the search criteria + Experiments []Experiment + // Token that can be used to retrieve the next page of experiments. An empty + // token means that no more experiments are available for retrieval. + NextPageToken *string +} + +type SearchLoggedModelsRequest struct { + // The IDs of the experiments in which to search for logged models. + ExperimentIds []string + // A filter expression over logged model info and data that allows returning a + // subset of logged models. The syntax is a subset of SQL that supports AND'ing + // together binary operations. + // + // Example: ``params.alpha < 0.3 AND metrics.accuracy > 0.9``. + Filter *string + // List of datasets on which to apply the metrics filter clauses. For example, a + // filter with `metrics.accuracy > 0.9` and dataset info with name + // "test_dataset" means we will return all logged models with accuracy > 0.9 on + // the test_dataset. Metric values from ANY dataset matching the criteria are + // considered. If no datasets are specified, then metrics across all datasets + // are considered in the filter. + Datasets []SearchLoggedModelsRequest_Dataset + // The maximum number of Logged Models to return. The maximum limit is 50. + MaxResults *int + // The list of columns for ordering the results, with additional fields for + // sorting criteria. + OrderBy []SearchLoggedModelsRequest_OrderBy + // The token indicating the page of logged models to fetch. + PageToken *string +} + +type SearchLoggedModelsRequest_Dataset struct { + // The name of the dataset. + DatasetName *string + // The digest of the dataset. + DatasetDigest *string +} + +type SearchLoggedModelsRequest_OrderBy struct { + // The name of the field to order by, e.g. "metrics.accuracy". + FieldName *string + // Whether the search results order is ascending or not. + Ascending *bool + // If ``field_name`` refers to a metric, this field specifies the name of the + // dataset associated with the metric. Only metrics associated with the + // specified dataset name will be considered for ordering. This field may only + // be set if ``field_name`` refers to a metric. + DatasetName *string + // If ``field_name`` refers to a metric, this field specifies the digest of the + // dataset associated with the metric. Only metrics associated with the + // specified dataset name and digest will be considered for ordering. This field + // may only be set if ``dataset_name`` is also set. + DatasetDigest *string +} + +type SearchLoggedModelsResponse struct { + // Logged models that match the search criteria. + Models []LoggedModel + // The token that can be used to retrieve the next page of logged models. + NextPageToken *string +} + +type SearchRunsRequest struct { + // List of experiment IDs to search over. + ExperimentIds []string + // A filter expression over params, metrics, and tags, that allows returning a + // subset of runs. The syntax is a subset of SQL that supports ANDing together + // binary operations between a param, metric, or tag and a constant. + // + // Example: `metrics.rmse < 1 and params.model_class = 'LogisticRegression'` + // + // You can select columns with special characters (hyphen, space, period, etc.) + // by using double quotes: `metrics."model class" = 'LinearRegression' and + // tags."user-name" = 'Tomas'` + // + // Supported operators are `=`, `!=`, `>`, `>=`, `<`, and `<=`. + Filter *string + // Whether to display only active, only deleted, or all runs. Defaults to only + // active runs. + RunViewType ViewType + // Maximum number of runs desired. Max threshold is 50000 + MaxResults *int + // List of columns to be ordered by, including attributes, params, metrics, and + // tags with an optional `"DESC"` or `"ASC"` annotation, where `"ASC"` is the + // default. Example: `["params.input DESC", "metrics.alpha ASC", + // "metrics.rmse"]`. Tiebreaks are done by start_time `DESC` followed by + // `run_id` for runs with the same start time (and this is the default ordering + // criterion if order_by is not provided). + OrderBy []string + // Token for the current page of runs. + PageToken *string +} + +type SearchRunsResponse struct { + // Runs that match the search criteria. + Runs []Run + // Token for the next page of runs. + NextPageToken *string +} + +type SetExperimentTagRequest struct { + // ID of the experiment under which to log the tag. Must be provided. + ExperimentId *string + // Name of the tag. Keys up to 250 bytes in size are supported. + Key *string + // String value of the tag being logged. Values up to 64KB in size are + // supported. + Value *string +} + +type SetExperimentTagResponse struct { +} + +type SetLoggedModelTagsRequest struct { + // The ID of the logged model to set the tags on. + ModelId *string + // The tags to set on the logged model. + Tags []LoggedModelTag +} + +type SetLoggedModelTagsResponse struct { +} + +type SetTagRequest struct { + // ID of the run under which to log the tag. Must be provided. + RunId *string + // [Deprecated, use `run_id` instead] ID of the run under which to log the tag. + // This field will be removed in a future MLflow version. + RunUuid *string + // Name of the tag. Keys up to 250 bytes in size are supported. + Key *string + // String value of the tag being logged. Values up to 64KB in size are + // supported. + Value *string +} + +type SetTagResponse struct { +} + +// A Unity Catalog trace storage location. Traces are stored as Delta tables in +// the specified catalog and schema.. +type UcTraceLocation struct { + // The name of the Unity Catalog catalog. + Catalog *string + // The name of the Unity Catalog schema within `catalog`. + Schema *string + // The prefix for the trace tables, which are named + // `{catalog}.{schema}.{table_prefix}_otel_*`. May only contain letters, digits, + // and underscores, and may be at most 238 characters. When unset, a + // server-generated prefix derived from the experiment ID is used and this field + // stays empty on read; the resolved value is always available in + // `effective_table_prefix`. + TablePrefix *string + // The trace-table prefix actually in effect: `table_prefix` if it was set on + // creation, otherwise the server-generated default. + EffectiveTablePrefix *string +} + +type UpdateExperimentRequest struct { + // ID of the associated experiment. + ExperimentId *string + // If provided, the experiment's name is changed to the new name. The new name + // must be unique. + NewName *string +} + +type UpdateExperimentResponse struct { +} + +type UpdateRunRequest struct { + // ID of the run to update. Must be provided. + RunId *string + // [Deprecated, use `run_id` instead] ID of the run to update. This field will + // be removed in a future MLflow version. + RunUuid *string + // Updated status of the run. + Status RunStatus + // Unix timestamp in milliseconds of when the run ended. + EndTime *int64 + // Updated name of the run. + RunName *string +} + +type UpdateRunResponse struct { + // Updated metadata of the run. + RunInfo *RunInfo +} diff --git a/experiments/v1/wire.go b/experiments/v1/wire.go new file mode 100755 index 0000000..b03a7f9 --- /dev/null +++ b/experiments/v1/wire.go @@ -0,0 +1,1613 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package experiments + +import ( + "fmt" +) + +type createExperimentRequestWire struct { + Name *string `json:"name,omitempty"` + ArtifactLocation *string `json:"artifact_location,omitempty"` + Tags []experimentTagWire `json:"tags,omitempty"` + TraceLocation *experimentTraceLocationWire `json:"trace_location,omitempty"` +} + +func createExperimentRequestToWire(v *CreateExperimentRequest) (*createExperimentRequestWire, error) { + if v == nil { + return nil, nil + } + tagsWireValue, err := convertSlice(v.Tags, experimentTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExperimentRequest.Tags", err) + } + traceLocationWireValue, err := experimentTraceLocationToWire(v.TraceLocation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExperimentRequest.TraceLocation", err) + } + return &createExperimentRequestWire{ + Name: v.Name, + ArtifactLocation: v.ArtifactLocation, + Tags: tagsWireValue, + TraceLocation: traceLocationWireValue, + }, nil +} + +type createExperimentResponseWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` +} + +func createExperimentResponseFromWire(w *createExperimentResponseWire) (*CreateExperimentResponse, error) { + if w == nil { + return nil, nil + } + return &CreateExperimentResponse{ + ExperimentId: w.ExperimentId, + }, nil +} + +type createLoggedModelRequestWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` + Name *string `json:"name,omitempty"` + ModelType *string `json:"model_type,omitempty"` + SourceRunId *string `json:"source_run_id,omitempty"` + Params []loggedModelParameterWire `json:"params,omitempty"` + Tags []loggedModelTagWire `json:"tags,omitempty"` +} + +func createLoggedModelRequestToWire(v *CreateLoggedModelRequest) (*createLoggedModelRequestWire, error) { + if v == nil { + return nil, nil + } + paramsWireValue, err := convertSlice(v.Params, loggedModelParameterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateLoggedModelRequest.Params", err) + } + tagsWireValue, err := convertSlice(v.Tags, loggedModelTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateLoggedModelRequest.Tags", err) + } + return &createLoggedModelRequestWire{ + ExperimentId: v.ExperimentId, + Name: v.Name, + ModelType: v.ModelType, + SourceRunId: v.SourceRunId, + Params: paramsWireValue, + Tags: tagsWireValue, + }, nil +} + +type createLoggedModelResponseWire struct { + Model *loggedModelWire `json:"model,omitempty"` +} + +func createLoggedModelResponseFromWire(w *createLoggedModelResponseWire) (*CreateLoggedModelResponse, error) { + if w == nil { + return nil, nil + } + modelPublicValue, err := loggedModelFromWire(w.Model) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateLoggedModelResponse.Model", err) + } + return &CreateLoggedModelResponse{ + Model: modelPublicValue, + }, nil +} + +type createRunRequestWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` + UserId *string `json:"user_id,omitempty"` + RunName *string `json:"run_name,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + Tags []runTagWire `json:"tags,omitempty"` +} + +func createRunRequestToWire(v *CreateRunRequest) (*createRunRequestWire, error) { + if v == nil { + return nil, nil + } + tagsWireValue, err := convertSlice(v.Tags, runTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRunRequest.Tags", err) + } + return &createRunRequestWire{ + ExperimentId: v.ExperimentId, + UserId: v.UserId, + RunName: v.RunName, + StartTime: v.StartTime, + Tags: tagsWireValue, + }, nil +} + +type createRunResponseWire struct { + Run *runWire `json:"run,omitempty"` +} + +func createRunResponseFromWire(w *createRunResponseWire) (*CreateRunResponse, error) { + if w == nil { + return nil, nil + } + runPublicValue, err := runFromWire(w.Run) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRunResponse.Run", err) + } + return &CreateRunResponse{ + Run: runPublicValue, + }, nil +} + +type datasetWire struct { + Name *string `json:"name,omitempty"` + Digest *string `json:"digest,omitempty"` + SourceType *string `json:"source_type,omitempty"` + Source *string `json:"source,omitempty"` + Schema *string `json:"schema,omitempty"` + Profile *string `json:"profile,omitempty"` +} + +func datasetToWire(v *Dataset) (*datasetWire, error) { + if v == nil { + return nil, nil + } + return &datasetWire{ + Name: v.Name, + Digest: v.Digest, + SourceType: v.SourceType, + Source: v.Source, + Schema: v.Schema, + Profile: v.Profile, + }, nil +} + +func datasetFromWire(w *datasetWire) (*Dataset, error) { + if w == nil { + return nil, nil + } + return &Dataset{ + Name: w.Name, + Digest: w.Digest, + SourceType: w.SourceType, + Source: w.Source, + Schema: w.Schema, + Profile: w.Profile, + }, nil +} + +type datasetInputWire struct { + Tags []inputTagWire `json:"tags,omitempty"` + Dataset *datasetWire `json:"dataset,omitempty"` +} + +func datasetInputToWire(v *DatasetInput) (*datasetInputWire, error) { + if v == nil { + return nil, nil + } + tagsWireValue, err := convertSlice(v.Tags, inputTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatasetInput.Tags", err) + } + datasetWireValue, err := datasetToWire(v.Dataset) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatasetInput.Dataset", err) + } + return &datasetInputWire{ + Tags: tagsWireValue, + Dataset: datasetWireValue, + }, nil +} + +func datasetInputFromWire(w *datasetInputWire) (*DatasetInput, error) { + if w == nil { + return nil, nil + } + tagsPublicValue, err := convertSlice(w.Tags, inputTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatasetInput.Tags", err) + } + datasetPublicValue, err := datasetFromWire(w.Dataset) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DatasetInput.Dataset", err) + } + return &DatasetInput{ + Tags: tagsPublicValue, + Dataset: datasetPublicValue, + }, nil +} + +type deleteExperimentRequestWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` +} + +func deleteExperimentRequestToWire(v *DeleteExperimentRequest) (*deleteExperimentRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteExperimentRequestWire{ + ExperimentId: v.ExperimentId, + }, nil +} + +type deleteRunRequestWire struct { + RunId *string `json:"run_id,omitempty"` +} + +func deleteRunRequestToWire(v *DeleteRunRequest) (*deleteRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteRunRequestWire{ + RunId: v.RunId, + }, nil +} + +type deleteRunsRequestWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` + MaxTimestampMillis *int64 `json:"max_timestamp_millis,omitempty"` + MaxRuns *int `json:"max_runs,omitempty"` +} + +func deleteRunsRequestToWire(v *DeleteRunsRequest) (*deleteRunsRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteRunsRequestWire{ + ExperimentId: v.ExperimentId, + MaxTimestampMillis: v.MaxTimestampMillis, + MaxRuns: v.MaxRuns, + }, nil +} + +type deleteRunsResponseWire struct { + RunsDeleted *int `json:"runs_deleted,omitempty"` +} + +func deleteRunsResponseFromWire(w *deleteRunsResponseWire) (*DeleteRunsResponse, error) { + if w == nil { + return nil, nil + } + return &DeleteRunsResponse{ + RunsDeleted: w.RunsDeleted, + }, nil +} + +type deleteTagRequestWire struct { + RunId *string `json:"run_id,omitempty"` + Key *string `json:"key,omitempty"` +} + +func deleteTagRequestToWire(v *DeleteTagRequest) (*deleteTagRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteTagRequestWire{ + RunId: v.RunId, + Key: v.Key, + }, nil +} + +type experimentWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` + Name *string `json:"name,omitempty"` + ArtifactLocation *string `json:"artifact_location,omitempty"` + LifecycleStage *string `json:"lifecycle_stage,omitempty"` + LastUpdateTime *int64 `json:"last_update_time,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + Tags []experimentTagWire `json:"tags,omitempty"` + TraceLocation *experimentTraceLocationWire `json:"trace_location,omitempty"` +} + +func experimentFromWire(w *experimentWire) (*Experiment, error) { + if w == nil { + return nil, nil + } + tagsPublicValue, err := convertSlice(w.Tags, experimentTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Experiment.Tags", err) + } + traceLocationPublicValue, err := experimentTraceLocationFromWire(w.TraceLocation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Experiment.TraceLocation", err) + } + return &Experiment{ + ExperimentId: w.ExperimentId, + Name: w.Name, + ArtifactLocation: w.ArtifactLocation, + LifecycleStage: w.LifecycleStage, + LastUpdateTime: w.LastUpdateTime, + CreationTime: w.CreationTime, + Tags: tagsPublicValue, + TraceLocation: traceLocationPublicValue, + }, nil +} + +type experimentTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func experimentTagToWire(v *ExperimentTag) (*experimentTagWire, error) { + if v == nil { + return nil, nil + } + return &experimentTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func experimentTagFromWire(w *experimentTagWire) (*ExperimentTag, error) { + if w == nil { + return nil, nil + } + return &ExperimentTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type experimentTraceLocationWire struct { + UcTraceLocation *ucTraceLocationWire `json:"uc_trace_location,omitempty"` +} + +func experimentTraceLocationToWire(v *ExperimentTraceLocation) (*experimentTraceLocationWire, error) { + if v == nil { + return nil, nil + } + var locationUcTraceLocationWire *ucTraceLocationWire + switch value := v.Location.(type) { + case nil: + case *ExperimentTraceLocation_Location_UcTraceLocation: + if value != nil { + locationUcTraceLocationConverted, err := ucTraceLocationToWire(&value.UcTraceLocation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExperimentTraceLocation.Location.UcTraceLocation", err) + } + locationUcTraceLocationWire = locationUcTraceLocationConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ExperimentTraceLocation.Location", value) + } + return &experimentTraceLocationWire{ + UcTraceLocation: locationUcTraceLocationWire, + }, nil +} + +func experimentTraceLocationFromWire(w *experimentTraceLocationWire) (*ExperimentTraceLocation, error) { + if w == nil { + return nil, nil + } + locationMembers := 0 + if w.UcTraceLocation != nil { + locationMembers++ + } + if locationMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ExperimentTraceLocation.Location") + } + var locationSelection isExperimentTraceLocation_Location + switch { + case w.UcTraceLocation != nil: + locationUcTraceLocationConverted, err := ucTraceLocationFromWire(w.UcTraceLocation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExperimentTraceLocation.Location.UcTraceLocation", err) + } + locationSelection = &ExperimentTraceLocation_Location_UcTraceLocation{UcTraceLocation: *locationUcTraceLocationConverted} + } + return &ExperimentTraceLocation{ + Location: locationSelection, + }, nil +} + +type fileInfoWire struct { + Path *string `json:"path,omitempty"` + IsDir *bool `json:"is_dir,omitempty"` + FileSize *int64 `json:"file_size,omitempty"` +} + +func fileInfoFromWire(w *fileInfoWire) (*FileInfo, error) { + if w == nil { + return nil, nil + } + return &FileInfo{ + Path: w.Path, + IsDir: w.IsDir, + FileSize: w.FileSize, + }, nil +} + +type finalizeLoggedModelRequestWire struct { + ModelId *string `json:"model_id,omitempty"` + Status LoggedModelStatus `json:"status,omitempty"` +} + +func finalizeLoggedModelRequestToWire(v *FinalizeLoggedModelRequest) (*finalizeLoggedModelRequestWire, error) { + if v == nil { + return nil, nil + } + return &finalizeLoggedModelRequestWire{ + ModelId: v.ModelId, + Status: v.Status, + }, nil +} + +type finalizeLoggedModelResponseWire struct { + Model *loggedModelWire `json:"model,omitempty"` +} + +func finalizeLoggedModelResponseFromWire(w *finalizeLoggedModelResponseWire) (*FinalizeLoggedModelResponse, error) { + if w == nil { + return nil, nil + } + modelPublicValue, err := loggedModelFromWire(w.Model) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FinalizeLoggedModelResponse.Model", err) + } + return &FinalizeLoggedModelResponse{ + Model: modelPublicValue, + }, nil +} + +type getExperimentByNameRequestWire struct { + ExperimentName *string `json:"experiment_name,omitempty"` +} + +func getExperimentByNameRequestToWire(v *GetExperimentByNameRequest) (*getExperimentByNameRequestWire, error) { + if v == nil { + return nil, nil + } + return &getExperimentByNameRequestWire{ + ExperimentName: v.ExperimentName, + }, nil +} + +type getExperimentByNameResponseWire struct { + Experiment *experimentWire `json:"experiment,omitempty"` +} + +func getExperimentByNameResponseFromWire(w *getExperimentByNameResponseWire) (*GetExperimentByNameResponse, error) { + if w == nil { + return nil, nil + } + experimentPublicValue, err := experimentFromWire(w.Experiment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetExperimentByNameResponse.Experiment", err) + } + return &GetExperimentByNameResponse{ + Experiment: experimentPublicValue, + }, nil +} + +type getExperimentRequestWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` +} + +func getExperimentRequestToWire(v *GetExperimentRequest) (*getExperimentRequestWire, error) { + if v == nil { + return nil, nil + } + return &getExperimentRequestWire{ + ExperimentId: v.ExperimentId, + }, nil +} + +type getExperimentResponseWire struct { + Experiment *experimentWire `json:"experiment,omitempty"` + Runs []runInfoWire `json:"runs,omitempty"` +} + +func getExperimentResponseFromWire(w *getExperimentResponseWire) (*GetExperimentResponse, error) { + if w == nil { + return nil, nil + } + experimentPublicValue, err := experimentFromWire(w.Experiment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetExperimentResponse.Experiment", err) + } + runsPublicValue, err := convertSlice(w.Runs, runInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetExperimentResponse.Runs", err) + } + return &GetExperimentResponse{ + Experiment: experimentPublicValue, + Runs: runsPublicValue, + }, nil +} + +type getLoggedModelResponseWire struct { + Model *loggedModelWire `json:"model,omitempty"` +} + +func getLoggedModelResponseFromWire(w *getLoggedModelResponseWire) (*GetLoggedModelResponse, error) { + if w == nil { + return nil, nil + } + modelPublicValue, err := loggedModelFromWire(w.Model) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetLoggedModelResponse.Model", err) + } + return &GetLoggedModelResponse{ + Model: modelPublicValue, + }, nil +} + +type getMetricHistoryResponseWire struct { + Metrics []metricWire `json:"metrics,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func getMetricHistoryResponseFromWire(w *getMetricHistoryResponseWire) (*GetMetricHistoryResponse, error) { + if w == nil { + return nil, nil + } + metricsPublicValue, err := convertSlice(w.Metrics, metricFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetMetricHistoryResponse.Metrics", err) + } + return &GetMetricHistoryResponse{ + Metrics: metricsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type getRunRequestWire struct { + RunId *string `json:"run_id,omitempty"` + RunUuid *string `json:"run_uuid,omitempty"` +} + +func getRunRequestToWire(v *GetRunRequest) (*getRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &getRunRequestWire{ + RunId: v.RunId, + RunUuid: v.RunUuid, + }, nil +} + +type getRunResponseWire struct { + Run *runWire `json:"run,omitempty"` +} + +func getRunResponseFromWire(w *getRunResponseWire) (*GetRunResponse, error) { + if w == nil { + return nil, nil + } + runPublicValue, err := runFromWire(w.Run) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.Run", err) + } + return &GetRunResponse{ + Run: runPublicValue, + }, nil +} + +type inputTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func inputTagToWire(v *InputTag) (*inputTagWire, error) { + if v == nil { + return nil, nil + } + return &inputTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func inputTagFromWire(w *inputTagWire) (*InputTag, error) { + if w == nil { + return nil, nil + } + return &InputTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type listArtifactsRequestWire struct { + RunId *string `json:"run_id,omitempty"` + RunUuid *string `json:"run_uuid,omitempty"` + Path *string `json:"path,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listArtifactsRequestToWire(v *ListArtifactsRequest) (*listArtifactsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listArtifactsRequestWire{ + RunId: v.RunId, + RunUuid: v.RunUuid, + Path: v.Path, + PageToken: v.PageToken, + }, nil +} + +type listArtifactsResponseWire struct { + RootUri *string `json:"root_uri,omitempty"` + Files []fileInfoWire `json:"files,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listArtifactsResponseFromWire(w *listArtifactsResponseWire) (*ListArtifactsResponse, error) { + if w == nil { + return nil, nil + } + filesPublicValue, err := convertSlice(w.Files, fileInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListArtifactsResponse.Files", err) + } + return &ListArtifactsResponse{ + RootUri: w.RootUri, + Files: filesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listExperimentsRequestWire struct { + ViewType ViewType `json:"view_type,omitempty"` + MaxResults *int64 `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listExperimentsRequestToWire(v *ListExperimentsRequest) (*listExperimentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listExperimentsRequestWire{ + ViewType: v.ViewType, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listExperimentsResponseWire struct { + Experiments []experimentWire `json:"experiments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listExperimentsResponseFromWire(w *listExperimentsResponseWire) (*ListExperimentsResponse, error) { + if w == nil { + return nil, nil + } + experimentsPublicValue, err := convertSlice(w.Experiments, experimentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListExperimentsResponse.Experiments", err) + } + return &ListExperimentsResponse{ + Experiments: experimentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listMetricHistoryRequestWire struct { + RunId *string `json:"run_id,omitempty"` + RunUuid *string `json:"run_uuid,omitempty"` + MetricKey *string `json:"metric_key,omitempty"` + PageToken *string `json:"page_token,omitempty"` + MaxResults *int `json:"max_results,omitempty"` +} + +func listMetricHistoryRequestToWire(v *ListMetricHistoryRequest) (*listMetricHistoryRequestWire, error) { + if v == nil { + return nil, nil + } + return &listMetricHistoryRequestWire{ + RunId: v.RunId, + RunUuid: v.RunUuid, + MetricKey: v.MetricKey, + PageToken: v.PageToken, + MaxResults: v.MaxResults, + }, nil +} + +type logBatchRequestWire struct { + RunId *string `json:"run_id,omitempty"` + Metrics []metricWire `json:"metrics,omitempty"` + Params []paramWire `json:"params,omitempty"` + Tags []runTagWire `json:"tags,omitempty"` +} + +func logBatchRequestToWire(v *LogBatchRequest) (*logBatchRequestWire, error) { + if v == nil { + return nil, nil + } + metricsWireValue, err := convertSlice(v.Metrics, metricToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LogBatchRequest.Metrics", err) + } + paramsWireValue, err := convertSlice(v.Params, paramToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LogBatchRequest.Params", err) + } + tagsWireValue, err := convertSlice(v.Tags, runTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LogBatchRequest.Tags", err) + } + return &logBatchRequestWire{ + RunId: v.RunId, + Metrics: metricsWireValue, + Params: paramsWireValue, + Tags: tagsWireValue, + }, nil +} + +type logInputsRequestWire struct { + RunId *string `json:"run_id,omitempty"` + Datasets []datasetInputWire `json:"datasets,omitempty"` + Models []modelInputWire `json:"models,omitempty"` +} + +func logInputsRequestToWire(v *LogInputsRequest) (*logInputsRequestWire, error) { + if v == nil { + return nil, nil + } + datasetsWireValue, err := convertSlice(v.Datasets, datasetInputToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LogInputsRequest.Datasets", err) + } + modelsWireValue, err := convertSlice(v.Models, modelInputToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LogInputsRequest.Models", err) + } + return &logInputsRequestWire{ + RunId: v.RunId, + Datasets: datasetsWireValue, + Models: modelsWireValue, + }, nil +} + +type logLoggedModelParamsRequestWire struct { + ModelId *string `json:"model_id,omitempty"` + Params []loggedModelParameterWire `json:"params,omitempty"` +} + +func logLoggedModelParamsRequestToWire(v *LogLoggedModelParamsRequest) (*logLoggedModelParamsRequestWire, error) { + if v == nil { + return nil, nil + } + paramsWireValue, err := convertSlice(v.Params, loggedModelParameterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LogLoggedModelParamsRequest.Params", err) + } + return &logLoggedModelParamsRequestWire{ + ModelId: v.ModelId, + Params: paramsWireValue, + }, nil +} + +type logMetricRequestWire struct { + RunId *string `json:"run_id,omitempty"` + RunUuid *string `json:"run_uuid,omitempty"` + Key *string `json:"key,omitempty"` + Value *float64 `json:"value,omitempty"` + Timestamp *int64 `json:"timestamp,omitempty"` + Step *int64 `json:"step,omitempty"` + ModelId *string `json:"model_id,omitempty"` + DatasetName *string `json:"dataset_name,omitempty"` + DatasetDigest *string `json:"dataset_digest,omitempty"` +} + +func logMetricRequestToWire(v *LogMetricRequest) (*logMetricRequestWire, error) { + if v == nil { + return nil, nil + } + return &logMetricRequestWire{ + RunId: v.RunId, + RunUuid: v.RunUuid, + Key: v.Key, + Value: v.Value, + Timestamp: v.Timestamp, + Step: v.Step, + ModelId: v.ModelId, + DatasetName: v.DatasetName, + DatasetDigest: v.DatasetDigest, + }, nil +} + +type logModelRequestWire struct { + RunId *string `json:"run_id,omitempty"` + ModelJson *string `json:"model_json,omitempty"` +} + +func logModelRequestToWire(v *LogModelRequest) (*logModelRequestWire, error) { + if v == nil { + return nil, nil + } + return &logModelRequestWire{ + RunId: v.RunId, + ModelJson: v.ModelJson, + }, nil +} + +type logOutputsRequestWire struct { + RunId *string `json:"run_id,omitempty"` + Models []modelOutputWire `json:"models,omitempty"` +} + +func logOutputsRequestToWire(v *LogOutputsRequest) (*logOutputsRequestWire, error) { + if v == nil { + return nil, nil + } + modelsWireValue, err := convertSlice(v.Models, modelOutputToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LogOutputsRequest.Models", err) + } + return &logOutputsRequestWire{ + RunId: v.RunId, + Models: modelsWireValue, + }, nil +} + +type logParamRequestWire struct { + RunId *string `json:"run_id,omitempty"` + RunUuid *string `json:"run_uuid,omitempty"` + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func logParamRequestToWire(v *LogParamRequest) (*logParamRequestWire, error) { + if v == nil { + return nil, nil + } + return &logParamRequestWire{ + RunId: v.RunId, + RunUuid: v.RunUuid, + Key: v.Key, + Value: v.Value, + }, nil +} + +type loggedModelWire struct { + Info *loggedModelInfoWire `json:"info,omitempty"` + Data *loggedModelDataWire `json:"data,omitempty"` +} + +func loggedModelFromWire(w *loggedModelWire) (*LoggedModel, error) { + if w == nil { + return nil, nil + } + infoPublicValue, err := loggedModelInfoFromWire(w.Info) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LoggedModel.Info", err) + } + dataPublicValue, err := loggedModelDataFromWire(w.Data) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LoggedModel.Data", err) + } + return &LoggedModel{ + Info: infoPublicValue, + Data: dataPublicValue, + }, nil +} + +type loggedModelDataWire struct { + Params []loggedModelParameterWire `json:"params,omitempty"` + Metrics []metricWire `json:"metrics,omitempty"` +} + +func loggedModelDataFromWire(w *loggedModelDataWire) (*LoggedModelData, error) { + if w == nil { + return nil, nil + } + paramsPublicValue, err := convertSlice(w.Params, loggedModelParameterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LoggedModelData.Params", err) + } + metricsPublicValue, err := convertSlice(w.Metrics, metricFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LoggedModelData.Metrics", err) + } + return &LoggedModelData{ + Params: paramsPublicValue, + Metrics: metricsPublicValue, + }, nil +} + +type loggedModelInfoWire struct { + ModelId *string `json:"model_id,omitempty"` + ExperimentId *string `json:"experiment_id,omitempty"` + Name *string `json:"name,omitempty"` + CreationTimestampMs *int64 `json:"creation_timestamp_ms,omitempty"` + LastUpdatedTimestampMs *int64 `json:"last_updated_timestamp_ms,omitempty"` + ArtifactUri *string `json:"artifact_uri,omitempty"` + Status LoggedModelStatus `json:"status,omitempty"` + CreatorId *int64 `json:"creator_id,omitempty"` + ModelType *string `json:"model_type,omitempty"` + SourceRunId *string `json:"source_run_id,omitempty"` + StatusMessage *string `json:"status_message,omitempty"` + Tags []loggedModelTagWire `json:"tags,omitempty"` +} + +func loggedModelInfoFromWire(w *loggedModelInfoWire) (*LoggedModelInfo, error) { + if w == nil { + return nil, nil + } + tagsPublicValue, err := convertSlice(w.Tags, loggedModelTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LoggedModelInfo.Tags", err) + } + return &LoggedModelInfo{ + ModelId: w.ModelId, + ExperimentId: w.ExperimentId, + Name: w.Name, + CreationTimestampMs: w.CreationTimestampMs, + LastUpdatedTimestampMs: w.LastUpdatedTimestampMs, + ArtifactUri: w.ArtifactUri, + Status: w.Status, + CreatorId: w.CreatorId, + ModelType: w.ModelType, + SourceRunId: w.SourceRunId, + StatusMessage: w.StatusMessage, + Tags: tagsPublicValue, + }, nil +} + +type loggedModelParameterWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func loggedModelParameterToWire(v *LoggedModelParameter) (*loggedModelParameterWire, error) { + if v == nil { + return nil, nil + } + return &loggedModelParameterWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func loggedModelParameterFromWire(w *loggedModelParameterWire) (*LoggedModelParameter, error) { + if w == nil { + return nil, nil + } + return &LoggedModelParameter{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type loggedModelTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func loggedModelTagToWire(v *LoggedModelTag) (*loggedModelTagWire, error) { + if v == nil { + return nil, nil + } + return &loggedModelTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func loggedModelTagFromWire(w *loggedModelTagWire) (*LoggedModelTag, error) { + if w == nil { + return nil, nil + } + return &LoggedModelTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type metricWire struct { + Key *string `json:"key,omitempty"` + Value *float64 `json:"value,omitempty"` + Timestamp *int64 `json:"timestamp,omitempty"` + Step *int64 `json:"step,omitempty"` + DatasetName *string `json:"dataset_name,omitempty"` + DatasetDigest *string `json:"dataset_digest,omitempty"` + ModelId *string `json:"model_id,omitempty"` + RunId *string `json:"run_id,omitempty"` +} + +func metricToWire(v *Metric) (*metricWire, error) { + if v == nil { + return nil, nil + } + return &metricWire{ + Key: v.Key, + Value: v.Value, + Timestamp: v.Timestamp, + Step: v.Step, + DatasetName: v.DatasetName, + DatasetDigest: v.DatasetDigest, + ModelId: v.ModelId, + RunId: v.RunId, + }, nil +} + +func metricFromWire(w *metricWire) (*Metric, error) { + if w == nil { + return nil, nil + } + return &Metric{ + Key: w.Key, + Value: w.Value, + Timestamp: w.Timestamp, + Step: w.Step, + DatasetName: w.DatasetName, + DatasetDigest: w.DatasetDigest, + ModelId: w.ModelId, + RunId: w.RunId, + }, nil +} + +type modelInputWire struct { + ModelId *string `json:"model_id,omitempty"` +} + +func modelInputToWire(v *ModelInput) (*modelInputWire, error) { + if v == nil { + return nil, nil + } + return &modelInputWire{ + ModelId: v.ModelId, + }, nil +} + +func modelInputFromWire(w *modelInputWire) (*ModelInput, error) { + if w == nil { + return nil, nil + } + return &ModelInput{ + ModelId: w.ModelId, + }, nil +} + +type modelOutputWire struct { + ModelId *string `json:"model_id,omitempty"` + Step *int64 `json:"step,omitempty"` +} + +func modelOutputToWire(v *ModelOutput) (*modelOutputWire, error) { + if v == nil { + return nil, nil + } + return &modelOutputWire{ + ModelId: v.ModelId, + Step: v.Step, + }, nil +} + +type paramWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func paramToWire(v *Param) (*paramWire, error) { + if v == nil { + return nil, nil + } + return ¶mWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func paramFromWire(w *paramWire) (*Param, error) { + if w == nil { + return nil, nil + } + return &Param{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type restoreExperimentRequestWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` +} + +func restoreExperimentRequestToWire(v *RestoreExperimentRequest) (*restoreExperimentRequestWire, error) { + if v == nil { + return nil, nil + } + return &restoreExperimentRequestWire{ + ExperimentId: v.ExperimentId, + }, nil +} + +type restoreRunRequestWire struct { + RunId *string `json:"run_id,omitempty"` +} + +func restoreRunRequestToWire(v *RestoreRunRequest) (*restoreRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &restoreRunRequestWire{ + RunId: v.RunId, + }, nil +} + +type restoreRunsRequestWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` + MinTimestampMillis *int64 `json:"min_timestamp_millis,omitempty"` + MaxRuns *int `json:"max_runs,omitempty"` +} + +func restoreRunsRequestToWire(v *RestoreRunsRequest) (*restoreRunsRequestWire, error) { + if v == nil { + return nil, nil + } + return &restoreRunsRequestWire{ + ExperimentId: v.ExperimentId, + MinTimestampMillis: v.MinTimestampMillis, + MaxRuns: v.MaxRuns, + }, nil +} + +type restoreRunsResponseWire struct { + RunsRestored *int `json:"runs_restored,omitempty"` +} + +func restoreRunsResponseFromWire(w *restoreRunsResponseWire) (*RestoreRunsResponse, error) { + if w == nil { + return nil, nil + } + return &RestoreRunsResponse{ + RunsRestored: w.RunsRestored, + }, nil +} + +type runWire struct { + Info *runInfoWire `json:"info,omitempty"` + Data *runDataWire `json:"data,omitempty"` + Inputs *runInputsWire `json:"inputs,omitempty"` +} + +func runFromWire(w *runWire) (*Run, error) { + if w == nil { + return nil, nil + } + infoPublicValue, err := runInfoFromWire(w.Info) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.Info", err) + } + dataPublicValue, err := runDataFromWire(w.Data) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.Data", err) + } + inputsPublicValue, err := runInputsFromWire(w.Inputs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.Inputs", err) + } + return &Run{ + Info: infoPublicValue, + Data: dataPublicValue, + Inputs: inputsPublicValue, + }, nil +} + +type runDataWire struct { + Metrics []metricWire `json:"metrics,omitempty"` + Params []paramWire `json:"params,omitempty"` + Tags []runTagWire `json:"tags,omitempty"` +} + +func runDataFromWire(w *runDataWire) (*RunData, error) { + if w == nil { + return nil, nil + } + metricsPublicValue, err := convertSlice(w.Metrics, metricFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunData.Metrics", err) + } + paramsPublicValue, err := convertSlice(w.Params, paramFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunData.Params", err) + } + tagsPublicValue, err := convertSlice(w.Tags, runTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunData.Tags", err) + } + return &RunData{ + Metrics: metricsPublicValue, + Params: paramsPublicValue, + Tags: tagsPublicValue, + }, nil +} + +type runInfoWire struct { + RunId *string `json:"run_id,omitempty"` + RunUuid *string `json:"run_uuid,omitempty"` + ExperimentId *string `json:"experiment_id,omitempty"` + RunName *string `json:"run_name,omitempty"` + UserId *string `json:"user_id,omitempty"` + Status RunStatus `json:"status,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + EndTime *int64 `json:"end_time,omitempty"` + ArtifactUri *string `json:"artifact_uri,omitempty"` + LifecycleStage *string `json:"lifecycle_stage,omitempty"` +} + +func runInfoFromWire(w *runInfoWire) (*RunInfo, error) { + if w == nil { + return nil, nil + } + return &RunInfo{ + RunId: w.RunId, + RunUuid: w.RunUuid, + ExperimentId: w.ExperimentId, + RunName: w.RunName, + UserId: w.UserId, + Status: w.Status, + StartTime: w.StartTime, + EndTime: w.EndTime, + ArtifactUri: w.ArtifactUri, + LifecycleStage: w.LifecycleStage, + }, nil +} + +type runInputsWire struct { + DatasetInputs []datasetInputWire `json:"dataset_inputs,omitempty"` + ModelInputs []modelInputWire `json:"model_inputs,omitempty"` +} + +func runInputsFromWire(w *runInputsWire) (*RunInputs, error) { + if w == nil { + return nil, nil + } + datasetInputsPublicValue, err := convertSlice(w.DatasetInputs, datasetInputFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunInputs.DatasetInputs", err) + } + modelInputsPublicValue, err := convertSlice(w.ModelInputs, modelInputFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunInputs.ModelInputs", err) + } + return &RunInputs{ + DatasetInputs: datasetInputsPublicValue, + ModelInputs: modelInputsPublicValue, + }, nil +} + +type runTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func runTagToWire(v *RunTag) (*runTagWire, error) { + if v == nil { + return nil, nil + } + return &runTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func runTagFromWire(w *runTagWire) (*RunTag, error) { + if w == nil { + return nil, nil + } + return &RunTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type searchExperimentsRequestWire struct { + MaxResults *int64 `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` + Filter *string `json:"filter,omitempty"` + OrderBy []string `json:"order_by,omitempty"` + ViewType ViewType `json:"view_type,omitempty"` +} + +func searchExperimentsRequestToWire(v *SearchExperimentsRequest) (*searchExperimentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &searchExperimentsRequestWire{ + MaxResults: v.MaxResults, + PageToken: v.PageToken, + Filter: v.Filter, + OrderBy: v.OrderBy, + ViewType: v.ViewType, + }, nil +} + +type searchExperimentsResponseWire struct { + Experiments []experimentWire `json:"experiments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func searchExperimentsResponseFromWire(w *searchExperimentsResponseWire) (*SearchExperimentsResponse, error) { + if w == nil { + return nil, nil + } + experimentsPublicValue, err := convertSlice(w.Experiments, experimentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SearchExperimentsResponse.Experiments", err) + } + return &SearchExperimentsResponse{ + Experiments: experimentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type searchLoggedModelsRequestWire struct { + ExperimentIds []string `json:"experiment_ids,omitempty"` + Filter *string `json:"filter,omitempty"` + Datasets []searchLoggedModelsRequest_DatasetWire `json:"datasets,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + OrderBy []searchLoggedModelsRequest_OrderByWire `json:"order_by,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func searchLoggedModelsRequestToWire(v *SearchLoggedModelsRequest) (*searchLoggedModelsRequestWire, error) { + if v == nil { + return nil, nil + } + datasetsWireValue, err := convertSlice(v.Datasets, searchLoggedModelsRequest_DatasetToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SearchLoggedModelsRequest.Datasets", err) + } + orderByWireValue, err := convertSlice(v.OrderBy, searchLoggedModelsRequest_OrderByToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SearchLoggedModelsRequest.OrderBy", err) + } + return &searchLoggedModelsRequestWire{ + ExperimentIds: v.ExperimentIds, + Filter: v.Filter, + Datasets: datasetsWireValue, + MaxResults: v.MaxResults, + OrderBy: orderByWireValue, + PageToken: v.PageToken, + }, nil +} + +type searchLoggedModelsRequest_DatasetWire struct { + DatasetName *string `json:"dataset_name,omitempty"` + DatasetDigest *string `json:"dataset_digest,omitempty"` +} + +func searchLoggedModelsRequest_DatasetToWire(v *SearchLoggedModelsRequest_Dataset) (*searchLoggedModelsRequest_DatasetWire, error) { + if v == nil { + return nil, nil + } + return &searchLoggedModelsRequest_DatasetWire{ + DatasetName: v.DatasetName, + DatasetDigest: v.DatasetDigest, + }, nil +} + +type searchLoggedModelsRequest_OrderByWire struct { + FieldName *string `json:"field_name,omitempty"` + Ascending *bool `json:"ascending,omitempty"` + DatasetName *string `json:"dataset_name,omitempty"` + DatasetDigest *string `json:"dataset_digest,omitempty"` +} + +func searchLoggedModelsRequest_OrderByToWire(v *SearchLoggedModelsRequest_OrderBy) (*searchLoggedModelsRequest_OrderByWire, error) { + if v == nil { + return nil, nil + } + return &searchLoggedModelsRequest_OrderByWire{ + FieldName: v.FieldName, + Ascending: v.Ascending, + DatasetName: v.DatasetName, + DatasetDigest: v.DatasetDigest, + }, nil +} + +type searchLoggedModelsResponseWire struct { + Models []loggedModelWire `json:"models,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func searchLoggedModelsResponseFromWire(w *searchLoggedModelsResponseWire) (*SearchLoggedModelsResponse, error) { + if w == nil { + return nil, nil + } + modelsPublicValue, err := convertSlice(w.Models, loggedModelFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SearchLoggedModelsResponse.Models", err) + } + return &SearchLoggedModelsResponse{ + Models: modelsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type searchRunsRequestWire struct { + ExperimentIds []string `json:"experiment_ids,omitempty"` + Filter *string `json:"filter,omitempty"` + RunViewType ViewType `json:"run_view_type,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + OrderBy []string `json:"order_by,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func searchRunsRequestToWire(v *SearchRunsRequest) (*searchRunsRequestWire, error) { + if v == nil { + return nil, nil + } + return &searchRunsRequestWire{ + ExperimentIds: v.ExperimentIds, + Filter: v.Filter, + RunViewType: v.RunViewType, + MaxResults: v.MaxResults, + OrderBy: v.OrderBy, + PageToken: v.PageToken, + }, nil +} + +type searchRunsResponseWire struct { + Runs []runWire `json:"runs,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func searchRunsResponseFromWire(w *searchRunsResponseWire) (*SearchRunsResponse, error) { + if w == nil { + return nil, nil + } + runsPublicValue, err := convertSlice(w.Runs, runFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SearchRunsResponse.Runs", err) + } + return &SearchRunsResponse{ + Runs: runsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type setExperimentTagRequestWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func setExperimentTagRequestToWire(v *SetExperimentTagRequest) (*setExperimentTagRequestWire, error) { + if v == nil { + return nil, nil + } + return &setExperimentTagRequestWire{ + ExperimentId: v.ExperimentId, + Key: v.Key, + Value: v.Value, + }, nil +} + +type setLoggedModelTagsRequestWire struct { + ModelId *string `json:"model_id,omitempty"` + Tags []loggedModelTagWire `json:"tags,omitempty"` +} + +func setLoggedModelTagsRequestToWire(v *SetLoggedModelTagsRequest) (*setLoggedModelTagsRequestWire, error) { + if v == nil { + return nil, nil + } + tagsWireValue, err := convertSlice(v.Tags, loggedModelTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SetLoggedModelTagsRequest.Tags", err) + } + return &setLoggedModelTagsRequestWire{ + ModelId: v.ModelId, + Tags: tagsWireValue, + }, nil +} + +type setTagRequestWire struct { + RunId *string `json:"run_id,omitempty"` + RunUuid *string `json:"run_uuid,omitempty"` + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func setTagRequestToWire(v *SetTagRequest) (*setTagRequestWire, error) { + if v == nil { + return nil, nil + } + return &setTagRequestWire{ + RunId: v.RunId, + RunUuid: v.RunUuid, + Key: v.Key, + Value: v.Value, + }, nil +} + +type ucTraceLocationWire struct { + Catalog *string `json:"catalog,omitempty"` + Schema *string `json:"schema,omitempty"` + TablePrefix *string `json:"table_prefix,omitempty"` + EffectiveTablePrefix *string `json:"effective_table_prefix,omitempty"` +} + +func ucTraceLocationToWire(v *UcTraceLocation) (*ucTraceLocationWire, error) { + if v == nil { + return nil, nil + } + return &ucTraceLocationWire{ + Catalog: v.Catalog, + Schema: v.Schema, + TablePrefix: v.TablePrefix, + EffectiveTablePrefix: v.EffectiveTablePrefix, + }, nil +} + +func ucTraceLocationFromWire(w *ucTraceLocationWire) (*UcTraceLocation, error) { + if w == nil { + return nil, nil + } + return &UcTraceLocation{ + Catalog: w.Catalog, + Schema: w.Schema, + TablePrefix: w.TablePrefix, + EffectiveTablePrefix: w.EffectiveTablePrefix, + }, nil +} + +type updateExperimentRequestWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` + NewName *string `json:"new_name,omitempty"` +} + +func updateExperimentRequestToWire(v *UpdateExperimentRequest) (*updateExperimentRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateExperimentRequestWire{ + ExperimentId: v.ExperimentId, + NewName: v.NewName, + }, nil +} + +type updateRunRequestWire struct { + RunId *string `json:"run_id,omitempty"` + RunUuid *string `json:"run_uuid,omitempty"` + Status RunStatus `json:"status,omitempty"` + EndTime *int64 `json:"end_time,omitempty"` + RunName *string `json:"run_name,omitempty"` +} + +func updateRunRequestToWire(v *UpdateRunRequest) (*updateRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateRunRequestWire{ + RunId: v.RunId, + RunUuid: v.RunUuid, + Status: v.Status, + EndTime: v.EndTime, + RunName: v.RunName, + }, nil +} + +type updateRunResponseWire struct { + RunInfo *runInfoWire `json:"run_info,omitempty"` +} + +func updateRunResponseFromWire(w *updateRunResponseWire) (*UpdateRunResponse, error) { + if w == nil { + return nil, nil + } + runInfoPublicValue, err := runInfoFromWire(w.RunInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRunResponse.RunInfo", err) + } + return &UpdateRunResponse{ + RunInfo: runInfoPublicValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/features/.package.json b/features/.package.json new file mode 100644 index 0000000..5c082d3 --- /dev/null +++ b/features/.package.json @@ -0,0 +1,3 @@ +{ + "package": "features" +} diff --git a/features/CHANGELOG.md b/features/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/features/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/features/README.md b/features/README.md new file mode 100644 index 0000000..8bd17a2 --- /dev/null +++ b/features/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/features + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/features@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/features/v1" + +client, err := features.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/features/go.mod b/features/go.mod new file mode 100644 index 0000000..37f51b1 --- /dev/null +++ b/features/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/features + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/features/internal/version.go b/features/internal/version.go new file mode 100644 index 0000000..20dafa2 --- /dev/null +++ b/features/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-features" + +const Version = "0.0.1-dev.1" diff --git a/features/v1/client.go b/features/v1/client.go new file mode 100755 index 0000000..389f7ea --- /dev/null +++ b/features/v1/client.go @@ -0,0 +1,1604 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package features + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/features/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Batch create materialized features. +func (c *internalClient) BatchCreateMaterializedFeatures(ctx context.Context, req *BatchCreateMaterializedFeaturesRequest, opts ...call.Option) (*BatchCreateMaterializedFeaturesResponse, error) { + wireReq, err := batchCreateMaterializedFeaturesRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-engineering/materialized-features:batchCreate" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *BatchCreateMaterializedFeaturesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp batchCreateMaterializedFeaturesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = batchCreateMaterializedFeaturesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a Feature. +func (c *internalClient) CreateFeature(ctx context.Context, req *CreateFeatureRequest, opts ...call.Option) (*Feature, error) { + wireReq, err := createFeatureRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Feature) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-engineering/features" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Feature + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp featureWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = featureFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a Kafka config. During PrPr, Kafka configs can be read and used when +// creating features under the entire metastore. Only the creator of the Kafka +// config can delete it. +func (c *internalClient) CreateKafkaConfig(ctx context.Context, req *CreateKafkaConfigRequest, opts ...call.Option) (*KafkaConfig, error) { + wireReq, err := createKafkaConfigRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.KafkaConfig) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-engineering/features/kafka-configs" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *KafkaConfig + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp kafkaConfigWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = kafkaConfigFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a materialized feature. +func (c *internalClient) CreateMaterializedFeature(ctx context.Context, req *CreateMaterializedFeatureRequest, opts ...call.Option) (*MaterializedFeature, error) { + wireReq, err := createMaterializedFeatureRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.MaterializedFeature) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-engineering/materialized-features" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *MaterializedFeature + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp materializedFeatureWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = materializedFeatureFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a Stream, a governed UC entity representing an external streaming data +// source. +func (c *internalClient) CreateStream(ctx context.Context, req *CreateStreamRequest, opts ...call.Option) (*Stream, error) { + wireReq, err := createStreamRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Stream) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-engineering/streams" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Stream + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp streamWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = streamFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a Feature. +func (c *internalClient) DeleteFeature(ctx context.Context, req *DeleteFeatureRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/features/") + pb.singleSegment(*req.FullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete a Kafka config. During PrPr, Kafka configs can be read and used when +// creating features under the entire metastore. Only the creator of the Kafka +// config can delete it. +func (c *internalClient) DeleteKafkaConfig(ctx context.Context, req *DeleteKafkaConfigRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/features/kafka-configs/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete a materialized feature. +func (c *internalClient) DeleteMaterializedFeature(ctx context.Context, req *DeleteMaterializedFeatureRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/materialized-features/") + pb.singleSegment(*req.MaterializedFeatureId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete a Stream by its full three-part name (catalog.schema.stream). +func (c *internalClient) DeleteStream(ctx context.Context, req *DeleteStreamRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/streams/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Get a Feature. +func (c *internalClient) GetFeature(ctx context.Context, req *GetFeatureRequest, opts ...call.Option) (*Feature, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/features/") + pb.singleSegment(*req.FullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Feature + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp featureWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = featureFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a Kafka config. During PrPr, Kafka configs can be read and used when +// creating features under the entire metastore. Only the creator of the Kafka +// config can delete it. +func (c *internalClient) GetKafkaConfig(ctx context.Context, req *GetKafkaConfigRequest, opts ...call.Option) (*KafkaConfig, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/features/kafka-configs/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *KafkaConfig + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp kafkaConfigWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = kafkaConfigFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a materialized feature. +func (c *internalClient) GetMaterializedFeature(ctx context.Context, req *GetMaterializedFeatureRequest, opts ...call.Option) (*MaterializedFeature, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/materialized-features/") + pb.singleSegment(*req.MaterializedFeatureId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *MaterializedFeature + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp materializedFeatureWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = materializedFeatureFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a Stream by its full three-part name (catalog.schema.stream). +func (c *internalClient) GetStream(ctx context.Context, req *GetStreamRequest, opts ...call.Option) (*Stream, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/streams/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Stream + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp streamWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = streamFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List Features. +func (c *internalClient) ListFeatures(ctx context.Context, req *ListFeaturesRequest, opts ...call.Option) (*ListFeaturesResponse, error) { + wireReq, err := listFeaturesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-engineering/features" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "catalog_name", wireReq.CatalogName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "schema_name", wireReq.SchemaName); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListFeaturesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listFeaturesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listFeaturesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListFeaturesIter returns an iterator that iterates +// over the results of ListFeatures. +// +// For example: +// +// for item, err := range c.ListFeaturesIter(ctx, &ListFeaturesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListFeatures call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListFeatures directly. +func (c *internalClient) ListFeaturesIter(ctx context.Context, req *ListFeaturesRequest, opts ...call.Option) iter.Seq2[*Feature, error] { + return func(yield func(*Feature, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListFeaturesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListFeatures(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Features { + if !yield(&resp.Features[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List Kafka configs. During PrPr, Kafka configs can be read and used when +// creating features under the entire metastore. Only the creator of the Kafka +// config can delete it. +func (c *internalClient) ListKafkaConfigs(ctx context.Context, req *ListKafkaConfigsRequest, opts ...call.Option) (*ListKafkaConfigsResponse, error) { + wireReq, err := listKafkaConfigsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-engineering/features/kafka-configs" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListKafkaConfigsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listKafkaConfigsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listKafkaConfigsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListKafkaConfigsIter returns an iterator that iterates +// over the results of ListKafkaConfigs. +// +// For example: +// +// for item, err := range c.ListKafkaConfigsIter(ctx, &ListKafkaConfigsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListKafkaConfigs call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListKafkaConfigs directly. +func (c *internalClient) ListKafkaConfigsIter(ctx context.Context, req *ListKafkaConfigsRequest, opts ...call.Option) iter.Seq2[*KafkaConfig, error] { + return func(yield func(*KafkaConfig, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListKafkaConfigsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListKafkaConfigs(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.KafkaConfigs { + if !yield(&resp.KafkaConfigs[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List materialized features. +func (c *internalClient) ListMaterializedFeatures(ctx context.Context, req *ListMaterializedFeaturesRequest, opts ...call.Option) (*ListMaterializedFeaturesResponse, error) { + wireReq, err := listMaterializedFeaturesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-engineering/materialized-features" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "feature_name", wireReq.FeatureName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListMaterializedFeaturesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listMaterializedFeaturesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listMaterializedFeaturesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListMaterializedFeaturesIter returns an iterator that iterates +// over the results of ListMaterializedFeatures. +// +// For example: +// +// for item, err := range c.ListMaterializedFeaturesIter(ctx, &ListMaterializedFeaturesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListMaterializedFeatures call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListMaterializedFeatures directly. +func (c *internalClient) ListMaterializedFeaturesIter(ctx context.Context, req *ListMaterializedFeaturesRequest, opts ...call.Option) iter.Seq2[*MaterializedFeature, error] { + return func(yield func(*MaterializedFeature, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListMaterializedFeaturesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListMaterializedFeatures(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.MaterializedFeatures { + if !yield(&resp.MaterializedFeatures[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List Streams under a given catalog.schema parent. +func (c *internalClient) ListStreams(ctx context.Context, req *ListStreamsRequest, opts ...call.Option) (*ListStreamsResponse, error) { + wireReq, err := listStreamsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-engineering/streams" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "parent", wireReq.Parent); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListStreamsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listStreamsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listStreamsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListStreamsIter returns an iterator that iterates +// over the results of ListStreams. +// +// For example: +// +// for item, err := range c.ListStreamsIter(ctx, &ListStreamsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListStreams call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListStreams directly. +func (c *internalClient) ListStreamsIter(ctx context.Context, req *ListStreamsRequest, opts ...call.Option) iter.Seq2[*Stream, error] { + return func(yield func(*Stream, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListStreamsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListStreams(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Streams { + if !yield(&resp.Streams[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Update a Feature. +func (c *internalClient) UpdateFeature(ctx context.Context, req *UpdateFeatureRequest, opts ...call.Option) (*Feature, error) { + wireReq, err := updateFeatureRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Feature) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/features/") + pb.singleSegment(*req.Feature.FullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Feature + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp featureWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = featureFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a Kafka config. During PrPr, Kafka configs can be read and used when +// creating features under the entire metastore. Only the creator of the Kafka +// config can delete it. +func (c *internalClient) UpdateKafkaConfig(ctx context.Context, req *UpdateKafkaConfigRequest, opts ...call.Option) (*KafkaConfig, error) { + wireReq, err := updateKafkaConfigRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.KafkaConfig) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/features/kafka-configs/") + pb.singleSegment(*req.KafkaConfig.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *KafkaConfig + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp kafkaConfigWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = kafkaConfigFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a materialized feature (pause/resume). +func (c *internalClient) UpdateMaterializedFeature(ctx context.Context, req *UpdateMaterializedFeatureRequest, opts ...call.Option) (*MaterializedFeature, error) { + wireReq, err := updateMaterializedFeatureRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.MaterializedFeature) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/materialized-features/") + pb.singleSegment(*req.MaterializedFeature.MaterializedFeatureId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *MaterializedFeature + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp materializedFeatureWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = materializedFeatureFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a Stream. Only fields listed in `update_mask` are mutated. +func (c *internalClient) UpdateStream(ctx context.Context, req *UpdateStreamRequest, opts ...call.Option) (*Stream, error) { + wireReq, err := updateStreamRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Stream) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-engineering/streams/") + pb.singleSegment(*req.Stream.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Stream + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp streamWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = streamFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/features/v1/genhelper.go b/features/v1/genhelper.go new file mode 100755 index 0000000..e6b43e0 --- /dev/null +++ b/features/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package features + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/features/v1/model.go b/features/v1/model.go new file mode 100755 index 0000000..b0bec27 --- /dev/null +++ b/features/v1/model.go @@ -0,0 +1,1714 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package features + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// Scalar data types for request-time field definitions. Only flat (non-nested) +// types are supported. +type ScalarDataType string + +const ( + ScalarDataType_Unspecified ScalarDataType = "" + ScalarDataType_Integer ScalarDataType = "INTEGER" + ScalarDataType_Float ScalarDataType = "FLOAT" + ScalarDataType_Boolean ScalarDataType = "BOOLEAN" + ScalarDataType_String ScalarDataType = "STRING" + ScalarDataType_Double ScalarDataType = "DOUBLE" + ScalarDataType_Long ScalarDataType = "LONG" + ScalarDataType_Timestamp ScalarDataType = "TIMESTAMP" + ScalarDataType_Date ScalarDataType = "DATE" + ScalarDataType_Short ScalarDataType = "SHORT" + ScalarDataType_Binary ScalarDataType = "BINARY" + ScalarDataType_Decimal ScalarDataType = "DECIMAL" +) + +type MaterializedFeature_PipelineScheduleState string + +const ( + MaterializedFeature_PipelineScheduleState_Unspecified MaterializedFeature_PipelineScheduleState = "" + // Pipeline was configured to run once then stop. + MaterializedFeature_PipelineScheduleState_Snapshot MaterializedFeature_PipelineScheduleState = "SNAPSHOT" + // Pipeline is actively running and computing features. + MaterializedFeature_PipelineScheduleState_Active MaterializedFeature_PipelineScheduleState = "ACTIVE" + // Pipeline is paused and not computing features. + MaterializedFeature_PipelineScheduleState_Paused MaterializedFeature_PipelineScheduleState = "PAUSED" +) + +// Supported serialization formats for a schema registry schema. +type SchemaLocator_Format string + +const ( + SchemaLocator_Format_Unspecified SchemaLocator_Format = "" + // Avro-encoded schema. + SchemaLocator_Format_FormatAvro SchemaLocator_Format = "FORMAT_AVRO" + // Protobuf-encoded schema. + SchemaLocator_Format_FormatProtobuf SchemaLocator_Format = "FORMAT_PROTOBUF" + // JSON-encoded schema. + SchemaLocator_Format_FormatJson SchemaLocator_Format = "FORMAT_JSON" +) + +type StreamingMode_StreamingModeType string + +const ( + StreamingMode_StreamingModeType_Unspecified StreamingMode_StreamingModeType = "" + // Real-time mode. Ultra-low-latency trigger intended for operational workloads + // that need responses in milliseconds or sub-second latency. + StreamingMode_StreamingModeType_StreamingModeTypeRtm StreamingMode_StreamingModeType = "STREAMING_MODE_TYPE_RTM" + // Micro-batch mode in Structured Streaming. Better suited for ETL and analytics + // workloads where latency is measured in seconds or minutes and cost efficiency + // matters more. + StreamingMode_StreamingModeType_StreamingModeTypeMbm StreamingMode_StreamingModeType = "STREAMING_MODE_TYPE_MBM" +) + +// An aggregation function applied over a time window.. +type AggregationFunction struct { + // The type of the aggregation function. + Operation isAggregationFunction_Operation + // The time window over which the aggregation is computed. + TimeWindow *TimeWindow `fieldmask:"time_window"` + _ [0]aggregationFunctionOperationFieldMaskMetadata `fieldmask_oneof:"Operation"` +} + +type isAggregationFunction_Operation interface { + isAggregationFunction_Operation() +} + +// AggregationFunction_Operation_Avg selects Avg for AggregationFunction.Operation. +type AggregationFunction_Operation_Avg struct { + Avg AvgFunction `fieldmask:"avg"` +} + +func (*AggregationFunction_Operation_Avg) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_CountFunction selects CountFunction for AggregationFunction.Operation. +type AggregationFunction_Operation_CountFunction struct { + CountFunction CountFunction `fieldmask:"count_function"` +} + +func (*AggregationFunction_Operation_CountFunction) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_Sum selects Sum for AggregationFunction.Operation. +type AggregationFunction_Operation_Sum struct { + Sum SumFunction `fieldmask:"sum"` +} + +func (*AggregationFunction_Operation_Sum) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_Min selects Min for AggregationFunction.Operation. +type AggregationFunction_Operation_Min struct { + Min MinFunction `fieldmask:"min"` +} + +func (*AggregationFunction_Operation_Min) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_Max selects Max for AggregationFunction.Operation. +type AggregationFunction_Operation_Max struct { + Max MaxFunction `fieldmask:"max"` +} + +func (*AggregationFunction_Operation_Max) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_First selects First for AggregationFunction.Operation. +type AggregationFunction_Operation_First struct { + First FirstFunction `fieldmask:"first"` +} + +func (*AggregationFunction_Operation_First) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_Last selects Last for AggregationFunction.Operation. +type AggregationFunction_Operation_Last struct { + Last LastFunction `fieldmask:"last"` +} + +func (*AggregationFunction_Operation_Last) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_ApproxCountDistinct selects ApproxCountDistinct for AggregationFunction.Operation. +type AggregationFunction_Operation_ApproxCountDistinct struct { + ApproxCountDistinct ApproxCountDistinctFunction `fieldmask:"approx_count_distinct"` +} + +func (*AggregationFunction_Operation_ApproxCountDistinct) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_ApproxPercentile selects ApproxPercentile for AggregationFunction.Operation. +type AggregationFunction_Operation_ApproxPercentile struct { + ApproxPercentile ApproxPercentileFunction `fieldmask:"approx_percentile"` +} + +func (*AggregationFunction_Operation_ApproxPercentile) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_StddevPop selects StddevPop for AggregationFunction.Operation. +type AggregationFunction_Operation_StddevPop struct { + StddevPop StddevPopFunction `fieldmask:"stddev_pop"` +} + +func (*AggregationFunction_Operation_StddevPop) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_StddevSamp selects StddevSamp for AggregationFunction.Operation. +type AggregationFunction_Operation_StddevSamp struct { + StddevSamp StddevSampFunction `fieldmask:"stddev_samp"` +} + +func (*AggregationFunction_Operation_StddevSamp) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_VarPop selects VarPop for AggregationFunction.Operation. +type AggregationFunction_Operation_VarPop struct { + VarPop VarPopFunction `fieldmask:"var_pop"` +} + +func (*AggregationFunction_Operation_VarPop) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_VarSamp selects VarSamp for AggregationFunction.Operation. +type AggregationFunction_Operation_VarSamp struct { + VarSamp VarSampFunction `fieldmask:"var_samp"` +} + +func (*AggregationFunction_Operation_VarSamp) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_FirstN selects FirstN for AggregationFunction.Operation. +type AggregationFunction_Operation_FirstN struct { + FirstN FirstNFunction `fieldmask:"first_n"` +} + +func (*AggregationFunction_Operation_FirstN) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_LastN selects LastN for AggregationFunction.Operation. +type AggregationFunction_Operation_LastN struct { + LastN LastNFunction `fieldmask:"last_n"` +} + +func (*AggregationFunction_Operation_LastN) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_FirstDistinct selects FirstDistinct for AggregationFunction.Operation. +type AggregationFunction_Operation_FirstDistinct struct { + FirstDistinct FirstDistinctFunction `fieldmask:"first_distinct"` +} + +func (*AggregationFunction_Operation_FirstDistinct) isAggregationFunction_Operation() {} + +// AggregationFunction_Operation_LastDistinct selects LastDistinct for AggregationFunction.Operation. +type AggregationFunction_Operation_LastDistinct struct { + LastDistinct LastDistinctFunction `fieldmask:"last_distinct"` +} + +func (*AggregationFunction_Operation_LastDistinct) isAggregationFunction_Operation() {} + +type aggregationFunctionOperationFieldMaskMetadata struct { + *AggregationFunction_Operation_Avg + *AggregationFunction_Operation_CountFunction + *AggregationFunction_Operation_Sum + *AggregationFunction_Operation_Min + *AggregationFunction_Operation_Max + *AggregationFunction_Operation_First + *AggregationFunction_Operation_Last + *AggregationFunction_Operation_ApproxCountDistinct + *AggregationFunction_Operation_ApproxPercentile + *AggregationFunction_Operation_StddevPop + *AggregationFunction_Operation_StddevSamp + *AggregationFunction_Operation_VarPop + *AggregationFunction_Operation_VarSamp + *AggregationFunction_Operation_FirstN + *AggregationFunction_Operation_LastN + *AggregationFunction_Operation_FirstDistinct + *AggregationFunction_Operation_LastDistinct +} + +// Computes the approximate count of distinct values.. +type ApproxCountDistinctFunction struct { + // The input column from which the approximate count of distinct values is + // computed. + Input *string `fieldmask:"input"` + // The maximum relative standard deviation allowed (default defined by Spark). + RelativeSd *float64 `fieldmask:"relative_sd"` +} + +// Computes the approximate percentile of values.. +type ApproxPercentileFunction struct { + // The input column from which the approximate percentile is computed. + Input *string `fieldmask:"input"` + // The percentile value to compute (between 0 and 1). + Percentile *float64 `fieldmask:"percentile"` + // The accuracy parameter (higher is more accurate but slower). + Accuracy *int64 `fieldmask:"accuracy"` +} + +type AuthConfig struct { + AuthConfig isAuthConfig_AuthConfig + _ [0]authConfigAuthConfigFieldMaskMetadata `fieldmask_oneof:"AuthConfig"` +} + +type isAuthConfig_AuthConfig interface { + isAuthConfig_AuthConfig() +} + +// AuthConfig_AuthConfig_UcServiceCredentialName selects UcServiceCredentialName for AuthConfig.AuthConfig. +// Name of the Unity Catalog service credential. This value will be set under +// the option databricks.serviceCredential +type AuthConfig_AuthConfig_UcServiceCredentialName struct { + UcServiceCredentialName string `fieldmask:"uc_service_credential_name"` +} + +func (*AuthConfig_AuthConfig_UcServiceCredentialName) isAuthConfig_AuthConfig() {} + +// AuthConfig_AuthConfig_MtlsConfig selects MtlsConfig for AuthConfig.AuthConfig. +// Mutual-TLS authentication. See MtlsConfig. +type AuthConfig_AuthConfig_MtlsConfig struct { + MtlsConfig MtlsConfig `fieldmask:"mtls_config"` +} + +func (*AuthConfig_AuthConfig_MtlsConfig) isAuthConfig_AuthConfig() {} + +type authConfigAuthConfigFieldMaskMetadata struct { + *AuthConfig_AuthConfig_UcServiceCredentialName + *AuthConfig_AuthConfig_MtlsConfig +} + +// Computes the average of values.. +type AvgFunction struct { + // The input column from which the average is computed. For Kafka sources, use + // dot-prefixed path notation (e.g., "value.amount"). For nested fields, the + // leaf node name is used. Colon-prefixed notation (e.g., "value:amount") is + // supported for backwards compatibility but is deprecated; migrate to dot + // notation. + Input *string `fieldmask:"input"` +} + +type BackfillSource struct { + BackfillSource isBackfillSource_BackfillSource + _ [0]backfillSourceBackfillSourceFieldMaskMetadata `fieldmask_oneof:"BackfillSource"` +} + +type isBackfillSource_BackfillSource interface { + isBackfillSource_BackfillSource() +} + +// BackfillSource_BackfillSource_DeltaTableSource selects DeltaTableSource for BackfillSource.BackfillSource. +// Deprecated: Use delta_table_name instead. Kept for backwards compatibility. +// The Delta table source containing the historical data to backfill. Only the +// delta table name is used for backfill, other fields are ignored. +type BackfillSource_BackfillSource_DeltaTableSource struct { + DeltaTableSource DeltaTableSource `fieldmask:"delta_table_source"` +} + +func (*BackfillSource_BackfillSource_DeltaTableSource) isBackfillSource_BackfillSource() {} + +// BackfillSource_BackfillSource_DeltaTableName selects DeltaTableName for BackfillSource.BackfillSource. +// The full three-part name (catalog, schema, name) of the Delta table +// containing the historical data to backfill. +type BackfillSource_BackfillSource_DeltaTableName struct { + DeltaTableName string `fieldmask:"delta_table_name"` +} + +func (*BackfillSource_BackfillSource_DeltaTableName) isBackfillSource_BackfillSource() {} + +type backfillSourceBackfillSourceFieldMaskMetadata struct { + *BackfillSource_BackfillSource_DeltaTableSource + *BackfillSource_BackfillSource_DeltaTableName +} + +type BatchCreateMaterializedFeaturesRequest struct { + // The requests to create materialized features. + Requests []CreateMaterializedFeatureRequest +} + +type BatchCreateMaterializedFeaturesResponse struct { + // The created materialized features with assigned IDs. + MaterializedFeatures []MaterializedFeature +} + +// A ColumnSelection function, equivalent to the LAST() record of an entity over +// a lifetime window. +type ColumnSelection struct { + // Column name from source to select as the feature value. + Column *string `fieldmask:"column"` +} + +// Computes the count of values.. +type CountFunction struct { + // The input column from which the count is computed. For Kafka sources, use + // dot-prefixed path notation (e.g., "value.amount"). For nested fields, the + // leaf node name is used. Colon-prefixed notation (e.g., "value:amount") is + // supported for backwards compatibility but is deprecated; migrate to dot + // notation. + Input *string `fieldmask:"input"` +} + +type CreateFeatureRequest struct { + // Feature to create. + Feature *Feature +} + +type CreateKafkaConfigRequest struct { + KafkaConfig *KafkaConfig +} + +type CreateMaterializedFeatureRequest struct { + // The materialized feature to create. + MaterializedFeature *MaterializedFeature +} + +// Create a Stream, a governed UC entity representing an external streaming data +// source.. +type CreateStreamRequest struct { + // The Stream to create. + Stream *Stream +} + +// A cron-based schedule trigger for the materialization pipeline.. +type CronSchedule struct { + // The cron expression defining the schedule (e.g., "0 0 * * *" for daily at + // midnight). + CronExpression *string `fieldmask:"cron_expression"` +} + +// A CustomUdf function applies a registered Unity Catalog function row-wise to +// source columns, producing a single output column per row.. +type CustomUdf struct { + // Fully qualified 3-part Unity Catalog path of the function to apply. + FunctionPath *string `fieldmask:"function_path"` + // Binds each UC function parameter to a source column. May be empty for + // zero-argument functions (e.g. a timestamp generator). + InputBindings []InputBinding `fieldmask:"input_bindings"` +} + +// Specifies the data source backing a feature. Exactly one source type must be +// set.. +type DataSource struct { + DataSource isDataSource_DataSource + // Completeness timing for this Feature's use of the source. This configuration + // is part of the Feature definition; it does not modify the underlying table or + // stream. + Lateness *SourceLateness `fieldmask:"lateness"` + _ [0]dataSourceDataSourceFieldMaskMetadata `fieldmask_oneof:"DataSource"` +} + +type isDataSource_DataSource interface { + isDataSource_DataSource() +} + +// DataSource_DataSource_DeltaTableSource selects DeltaTableSource for DataSource.DataSource. +// A Delta table data source. +type DataSource_DataSource_DeltaTableSource struct { + DeltaTableSource DeltaTableSource `fieldmask:"delta_table_source"` +} + +func (*DataSource_DataSource_DeltaTableSource) isDataSource_DataSource() {} + +// DataSource_DataSource_KafkaSource selects KafkaSource for DataSource.DataSource. +// A Kafka stream data source. +type DataSource_DataSource_KafkaSource struct { + KafkaSource KafkaSource `fieldmask:"kafka_source"` +} + +func (*DataSource_DataSource_KafkaSource) isDataSource_DataSource() {} + +// DataSource_DataSource_RequestSource selects RequestSource for DataSource.DataSource. +// A request-time data source. +type DataSource_DataSource_RequestSource struct { + RequestSource RequestSource `fieldmask:"request_source"` +} + +func (*DataSource_DataSource_RequestSource) isDataSource_DataSource() {} + +// DataSource_DataSource_StreamSource selects StreamSource for DataSource.DataSource. +// A Stream data source. +type DataSource_DataSource_StreamSource struct { + StreamSource StreamSource `fieldmask:"stream_source"` +} + +func (*DataSource_DataSource_StreamSource) isDataSource_DataSource() {} + +type dataSourceDataSourceFieldMaskMetadata struct { + *DataSource_DataSource_DeltaTableSource + *DataSource_DataSource_KafkaSource + *DataSource_DataSource_RequestSource + *DataSource_DataSource_StreamSource +} + +type DeleteFeatureRequest struct { + // Name of the feature to delete. + FullName *string +} + +type DeleteKafkaConfigRequest struct { + // Name of the Kafka config to delete. + Name *string +} + +type DeleteMaterializedFeatureRequest struct { + // The ID of the materialized feature to delete. + MaterializedFeatureId *string +} + +// Delete a Stream by its full three-part name (catalog.schema.stream).. +type DeleteStreamRequest struct { + // Full three-part name (catalog.schema.stream) of the Stream to delete. + Name *string +} + +type DeltaTableSource struct { + // The full three-part (catalog, schema, table) name of the Delta table. + FullName *string `fieldmask:"full_name"` + // Single WHERE clause to filter delta table before applying transformations. + // Will be row-wise evaluated, so should only include conditionals and + // projections. + FilterCondition *string `fieldmask:"filter_condition"` + // A single SQL SELECT expression applied after filter_condition. Should + // contains all the columns needed (eg. "SELECT *, col_a + col_b AS col_c FROM + // x.y.z WHERE col_a > 0" would have `transformation_sql` "*, col_a + col_b AS + // col_c") If transformation_sql is not provided, all columns of the delta table + // are present in the DataSource dataframe. + TransformationSql *string `fieldmask:"transformation_sql"` + // Schema of the resulting dataframe after transformations, in Spark StructType + // JSON format (from df.schema.json()). Required if transformation_sql is + // specified. Example: + // {"type":"struct","fields":[{"name":"col_a","type":"integer","nullable":true,"metadata":{}},{"name":"col_c","type":"integer","nullable":true,"metadata":{}}]} + DataframeSchema *string `fieldmask:"dataframe_schema"` +} + +// Direct connection configs for mTLS, as Kafka Connections do not support mTLS +// yet . Temporarily used until UC Kafka Connections gain mTLS support.. +type DirectMtlsConfig struct { + // A comma-separated list of host:port pairs for the Kafka bootstrap servers. + BootstrapServers *string `fieldmask:"bootstrap_servers"` + // Mutual-TLS authentication configuration. + MtlsConfig *MtlsConfig `fieldmask:"mtls_config"` +} + +// Schema definitions provided directly on the Stream, as opposed to referencing +// a schema registry. To resolve schemas from a registry instead, use +// SchemaRegistryConfig.. +type DirectSchemas struct { + // Schema for the message payload. For Kafka, this is the value schema. Unless + // the platform supports another schema (e.g. keys for Kafka), this must be + // specified. + PayloadSchema *SchemaConfig `fieldmask:"payload_schema"` + // Schema for the message key. This is only used for Kafka streams. For Kafka, + // at least one of payload_schema or key_schema must be specified. + KeySchema *SchemaConfig `fieldmask:"key_schema"` +} + +type EntityColumn struct { + // The name of the entity column. For Kafka sources, use dot-prefixed path + // notation to reference fields within the key or value schema (e.g., + // "value.user_id", "key.partition_key"). For nested fields, the leaf node name + // (e.g., "user_id" from "value.trip_details.user_id") is what will be present + // in materialized tables and expected to match at query time. Colon-prefixed + // notation (e.g., "value:user_id") is supported for backwards compatibility but + // is deprecated; migrate to dot notation. + Name *string +} + +type Feature struct { + // The full three-part name (catalog, schema, name) of the feature. This is the + // feature's resource identifier; the catalog_name, schema_name, and name fields + // below are OUTPUT_ONLY decomposed views of this value. + FullName *string `fieldmask:"full_name"` + // The data source of the feature. + Source *DataSource `fieldmask:"source"` + // The function by which the feature is computed. + Function *Function `fieldmask:"function"` + // The description of the feature. + Description *string `fieldmask:"description"` + // Lineage context information for this feature. WARNING: This field is + // primarily intended for internal use by systems and is + // automatically populated when features are created through + // notebooks or jobs. Users should not manually set this field as incorrect + // values may lead to inaccurate lineage tracking or unexpected behavior. This + // field will be set by feature-engineering client and should be left unset by + // SDK and terraform users. + LineageContext *LineageContext `fieldmask:"lineage_context"` + // The entity columns for the feature, used as aggregation keys and for + // query-time lookup. + Entities []EntityColumn `fieldmask:"entities"` + // Column recording time, used for point-in-time joins, backfills, and + // aggregations. + TimeseriesColumn *TimeseriesColumn `fieldmask:"timeseries_column"` + // Name of parent catalog. + CatalogName *string `fieldmask:"catalog_name"` + // Name of parent schema relative to its parent catalog. + SchemaName *string `fieldmask:"schema_name"` + // Name of the feature, extracted from the full three-part name + // (catalog.schema.name). + Name *string `fieldmask:"name"` + // Time at which this feature was created. + CreatedAt *types.Time `fieldmask:"created_at"` + // Username of the feature creator. + CreatedBy *string `fieldmask:"created_by"` +} + +// A single field definition within a FlatSchema, specifying the field name and +// its scalar data type. Does not support nested or complex types (arrays, maps, +// structs).. +type FieldDefinition struct { + // The name of the field. + Name *string + // The scalar data type of the field. + DataType ScalarDataType +} + +// Returns the first N distinct values, ordered by the feature's timeseries +// column.. +type FirstDistinctFunction struct { + // The input column from which the first N distinct values are returned. + Input *string `fieldmask:"input"` + // The number of distinct values to return. + N *int64 `fieldmask:"n"` +} + +// Returns the first value.. +type FirstFunction struct { + // The input column from which the first value is returned. + Input *string `fieldmask:"input"` +} + +// Returns the first N values, ordered by the feature's timeseries column.. +type FirstNFunction struct { + // The input column from which the first N values are returned. + Input *string `fieldmask:"input"` + // The number of values to return. + N *int64 `fieldmask:"n"` +} + +// A flat (non-nested) schema for request-time fields, defined as an ordered +// list of field definitions. This schema only supports scalar types.. +type FlatSchema struct { + // The list of fields in this schema. + Fields []FieldDefinition `fieldmask:"fields"` +} + +type Function struct { + Function isFunction_Function + _ [0]functionFunctionFieldMaskMetadata `fieldmask_oneof:"Function"` +} + +type isFunction_Function interface { + isFunction_Function() +} + +// Function_Function_AggregationFunction selects AggregationFunction for Function.Function. +// An aggregation function applied over a time window. +type Function_Function_AggregationFunction struct { + AggregationFunction AggregationFunction `fieldmask:"aggregation_function"` +} + +func (*Function_Function_AggregationFunction) isFunction_Function() {} + +// Function_Function_ColumnSelection selects ColumnSelection for Function.Function. +// Selects the latest value of a single column in a data source +type Function_Function_ColumnSelection struct { + ColumnSelection ColumnSelection `fieldmask:"column_selection"` +} + +func (*Function_Function_ColumnSelection) isFunction_Function() {} + +// Function_Function_CustomUdf selects CustomUdf for Function.Function. +// Applies a registered Unity Catalog function row-wise to source columns. +type Function_Function_CustomUdf struct { + CustomUdf CustomUdf `fieldmask:"custom_udf"` +} + +func (*Function_Function_CustomUdf) isFunction_Function() {} + +type functionFunctionFieldMaskMetadata struct { + *Function_Function_AggregationFunction + *Function_Function_ColumnSelection + *Function_Function_CustomUdf +} + +type GetFeatureRequest struct { + // Name of the feature to get. + FullName *string +} + +type GetKafkaConfigRequest struct { + // Name of the Kafka config to get. + Name *string +} + +type GetMaterializedFeatureRequest struct { + // The ID of the materialized feature. + MaterializedFeatureId *string +} + +// Get a Stream by its full three-part name (catalog.schema.stream).. +type GetStreamRequest struct { + // Full three-part name (catalog.schema.stream) of the Stream to get. + Name *string +} + +// Configuration for the -managed ingestion pipeline. Groups the +// ingestion destination (required) and optional backfill source.. +type IngestionConfig struct { + // Destination for the -managed Delta table that holds an offline + // copy of the streaming data for querying and training. This table contains + // both 1) forward-filled data from the Stream and 2) backfilled data from the + // BackfillSource (if provided). This table is created and managed by + // and is deleted when the Stream is deleted. + IngestionDestination *IngestionDestination `fieldmask:"ingestion_destination"` + // A user-provided source for backfilling data. Historical data is used when + // creating a training set from streaming features linked to this Stream. The + // backfill data stored in this location will be copied into the ingestion table + // for offline querying and training. The schema for this source must match + // exactly that of the key and payload schemas specified for this Stream. + BackfillSource *BackfillSource `fieldmask:"backfill_source"` + // Column paths used to identify duplicate rows during ingestion; only one row + // per distinct combination of these values is kept. Use dot notation for nested + // fields (e.g. `value.user_id`). Empty list means every column is compared. + DeduplicationColumns []string `fieldmask:"deduplication_columns"` + // The ID of the SDP pipeline that continuously copies new events from the + // streaming source into the ingestion Delta table. + IngestionPipelineId *string `fieldmask:"ingestion_pipeline_id"` + // The ID of the Databricks Job that performs the forward-fill ingestion. + IngestionJobId *int64 `fieldmask:"ingestion_job_id"` + // The ID of the Databricks Job that performs the historical backfill of the + // ingestion Delta table. + BackfillJobId *int64 `fieldmask:"backfill_job_id"` +} + +// Destination for the -managed Delta table that holds an offline +// copy of the streaming data for querying and training.. +type IngestionDestination struct { + IngestionDestination isIngestionDestination_IngestionDestination + _ [0]ingestionDestinationIngestionDestinationFieldMaskMetadata `fieldmask_oneof:"IngestionDestination"` +} + +type isIngestionDestination_IngestionDestination interface { + isIngestionDestination_IngestionDestination() +} + +// IngestionDestination_IngestionDestination_DeltaTableName selects DeltaTableName for IngestionDestination.IngestionDestination. +// The full three-part name (catalog, schema, name) of the Delta table to be +// created for ingestion. +type IngestionDestination_IngestionDestination_DeltaTableName struct { + DeltaTableName string `fieldmask:"delta_table_name"` +} + +func (*IngestionDestination_IngestionDestination_DeltaTableName) isIngestionDestination_IngestionDestination() { +} + +type ingestionDestinationIngestionDestinationFieldMaskMetadata struct { + *IngestionDestination_IngestionDestination_DeltaTableName +} + +// Binds a single UC function parameter to a source column.. +type InputBinding struct { + // Name of the UC function parameter. + Parameter *string + // Source column whose value is passed for this parameter at execution time. + Column *string +} + +type JobContext struct { + // The job ID where this API invoked. + JobId *int64 `fieldmask:"job_id"` + // The job run ID where this API was invoked. + JobRunId *int64 `fieldmask:"job_run_id"` +} + +type KafkaConfig struct { + // Name that uniquely identifies this Kafka config within the metastore. This + // will be the identifier used from the Feature object to reference these + // configs for a feature. Can be distinct from topic name. + Name *string `fieldmask:"name"` + // A comma-separated list of host/port pairs pointing to Kafka cluster. + BootstrapServers *string `fieldmask:"bootstrap_servers"` + // Options to configure which Kafka topics to pull data from. + SubscriptionMode *SubscriptionMode `fieldmask:"subscription_mode"` + // Authentication configuration for connection to topics. + AuthConfig *AuthConfig `fieldmask:"auth_config"` + // Schema configuration for extracting message keys from topics. At least one of + // key_schema and value_schema must be provided. + KeySchema *SchemaConfig `fieldmask:"key_schema"` + // Schema configuration for extracting message values from topics. At least one + // of key_schema and value_schema must be provided. + ValueSchema *SchemaConfig `fieldmask:"value_schema"` + // Catch-all for miscellaneous options. Keys should be source options or Kafka + // consumer options (kafka.*) + ExtraOptions map[string]string `fieldmask:"extra_options"` + // A user-provided and managed source for backfilling data. Historical data is + // used when creating a training set from streaming features linked to this + // Kafka config. In the future, a separate table will be maintained by + // for forward filling data. The schema for this source must match + // exactly that of the key and value schemas specified for this Kafka config. + BackfillSource *BackfillSource `fieldmask:"backfill_source"` + // Configuration for ingesting Kafka data into a -managed Delta + // table. + IngestionConfig *IngestionConfig `fieldmask:"ingestion_config"` +} + +type KafkaSource struct { + // Name of the Kafka source, used to identify it. This is used to look up the + // corresponding KafkaConfig object. Can be distinct from topic name. + Name *string `fieldmask:"name"` + // The filter condition applied to the source data before aggregation. + FilterCondition *string `fieldmask:"filter_condition"` +} + +// Kafka-specific configuration for a Stream.. +type KafkaStreamConfig struct { + // Options to configure which Kafka topics to pull data from. + SubscriptionMode *KafkaSubscriptionMode `fieldmask:"subscription_mode"` + // Optional Kafka source or consumer options, validated against a server-side + // allowlist at request time. Allowed keys: - `maxOffsetsPerTrigger` - + // `startingOffsets` - `includeHeaders` - `kafka.request.timeout.ms` - + // `kafka.session.timeout.ms` - `kafka.max.partition.fetch.bytes` The following + // keys are ingestion-only and are stripped before being forwarded to the + // materialization pipeline: - `maxOffsetsPerTrigger` - `startingOffsets` Auth + // and connection details belong on the parent Stream's `connection_config`, not + // here. + ExtraOptions map[string]string `fieldmask:"extra_options"` +} + +// Subscription mode for Kafka topic selection, matching standard Spark +// Structured Streaming options.. +type KafkaSubscriptionMode struct { + // These match the settings from + // https://spark.apache.org/docs/latest/streaming/structured-streaming-kafka-integration.html + SubscriptionMode isKafkaSubscriptionMode_SubscriptionMode + _ [0]kafkaSubscriptionModeSubscriptionModeFieldMaskMetadata `fieldmask_oneof:"SubscriptionMode"` +} + +type isKafkaSubscriptionMode_SubscriptionMode interface { + isKafkaSubscriptionMode_SubscriptionMode() +} + +// KafkaSubscriptionMode_SubscriptionMode_Assign selects Assign for KafkaSubscriptionMode.SubscriptionMode. +// A JSON string that contains the specific topic-partitions to consume from. +// For example, for '{"topicA":[0,1],"topicB":[2,4]}', topicA's 0'th and 1st +// partitions will be consumed from. +type KafkaSubscriptionMode_SubscriptionMode_Assign struct { + Assign string `fieldmask:"assign"` +} + +func (*KafkaSubscriptionMode_SubscriptionMode_Assign) isKafkaSubscriptionMode_SubscriptionMode() {} + +// KafkaSubscriptionMode_SubscriptionMode_Subscribe selects Subscribe for KafkaSubscriptionMode.SubscriptionMode. +// A comma-separated list of Kafka topics to read from. For example, +// 'topicA,topicB,topicC'. +type KafkaSubscriptionMode_SubscriptionMode_Subscribe struct { + Subscribe string `fieldmask:"subscribe"` +} + +func (*KafkaSubscriptionMode_SubscriptionMode_Subscribe) isKafkaSubscriptionMode_SubscriptionMode() {} + +// KafkaSubscriptionMode_SubscriptionMode_SubscribePattern selects SubscribePattern for KafkaSubscriptionMode.SubscriptionMode. +// A regular expression matching topics to subscribe to. For example, 'topic.*' +// will subscribe to all topics starting with 'topic'. +type KafkaSubscriptionMode_SubscriptionMode_SubscribePattern struct { + SubscribePattern string `fieldmask:"subscribe_pattern"` +} + +func (*KafkaSubscriptionMode_SubscriptionMode_SubscribePattern) isKafkaSubscriptionMode_SubscriptionMode() { +} + +type kafkaSubscriptionModeSubscriptionModeFieldMaskMetadata struct { + *KafkaSubscriptionMode_SubscriptionMode_Assign + *KafkaSubscriptionMode_SubscriptionMode_Subscribe + *KafkaSubscriptionMode_SubscriptionMode_SubscribePattern +} + +// Kinesis-specific configuration for a Stream. For the underlying connector and +// its source options, see the documentation on connecting to +// Amazon Kinesis +// (https://docs.databricks.com/aws/en/connect/streaming/kinesis).. +type KinesisStreamConfig struct { + // Identifies the Kinesis data stream(s) to read from. Set exactly one of + // stream_names or stream_arns (identify the streams by name or by ARN, but not + // both). A single Stream may read from one or more Kinesis streams. + StreamIdentifier isKinesisStreamConfig_StreamIdentifier + // Optional Kinesis source options, validated against a server-side allowlist at + // request time. Auth and connection details belong on the parent Stream's + // `connection_config`, not here. + ExtraOptions map[string]string `fieldmask:"extra_options"` + _ [0]kinesisStreamConfigStreamIdentifierFieldMaskMetadata `fieldmask_oneof:"StreamIdentifier"` +} + +type isKinesisStreamConfig_StreamIdentifier interface { + isKinesisStreamConfig_StreamIdentifier() +} + +// KinesisStreamConfig_StreamIdentifier_StreamNames selects StreamNames for KinesisStreamConfig.StreamIdentifier. +// Kinesis stream names to read from. +type KinesisStreamConfig_StreamIdentifier_StreamNames struct { + StreamNames StreamNameList `fieldmask:"stream_names"` +} + +func (*KinesisStreamConfig_StreamIdentifier_StreamNames) isKinesisStreamConfig_StreamIdentifier() {} + +// KinesisStreamConfig_StreamIdentifier_StreamArns selects StreamArns for KinesisStreamConfig.StreamIdentifier. +// Kinesis stream ARNs to read from. +type KinesisStreamConfig_StreamIdentifier_StreamArns struct { + StreamArns StreamArnList `fieldmask:"stream_arns"` +} + +func (*KinesisStreamConfig_StreamIdentifier_StreamArns) isKinesisStreamConfig_StreamIdentifier() {} + +type kinesisStreamConfigStreamIdentifierFieldMaskMetadata struct { + *KinesisStreamConfig_StreamIdentifier_StreamNames + *KinesisStreamConfig_StreamIdentifier_StreamArns +} + +// Returns the last N distinct values, ordered by the feature's timeseries +// column.. +type LastDistinctFunction struct { + // The input column from which the last N distinct values are returned. + Input *string `fieldmask:"input"` + // The number of distinct values to return. + N *int64 `fieldmask:"n"` +} + +// Returns the last value.. +type LastFunction struct { + // The input column from which the last value is returned. + Input *string `fieldmask:"input"` +} + +// Returns the last N values, ordered by the feature's timeseries column.. +type LastNFunction struct { + // The input column from which the last N values are returned. + Input *string `fieldmask:"input"` + // The number of values to return. + N *int64 `fieldmask:"n"` +} + +// Lineage context information for tracking where an API was invoked. This will +// allow us to track lineage, which currently uses caller entity information for +// use across the Lineage Client and Observability in Lumberjack.. +type LineageContext struct { + // The notebook ID where this API was invoked. + NotebookId *int64 `fieldmask:"notebook_id"` + // Job context information including job ID and run ID. + JobContext *JobContext `fieldmask:"job_context"` +} + +// Request to list features. Listing is always scoped to a single catalog and +// schema; catalog_name and schema_name are required.. +type ListFeaturesRequest struct { + // Pagination token to go to the next page based on a previous query. + PageToken *string + // The maximum number of results to return. + PageSize *int + // Name of parent catalog for features of interest. + CatalogName *string + // Name of parent schema relative to its parent catalog. + SchemaName *string +} + +type ListFeaturesResponse struct { + // List of features. + Features []Feature + // Pagination token to request the next page of results for this query. + NextPageToken *string +} + +type ListKafkaConfigsRequest struct { + // Pagination token to go to the next page based on a previous query. + PageToken *string + // The maximum number of results to return. + PageSize *int +} + +type ListKafkaConfigsResponse struct { + // List of Kafka configs. Schemas are not included in the response. + KafkaConfigs []KafkaConfig + // Pagination token to request the next page of results for this query. + NextPageToken *string +} + +type ListMaterializedFeaturesRequest struct { + // Filter by feature name. If specified, only materialized features materialized + // from this feature will be returned. + FeatureName *string + // Pagination token to go to the next page based on a previous query. + PageToken *string + // The maximum number of results to return. Defaults to 100 if not specified. + // Cannot be greater than 1000. + PageSize *int +} + +type ListMaterializedFeaturesResponse struct { + // List of materialized features. + MaterializedFeatures []MaterializedFeature + // Pagination token to request the next page of results for this query. + NextPageToken *string +} + +// List Streams under a given parent. +// +// NOTE: Results are post-filtered by access permission on each stream's +// ingestion table. This means: - Returned results may be fewer than page_size +// (including zero) - Page token points to next unfiltered batch, not next +// filtered batch, and may point to an item that will be filtered out - Callers +// should paginate until next_page_token is empty to retrieve all accessible +// streams. +type ListStreamsRequest struct { + // Two-part name (catalog.schema) of the parent under which to list Streams. + Parent *string + // The maximum number of results to return. + PageSize *int + // Pagination token to go to the next page based on a previous query. + PageToken *string +} + +// Response to a ListStreamsRequest. +// +// NOTE: Results are post-filtered by access permission on each stream's +// ingestion table. This means: - Returned results may be fewer than page_size +// (including zero) - Page token points to next unfiltered batch, not next +// filtered batch, and may point to an item that will be filtered out Callers +// should paginate until next_page_token is empty to retrieve all accessible +// streams.. +type ListStreamsResponse struct { + // List of Streams. + Streams []Stream + // Pagination token to request the next page of results for this query. + NextPageToken *string +} + +// A materialized feature represents a feature that is continuously computed and +// stored.. +type MaterializedFeature struct { + // Server-assigned unique identifier for the materialized feature. + MaterializedFeatureId *string `fieldmask:"materialized_feature_id"` + // The full name of the feature in Unity Catalog. + FeatureName *string `fieldmask:"feature_name"` + Destination isMaterializedFeature_Destination + // The fully qualified Unity Catalog path to the table containing the + // materialized feature (Delta table or Lakebase table). Output only. + TableName *string `fieldmask:"table_name"` + // The schedule state of the materialization pipeline. Hidden from GraphQL: + // being deprecated, so not exposed to Catalog Explorer. + PipelineScheduleState MaterializedFeature_PipelineScheduleState `fieldmask:"pipeline_schedule_state"` + // The timestamp when the pipeline last ran and updated the materialized feature + // values. If the pipeline has not run yet, this field will be null. + LastMaterializationTime *types.Time `fieldmask:"last_materialization_time"` + // True if this is an online materialized feature. False if it is an offline + // materialized feature. + IsOnline *bool `fieldmask:"is_online"` + // The trigger configuration for the materialization pipeline. + Trigger isMaterializedFeature_Trigger + _ [0]materializedFeatureDestinationFieldMaskMetadata `fieldmask_oneof:"Destination"` + _ [0]materializedFeatureTriggerFieldMaskMetadata `fieldmask_oneof:"Trigger"` +} + +type isMaterializedFeature_Destination interface { + isMaterializedFeature_Destination() +} + +// MaterializedFeature_Destination_OfflineStoreConfig selects OfflineStoreConfig for MaterializedFeature.Destination. +// Destination for writing feature values to an offline Delta table. +type MaterializedFeature_Destination_OfflineStoreConfig struct { + OfflineStoreConfig OfflineStoreConfig `fieldmask:"offline_store_config"` +} + +func (*MaterializedFeature_Destination_OfflineStoreConfig) isMaterializedFeature_Destination() {} + +// MaterializedFeature_Destination_OnlineStoreConfig selects OnlineStoreConfig for MaterializedFeature.Destination. +// Destination for writing feature values to an online Lakebase table. +type MaterializedFeature_Destination_OnlineStoreConfig struct { + OnlineStoreConfig OnlineStoreConfig `fieldmask:"online_store_config"` +} + +func (*MaterializedFeature_Destination_OnlineStoreConfig) isMaterializedFeature_Destination() {} + +type isMaterializedFeature_Trigger interface { + isMaterializedFeature_Trigger() +} + +// MaterializedFeature_Trigger_CronScheduleTrigger selects CronScheduleTrigger for MaterializedFeature.Trigger. +// A cron-based schedule trigger for the materialization pipeline. +type MaterializedFeature_Trigger_CronScheduleTrigger struct { + CronScheduleTrigger CronSchedule `fieldmask:"cron_schedule_trigger"` +} + +func (*MaterializedFeature_Trigger_CronScheduleTrigger) isMaterializedFeature_Trigger() {} + +// MaterializedFeature_Trigger_TableTrigger selects TableTrigger for MaterializedFeature.Trigger. +// A trigger that fires when the upstream source table changes. +type MaterializedFeature_Trigger_TableTrigger struct { + TableTrigger TableTrigger `fieldmask:"table_trigger"` +} + +func (*MaterializedFeature_Trigger_TableTrigger) isMaterializedFeature_Trigger() {} + +// MaterializedFeature_Trigger_StreamingMode selects StreamingMode for MaterializedFeature.Trigger. +// The Structured Streaming trigger mode used for materialization. Real-time +// mode (RTM) targets sub-second latency for operational workloads; micro-batch +// mode (MBM) favors cost efficiency for ETL and analytics workloads. +type MaterializedFeature_Trigger_StreamingMode struct { + StreamingMode StreamingMode `fieldmask:"streaming_mode"` +} + +func (*MaterializedFeature_Trigger_StreamingMode) isMaterializedFeature_Trigger() {} + +type materializedFeatureDestinationFieldMaskMetadata struct { + *MaterializedFeature_Destination_OfflineStoreConfig + *MaterializedFeature_Destination_OnlineStoreConfig +} + +type materializedFeatureTriggerFieldMaskMetadata struct { + *MaterializedFeature_Trigger_CronScheduleTrigger + *MaterializedFeature_Trigger_TableTrigger + *MaterializedFeature_Trigger_StreamingMode +} + +// Computes the maximum value.. +type MaxFunction struct { + // The input column from which the maximum is computed. + Input *string `fieldmask:"input"` +} + +// Computes the minimum value.. +type MinFunction struct { + // The input column from which the minimum is computed. + Input *string `fieldmask:"input"` +} + +// Mutual-TLS (mTLS) authentication configuration. The keystore (client +// certificate + private key) and truststore (CAs trusted to verify the broker) +// live as JKS files on Unity Catalog volumes, with their passwords stored in +// secret scopes. This matches the SSL setup pattern documented at +// https://docs.databricks.com/en/connect/streaming/kafka/authentication#use-ssl-to-connect-databricks-to-kafka. +// +// At materialization time, the generated PySpark code passes the JKS file paths +// and resolved passwords through to the Kafka SSL options +// (kafka.ssl.keystore.location, kafka.ssl.keystore.password, +// kafka.ssl.key.password, kafka.ssl.truststore.location, +// kafka.ssl.truststore.password). Passwords are resolved on the Spark cluster +// via dbutils.secrets.get; this message stores only references, never password +// values.. +type MtlsConfig struct { + // Unity Catalog volume path to the JKS keystore file containing the client + // certificate and private key. e.g. + // "/Volumes////client.jks". The materialization + // compute must have read permission on this volume. + KeystoreLocation *string `fieldmask:"keystore_location"` + // Secret-scope reference for the JKS keystore password. + KeystorePasswordRef *SecretScopeReference `fieldmask:"keystore_password_ref"` + // Secret-scope reference for the private key password. Often the same value as + // the keystore password (keytool's default), but provided as a separate field + // because Apache Kafka requires it as a distinct option + // (kafka.ssl.key.password). + KeyPasswordRef *SecretScopeReference `fieldmask:"key_password_ref"` + // Unity Catalog volume path to the JKS truststore file containing the CA + // certificate(s) trusted to verify the Kafka broker's server certificate. e.g. + // "/Volumes////truststore.jks". + TruststoreLocation *string `fieldmask:"truststore_location"` + // Secret-scope reference for the JKS truststore password. + TruststorePasswordRef *SecretScopeReference `fieldmask:"truststore_password_ref"` + // Set to true only when the broker certificate's SAN intentionally does not + // match the connection endpoint — for example when reaching the cluster + // through a PrivateLink endpoint whose DNS name is not in the broker + // certificate. Skipping the hostname check removes a defense against + // man-in-the-middle attacks; do not enable casually. mTLS client authentication + // is unaffected by this option. + // + // See the Apache Kafka SSL security guide for background on this check: + // https://kafka.apache.org/42/security/encryption-and-authentication-using-ssl/#host-name-verification + DisableHostnameVerification *bool `fieldmask:"disable_hostname_verification"` +} + +// Configuration for offline store destination.. +type OfflineStoreConfig struct { + // The Unity Catalog catalog name. + CatalogName *string `fieldmask:"catalog_name"` + // The Unity Catalog schema name. + SchemaName *string `fieldmask:"schema_name"` + // Prefix for Unity Catalog table name. The materialized feature will be stored + // in a table with this prefix and a generated postfix. + TableNamePrefix *string `fieldmask:"table_name_prefix"` +} + +// Configuration for online store destination.. +type OnlineStoreConfig struct { + // The Unity Catalog catalog name. This name is also used as the Lakebase + // logical database name. Quoting is handled by the backend where needed, do not + // pre-quote it. + CatalogName *string `fieldmask:"catalog_name"` + // The Unity Catalog schema name. This name is also used as the Lakebase schema + // name under the database. Quoting is handled by the backend where needed, do + // not pre-quote it. + SchemaName *string `fieldmask:"schema_name"` + // Prefix for Unity Catalog table name. The materialized feature will be stored + // in a Lakebase table with this prefix and a generated postfix. + TableNamePrefix *string `fieldmask:"table_name_prefix"` + // The name of the target online store. + OnlineStoreName *string `fieldmask:"online_store_name"` +} + +// A Protocol Buffer schema paired with the name of the message within it that +// describes the Kafka payload. A .proto file may declare multiple messages; +// message_name disambiguates.. +type ProtoSchemaSpec struct { + // The raw .proto file text (proto2 and proto3 syntax supported, see + // https://protobuf.dev/programming-guides/proto3/ and + // https://protobuf.dev/programming-guides/proto2/). + SchemaText *string `fieldmask:"schema_text"` + // The fully-qualified name of the message within schema_text that describes the + // Kafka payload (e.g. "Event" or "com.example.Event" if schema_text declares a + // package). Identifies which message is used to decode each Kafka record — a + // .proto file may declare multiple messages but only one represents the + // payload. Must not be empty. + MessageName *string `fieldmask:"message_name"` +} + +// A request-time data source whose value is provided at inference time: offline +// batch scoring or online serving endpoint. +type RequestSource struct { + // The schema describing the request-time fields. Currently only flat schemas + // are supported. + Schema isRequestSource_Schema + _ [0]requestSourceSchemaFieldMaskMetadata `fieldmask_oneof:"Schema"` +} + +type isRequestSource_Schema interface { + isRequestSource_Schema() +} + +// RequestSource_Schema_FlatSchema selects FlatSchema for RequestSource.Schema. +// A flat schema with scalar-typed fields only. +type RequestSource_Schema_FlatSchema struct { + FlatSchema FlatSchema `fieldmask:"flat_schema"` +} + +func (*RequestSource_Schema_FlatSchema) isRequestSource_Schema() {} + +type requestSourceSchemaFieldMaskMetadata struct { + *RequestSource_Schema_FlatSchema +} + +// A rolling time window with an optional non-negative delay.. +type RollingWindow struct { + // The duration of the rolling window. Must be positive when set; absent means + // lifetime (aggregate over the entity's entire history). + WindowDuration *types.Duration `fieldmask:"window_duration"` + // Non-negative analytic lag that evaluates the window this far in the past. Use + // this for timing variations unrelated to source lateness, such as a 30-day + // count as of one week ago. If unset, the analytic lag is zero. It composes + // with source.lateness when both are set. + Delay *types.Duration `fieldmask:"delay"` +} + +// A sawtooth window served via the hybrid batch + streaming path. The batch +// pipeline maintains daily partial aggregates for the bulk of the window while +// the streaming pipeline maintains the most recent day(s), and serving merges +// them on read. Same field shape as RollingWindow, but a distinct type so the +// control plane can explicitly identify hybrid (sawtooth) features rather than +// inferring hybrid behavior from window_duration.. +type SawtoothWindow struct { + // The duration of the window. Must be positive and span more than two days when + // set, so that both the batch (N-1 day) and stale-path (N-2 day) partial + // aggregates are well defined. The duration need not be a whole number of days + // (e.g. 3 days 15 minutes is allowed). Absent means lifetime (aggregate over + // the entity's entire history). + WindowDuration *types.Duration `fieldmask:"window_duration"` + // Delay is not currently supported for Sawtooth windows. + Delay *types.Duration `fieldmask:"delay"` +} + +type SchemaConfig struct { + Schema isSchemaConfig_Schema + _ [0]schemaConfigSchemaFieldMaskMetadata `fieldmask_oneof:"Schema"` +} + +type isSchemaConfig_Schema interface { + isSchemaConfig_Schema() +} + +// SchemaConfig_Schema_JsonSchema selects JsonSchema for SchemaConfig.Schema. +// Schema of the JSON object in standard IETF JSON schema format +// (https://json-schema.org/). +type SchemaConfig_Schema_JsonSchema struct { + JsonSchema string `fieldmask:"json_schema"` +} + +func (*SchemaConfig_Schema_JsonSchema) isSchemaConfig_Schema() {} + +// SchemaConfig_Schema_AvroSchema selects AvroSchema for SchemaConfig.Schema. +// Avro schema in JSON format +// (https://avro.apache.org/docs/current/specification/). +type SchemaConfig_Schema_AvroSchema struct { + AvroSchema string `fieldmask:"avro_schema"` +} + +func (*SchemaConfig_Schema_AvroSchema) isSchemaConfig_Schema() {} + +// SchemaConfig_Schema_ProtoSchema selects ProtoSchema for SchemaConfig.Schema. +// Protocol Buffer schema with its payload message name. +type SchemaConfig_Schema_ProtoSchema struct { + ProtoSchema ProtoSchemaSpec `fieldmask:"proto_schema"` +} + +func (*SchemaConfig_Schema_ProtoSchema) isSchemaConfig_Schema() {} + +type schemaConfigSchemaFieldMaskMetadata struct { + *SchemaConfig_Schema_JsonSchema + *SchemaConfig_Schema_AvroSchema + *SchemaConfig_Schema_ProtoSchema +} + +// Schema locator for one side (payload or key) of a message. Identifies which +// schema to use in the schema registry and the serialization format.. +type SchemaLocator struct { + // Registry-specific schema locator. + RegistrySchema isSchemaLocator_RegistrySchema + // Serialization format for this schema. + Format SchemaLocator_Format `fieldmask:"format"` + _ [0]schemaLocatorRegistrySchemaFieldMaskMetadata `fieldmask_oneof:"RegistrySchema"` +} + +type isSchemaLocator_RegistrySchema interface { + isSchemaLocator_RegistrySchema() +} + +// SchemaLocator_RegistrySchema_ConfluentSchema selects ConfluentSchema for SchemaLocator.RegistrySchema. +// Confluent Schema Registry schema locator. +type SchemaLocator_RegistrySchema_ConfluentSchema struct { + ConfluentSchema SchemaLocator_ConfluentSchema `fieldmask:"confluent_schema"` +} + +func (*SchemaLocator_RegistrySchema_ConfluentSchema) isSchemaLocator_RegistrySchema() {} + +type schemaLocatorRegistrySchemaFieldMaskMetadata struct { + *SchemaLocator_RegistrySchema_ConfluentSchema +} + +// Confluent Schema Registry schema locator. The value to provide for `subject` +// depends on the naming strategy configured in your registry: - +// TopicNameStrategy (default): "{topic}-key" or "{topic}-value" e.g. for topic +// "transactions" use "transactions-value" for the payload and +// "transactions-key" for the key. - RecordNameStrategy: the fully-qualified +// record name e.g. "com.example.Payment" for Avro, the bare message name +// (without package) for Protobuf, or the `title` field value for JSON. - +// TopicRecordNameStrategy: "{topic}-{fully-qualified-record-name}" e.g. +// "transactions-com.example.Payment".. +type SchemaLocator_ConfluentSchema struct { + // The Confluent schema registry subject name. + Subject *string `fieldmask:"subject"` +} + +// Configuration for resolving a Stream's schema from an external schema +// registry (e.g. Confluent).. +type SchemaRegistryConfig struct { + // A Schema Registry UC Connection object. + UcConnection *string `fieldmask:"uc_connection"` + // Reference to the schema registry API secret in a secret scope. + ApiSecretRef *SecretScopeReference `fieldmask:"api_secret_ref"` + // Schema locator for the message payload. For Kafka this is the value. At least + // one of payload_schema_locator or key_schema_locator must be set. + PayloadSchemaLocator *SchemaLocator `fieldmask:"payload_schema_locator"` + // Schema locator for the message key. Only used for Kafka streams. At least one + // of payload_schema_locator or key_schema_locator must be set. + KeySchemaLocator *SchemaLocator `fieldmask:"key_schema_locator"` +} + +// Reference to an entry in a secret scope. The referenced value is +// fetched on the Spark cluster at materialization time via +// dbutils.secrets.get(scope, key).. +type SecretScopeReference struct { + // The secret scope name. + Scope *string `fieldmask:"scope"` + // The key within the scope. + Key *string `fieldmask:"key"` +} + +type SlidingWindow struct { + // The duration of the sliding window. Must be positive when set; absent means + // lifetime (aggregate over the entity's entire history). + WindowDuration *types.Duration `fieldmask:"window_duration"` + // The slide duration (interval by which windows advance, must be positive and + // less than duration). + SlideDuration *types.Duration `fieldmask:"slide_duration"` + // Non-negative analytic lag that evaluates the window this far in the past. Use + // this for timing variations unrelated to source lateness, such as a 30-day + // count as of one week ago. If unset, the analytic lag is zero. It composes + // with source.lateness when both are set. + Delay *types.Duration `fieldmask:"delay"` + // Non-negative phase shift from the default midnight UTC alignment. For + // example, offset=22h on a 24h slide produces boundaries at 22:00 UTC (17:00 + // New York in standard time) instead of midnight UTC. If unset, the offset is + // zero. Must be shorter than slide_duration (and therefore window_duration). + Offset *types.Duration `fieldmask:"offset"` +} + +// Configures when event-time data from this source is considered complete for a +// Feature.. +type SourceLateness struct { + // Non-negative time to wait after a window ends before treating its source data + // as complete. Training shifts the eligible evaluation time backwards by this + // duration so it does not join data that would still have been settling online. + // Materialization waits for the duration to elapse before publishing the + // window. If unset, source data is considered settled immediately. + SettlingDelay *types.Duration `fieldmask:"settling_delay"` +} + +// Computes the population standard deviation.. +type StddevPopFunction struct { + // The input column from which the population standard deviation is computed. + // For Kafka sources, use dot-prefixed path notation (e.g., "value.amount"). For + // nested fields, the leaf node name is used. Colon-prefixed notation (e.g., + // "value:amount") is supported for backwards compatibility but is deprecated; + // migrate to dot notation. + Input *string `fieldmask:"input"` +} + +// Computes the sample standard deviation.. +type StddevSampFunction struct { + // The input column from which the sample standard deviation is computed. + Input *string `fieldmask:"input"` +} + +// A Stream is a governed UC entity representing an external streaming data +// source. The source_config oneof determines the streaming platform source +// (e.g. Kafka, Kinesis, etc.).. +type Stream struct { + // Full three-part (catalog.schema.stream) name of the stream. + Name *string `fieldmask:"name"` + // User-provided description. + Description *string `fieldmask:"description"` + // Source-specific configuration. Determines the streaming platform source. + SourceConfig *StreamSourceConfig `fieldmask:"source_config"` + // Specifies how to connect and authenticate to the stream platform. + ConnectionConfig *StreamConnectionConfig `fieldmask:"connection_config"` + // Schema definitions for the stream, provided either directly on the Stream or + // resolved from an external schema registry through a UC Connection. + SchemaConfig *StreamSchemaConfig `fieldmask:"schema_config"` + // Configuration for streaming data ingestion: the managed table storing an + // offline copy of forward fill data and optional historical backfill. + IngestionConfig *IngestionConfig `fieldmask:"ingestion_config"` + // Time at which this Stream was created. + CreateTime *types.Time `fieldmask:"create_time"` + // Username of the Stream creator. + CreatedBy *string `fieldmask:"created_by"` + // Time at which this Stream was last modified. + UpdateTime *types.Time `fieldmask:"update_time"` + // Username of user who last modified the Stream. + UpdatedBy *string `fieldmask:"updated_by"` + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool `fieldmask:"browse_only"` +} + +// A list of Kinesis stream ARNs to read from.. +type StreamArnList struct { + // Kinesis stream ARNs to read from. For example, + // 'arn:aws:kinesis:us-west-2:111122223333:stream/stream-a'. + Arns []string `fieldmask:"arns"` +} + +// Specifies how to connect and authenticate to the stream platform.. +type StreamConnectionConfig struct { + ConnectionConfig isStreamConnectionConfig_ConnectionConfig + _ [0]streamConnectionConfigConnectionConfigFieldMaskMetadata `fieldmask_oneof:"ConnectionConfig"` +} + +type isStreamConnectionConfig_ConnectionConfig interface { + isStreamConnectionConfig_ConnectionConfig() +} + +// StreamConnectionConfig_ConnectionConfig_UcConnectionName selects UcConnectionName for StreamConnectionConfig.ConnectionConfig. +// Name of an existing UC Connection for stream platform access. Must be the +// correct type for the streaming platform (e.g. a Kafka Connection for a Kafka +// Stream, or a Kinesis Connection for a Kinesis Stream). +type StreamConnectionConfig_ConnectionConfig_UcConnectionName struct { + UcConnectionName string `fieldmask:"uc_connection_name"` +} + +func (*StreamConnectionConfig_ConnectionConfig_UcConnectionName) isStreamConnectionConfig_ConnectionConfig() { +} + +// StreamConnectionConfig_ConnectionConfig_DirectMtlsConfig selects DirectMtlsConfig for StreamConnectionConfig.ConnectionConfig. +// Direct mTLS configuration for stream platform access. This is only used in +// the short term until UC Kafka Connections support mTLS . Once UC Kafka +// Connections support mTLS, this will be deprecated. +type StreamConnectionConfig_ConnectionConfig_DirectMtlsConfig struct { + DirectMtlsConfig DirectMtlsConfig `fieldmask:"direct_mtls_config"` +} + +func (*StreamConnectionConfig_ConnectionConfig_DirectMtlsConfig) isStreamConnectionConfig_ConnectionConfig() { +} + +type streamConnectionConfigConnectionConfigFieldMaskMetadata struct { + *StreamConnectionConfig_ConnectionConfig_UcConnectionName + *StreamConnectionConfig_ConnectionConfig_DirectMtlsConfig +} + +// A list of Kinesis stream names to read from.. +type StreamNameList struct { + // Kinesis stream names to read from. + Names []string `fieldmask:"names"` +} + +// Schema definitions for the stream. Feature store supports both direct schemas +// and schema registries.. +type StreamSchemaConfig struct { + SchemaConfig isStreamSchemaConfig_SchemaConfig + _ [0]streamSchemaConfigSchemaConfigFieldMaskMetadata `fieldmask_oneof:"SchemaConfig"` +} + +type isStreamSchemaConfig_SchemaConfig interface { + isStreamSchemaConfig_SchemaConfig() +} + +// StreamSchemaConfig_SchemaConfig_DirectSchemas selects DirectSchemas for StreamSchemaConfig.SchemaConfig. +// Schema definitions provided directly on the Stream. +type StreamSchemaConfig_SchemaConfig_DirectSchemas struct { + DirectSchemas DirectSchemas `fieldmask:"direct_schemas"` +} + +func (*StreamSchemaConfig_SchemaConfig_DirectSchemas) isStreamSchemaConfig_SchemaConfig() {} + +// StreamSchemaConfig_SchemaConfig_SchemaRegistryConfig selects SchemaRegistryConfig for StreamSchemaConfig.SchemaConfig. +// Resolve schemas from an external schema registry. +type StreamSchemaConfig_SchemaConfig_SchemaRegistryConfig struct { + SchemaRegistryConfig SchemaRegistryConfig `fieldmask:"schema_registry_config"` +} + +func (*StreamSchemaConfig_SchemaConfig_SchemaRegistryConfig) isStreamSchemaConfig_SchemaConfig() {} + +type streamSchemaConfigSchemaConfigFieldMaskMetadata struct { + *StreamSchemaConfig_SchemaConfig_DirectSchemas + *StreamSchemaConfig_SchemaConfig_SchemaRegistryConfig +} + +// A Stream entity used as a data source for a feature.. +type StreamSource struct { + // Three-part full name of the Stream (catalog.schema.stream). + FullName *string `fieldmask:"full_name"` + // The filter condition applied to the source data before aggregation. + FilterCondition *string `fieldmask:"filter_condition"` + // The pipeline runs these SQL statements immediately after conversion into the + // schema specified on the Stream object. + TransformationSql *string `fieldmask:"transformation_sql"` + // Schema of the resulting dataframe after transformations, in Spark StructType + // JSON format (from df.schema.json()). Any subsequent functions operate against + // this dataframe. + DataframeSchema *string `fieldmask:"dataframe_schema"` +} + +// Source-specific configuration. Determines the streaming platform source.. +type StreamSourceConfig struct { + SourceConfig isStreamSourceConfig_SourceConfig + _ [0]streamSourceConfigSourceConfigFieldMaskMetadata `fieldmask_oneof:"SourceConfig"` +} + +type isStreamSourceConfig_SourceConfig interface { + isStreamSourceConfig_SourceConfig() +} + +// StreamSourceConfig_SourceConfig_KafkaStreamConfig selects KafkaStreamConfig for StreamSourceConfig.SourceConfig. +// Configuration for Apache Kafka streams. +type StreamSourceConfig_SourceConfig_KafkaStreamConfig struct { + KafkaStreamConfig KafkaStreamConfig `fieldmask:"kafka_stream_config"` +} + +func (*StreamSourceConfig_SourceConfig_KafkaStreamConfig) isStreamSourceConfig_SourceConfig() {} + +// StreamSourceConfig_SourceConfig_KinesisStreamConfig selects KinesisStreamConfig for StreamSourceConfig.SourceConfig. +// Configuration for AWS Kinesis Data Streams. +type StreamSourceConfig_SourceConfig_KinesisStreamConfig struct { + KinesisStreamConfig KinesisStreamConfig `fieldmask:"kinesis_stream_config"` +} + +func (*StreamSourceConfig_SourceConfig_KinesisStreamConfig) isStreamSourceConfig_SourceConfig() {} + +type streamSourceConfigSourceConfigFieldMaskMetadata struct { + *StreamSourceConfig_SourceConfig_KafkaStreamConfig + *StreamSourceConfig_SourceConfig_KinesisStreamConfig +} + +// The streaming mode configuration for a streaming materialization pipeline.. +type StreamingMode struct { + // The type of streaming mode used by the materialization pipeline. + Mode StreamingMode_StreamingModeType `fieldmask:"mode"` + // The desired data freshness for feature materialization, expressed as a + // duration string (e.g. "1 minute"). + FreshnessTarget *string `fieldmask:"freshness_target"` +} + +// Deprecated: Use KafkaSubscriptionMode instead.. +type SubscriptionMode struct { + // These match the settings from + // https://spark.apache.org/docs/latest/streaming/structured-streaming-kafka-integration.html + SubscriptionMode isSubscriptionMode_SubscriptionMode + _ [0]subscriptionModeSubscriptionModeFieldMaskMetadata `fieldmask_oneof:"SubscriptionMode"` +} + +type isSubscriptionMode_SubscriptionMode interface { + isSubscriptionMode_SubscriptionMode() +} + +// SubscriptionMode_SubscriptionMode_Assign selects Assign for SubscriptionMode.SubscriptionMode. +// A JSON string that contains the specific topic-partitions to consume from. +// For example, for '{"topicA":[0,1],"topicB":[2,4]}', topicA's 0'th and 1st +// partitions will be consumed from. +type SubscriptionMode_SubscriptionMode_Assign struct { + Assign string `fieldmask:"assign"` +} + +func (*SubscriptionMode_SubscriptionMode_Assign) isSubscriptionMode_SubscriptionMode() {} + +// SubscriptionMode_SubscriptionMode_Subscribe selects Subscribe for SubscriptionMode.SubscriptionMode. +// A comma-separated list of Kafka topics to read from. For example, +// 'topicA,topicB,topicC'. +type SubscriptionMode_SubscriptionMode_Subscribe struct { + Subscribe string `fieldmask:"subscribe"` +} + +func (*SubscriptionMode_SubscriptionMode_Subscribe) isSubscriptionMode_SubscriptionMode() {} + +// SubscriptionMode_SubscriptionMode_SubscribePattern selects SubscribePattern for SubscriptionMode.SubscriptionMode. +// A regular expression matching topics to subscribe to. For example, 'topic.*' +// will subscribe to all topics starting with 'topic'. +type SubscriptionMode_SubscriptionMode_SubscribePattern struct { + SubscribePattern string `fieldmask:"subscribe_pattern"` +} + +func (*SubscriptionMode_SubscriptionMode_SubscribePattern) isSubscriptionMode_SubscriptionMode() {} + +type subscriptionModeSubscriptionModeFieldMaskMetadata struct { + *SubscriptionMode_SubscriptionMode_Assign + *SubscriptionMode_SubscriptionMode_Subscribe + *SubscriptionMode_SubscriptionMode_SubscribePattern +} + +// Computes the sum of values.. +type SumFunction struct { + // The input column from which the sum is computed. For Kafka sources, use + // dot-prefixed path notation (e.g., "value.amount"). For nested fields, the + // leaf node name is used. Colon-prefixed notation (e.g., "value:amount") is + // supported for backwards compatibility but is deprecated; migrate to dot + // notation. + Input *string `fieldmask:"input"` +} + +// A trigger that fires when the upstream source table changes.. +type TableTrigger struct { +} + +type TimeWindow struct { + WindowType isTimeWindow_WindowType + // Earliest event-time boundary at which the Feature may emit an output. This + // gates outputs, not the historical inputs read by a window. For example, a + // 365-day window with start_time=2026-01-01 begins emitting partial-window + // values on that date instead of waiting for 365 days of data; a lifetime + // window produces no output before start_time. If unset, tumbling and + // fixed-duration sliding windows first emit at an offset-aligned boundary after + // a full window can be formed. If unset, lifetime sliding windows and rolling + // windows emit as soon as eligible source data exists. + StartTime *types.Time `fieldmask:"start_time"` + _ [0]timeWindowWindowTypeFieldMaskMetadata `fieldmask_oneof:"WindowType"` +} + +type isTimeWindow_WindowType interface { + isTimeWindow_WindowType() +} + +// TimeWindow_WindowType_Tumbling selects Tumbling for TimeWindow.WindowType. +type TimeWindow_WindowType_Tumbling struct { + Tumbling TumblingWindow `fieldmask:"tumbling"` +} + +func (*TimeWindow_WindowType_Tumbling) isTimeWindow_WindowType() {} + +// TimeWindow_WindowType_Sliding selects Sliding for TimeWindow.WindowType. +type TimeWindow_WindowType_Sliding struct { + Sliding SlidingWindow `fieldmask:"sliding"` +} + +func (*TimeWindow_WindowType_Sliding) isTimeWindow_WindowType() {} + +// TimeWindow_WindowType_Rolling selects Rolling for TimeWindow.WindowType. +type TimeWindow_WindowType_Rolling struct { + Rolling RollingWindow `fieldmask:"rolling"` +} + +func (*TimeWindow_WindowType_Rolling) isTimeWindow_WindowType() {} + +// TimeWindow_WindowType_Sawtooth selects Sawtooth for TimeWindow.WindowType. +// A sawtooth window served via the hybrid batch + streaming path. +type TimeWindow_WindowType_Sawtooth struct { + Sawtooth SawtoothWindow `fieldmask:"sawtooth"` +} + +func (*TimeWindow_WindowType_Sawtooth) isTimeWindow_WindowType() {} + +type timeWindowWindowTypeFieldMaskMetadata struct { + *TimeWindow_WindowType_Tumbling + *TimeWindow_WindowType_Sliding + *TimeWindow_WindowType_Rolling + *TimeWindow_WindowType_Sawtooth +} + +type TimeseriesColumn struct { + // The name of the timeseries column. For Kafka sources, use dot-prefixed path + // notation to reference fields within the key or value schema (e.g., + // "value.event_timestamp"). For nested fields, the leaf node name (e.g., + // "event_timestamp" from "value.event_details.event_timestamp") is what will be + // present in materialized tables and expected to match at query time. + // Colon-prefixed notation (e.g., "value:event_timestamp") is supported for + // backwards compatibility but is deprecated; migrate to dot notation. + Name *string `fieldmask:"name"` +} + +type TumblingWindow struct { + // The duration of each tumbling window (non-overlapping, fixed-duration + // windows). + WindowDuration *types.Duration `fieldmask:"window_duration"` + // Non-negative analytic lag that evaluates the window this far in the past. Use + // this for timing variations unrelated to source lateness, such as a 30-day + // count as of one week ago. If unset, the analytic lag is zero. It composes + // with source.lateness when both are set. + Delay *types.Duration `fieldmask:"delay"` + // Non-negative phase shift from the default midnight UTC alignment. For + // example, offset=22h on a 24h window produces boundaries at 22:00 UTC (17:00 + // New York in standard time) instead of midnight UTC. If unset, the offset is + // zero. Must be shorter than window_duration. + Offset *types.Duration `fieldmask:"offset"` +} + +type UpdateFeatureRequest struct { + // Feature to update. + Feature *Feature + // The list of fields to update. + UpdateMask *types.FieldMask[Feature] +} + +type UpdateKafkaConfigRequest struct { + // The Kafka config to update. + KafkaConfig *KafkaConfig + // The list of fields to update. + UpdateMask *types.FieldMask[KafkaConfig] +} + +type UpdateMaterializedFeatureRequest struct { + // The materialized feature to update. + MaterializedFeature *MaterializedFeature + // Provide the materialization feature fields which should be updated. + // Currently, only the pipeline_state field can be updated. + UpdateMask *types.FieldMask[MaterializedFeature] +} + +// Update a Stream. Only fields listed in `update_mask` are mutated.. +type UpdateStreamRequest struct { + // The Stream to update. + Stream *Stream + // The list of fields to update. + UpdateMask *types.FieldMask[Stream] +} + +// Computes the population variance.. +type VarPopFunction struct { + // The input column from which the population variance is computed. + Input *string `fieldmask:"input"` +} + +// Computes the sample variance.. +type VarSampFunction struct { + // The input column from which the sample variance is computed. + Input *string `fieldmask:"input"` +} diff --git a/features/v1/wire.go b/features/v1/wire.go new file mode 100755 index 0000000..fb1096d --- /dev/null +++ b/features/v1/wire.go @@ -0,0 +1,3642 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package features + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type aggregationFunctionWire struct { + Avg *avgFunctionWire `json:"avg,omitempty"` + CountFunction *countFunctionWire `json:"count_function,omitempty"` + Sum *sumFunctionWire `json:"sum,omitempty"` + Min *minFunctionWire `json:"min,omitempty"` + Max *maxFunctionWire `json:"max,omitempty"` + First *firstFunctionWire `json:"first,omitempty"` + Last *lastFunctionWire `json:"last,omitempty"` + ApproxCountDistinct *approxCountDistinctFunctionWire `json:"approx_count_distinct,omitempty"` + ApproxPercentile *approxPercentileFunctionWire `json:"approx_percentile,omitempty"` + StddevPop *stddevPopFunctionWire `json:"stddev_pop,omitempty"` + StddevSamp *stddevSampFunctionWire `json:"stddev_samp,omitempty"` + VarPop *varPopFunctionWire `json:"var_pop,omitempty"` + VarSamp *varSampFunctionWire `json:"var_samp,omitempty"` + FirstN *firstNFunctionWire `json:"first_n,omitempty"` + LastN *lastNFunctionWire `json:"last_n,omitempty"` + FirstDistinct *firstDistinctFunctionWire `json:"first_distinct,omitempty"` + LastDistinct *lastDistinctFunctionWire `json:"last_distinct,omitempty"` + TimeWindow *timeWindowWire `json:"time_window,omitempty"` +} + +func aggregationFunctionToWire(v *AggregationFunction) (*aggregationFunctionWire, error) { + if v == nil { + return nil, nil + } + timeWindowWireValue, err := timeWindowToWire(v.TimeWindow) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.TimeWindow", err) + } + var operationAvgWire *avgFunctionWire + var operationCountFunctionWire *countFunctionWire + var operationSumWire *sumFunctionWire + var operationMinWire *minFunctionWire + var operationMaxWire *maxFunctionWire + var operationFirstWire *firstFunctionWire + var operationLastWire *lastFunctionWire + var operationApproxCountDistinctWire *approxCountDistinctFunctionWire + var operationApproxPercentileWire *approxPercentileFunctionWire + var operationStddevPopWire *stddevPopFunctionWire + var operationStddevSampWire *stddevSampFunctionWire + var operationVarPopWire *varPopFunctionWire + var operationVarSampWire *varSampFunctionWire + var operationFirstNWire *firstNFunctionWire + var operationLastNWire *lastNFunctionWire + var operationFirstDistinctWire *firstDistinctFunctionWire + var operationLastDistinctWire *lastDistinctFunctionWire + switch value := v.Operation.(type) { + case nil: + case *AggregationFunction_Operation_Avg: + if value != nil { + operationAvgConverted, err := avgFunctionToWire(&value.Avg) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.Avg", err) + } + operationAvgWire = operationAvgConverted + } + case *AggregationFunction_Operation_CountFunction: + if value != nil { + operationCountFunctionConverted, err := countFunctionToWire(&value.CountFunction) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.CountFunction", err) + } + operationCountFunctionWire = operationCountFunctionConverted + } + case *AggregationFunction_Operation_Sum: + if value != nil { + operationSumConverted, err := sumFunctionToWire(&value.Sum) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.Sum", err) + } + operationSumWire = operationSumConverted + } + case *AggregationFunction_Operation_Min: + if value != nil { + operationMinConverted, err := minFunctionToWire(&value.Min) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.Min", err) + } + operationMinWire = operationMinConverted + } + case *AggregationFunction_Operation_Max: + if value != nil { + operationMaxConverted, err := maxFunctionToWire(&value.Max) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.Max", err) + } + operationMaxWire = operationMaxConverted + } + case *AggregationFunction_Operation_First: + if value != nil { + operationFirstConverted, err := firstFunctionToWire(&value.First) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.First", err) + } + operationFirstWire = operationFirstConverted + } + case *AggregationFunction_Operation_Last: + if value != nil { + operationLastConverted, err := lastFunctionToWire(&value.Last) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.Last", err) + } + operationLastWire = operationLastConverted + } + case *AggregationFunction_Operation_ApproxCountDistinct: + if value != nil { + operationApproxCountDistinctConverted, err := approxCountDistinctFunctionToWire(&value.ApproxCountDistinct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.ApproxCountDistinct", err) + } + operationApproxCountDistinctWire = operationApproxCountDistinctConverted + } + case *AggregationFunction_Operation_ApproxPercentile: + if value != nil { + operationApproxPercentileConverted, err := approxPercentileFunctionToWire(&value.ApproxPercentile) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.ApproxPercentile", err) + } + operationApproxPercentileWire = operationApproxPercentileConverted + } + case *AggregationFunction_Operation_StddevPop: + if value != nil { + operationStddevPopConverted, err := stddevPopFunctionToWire(&value.StddevPop) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.StddevPop", err) + } + operationStddevPopWire = operationStddevPopConverted + } + case *AggregationFunction_Operation_StddevSamp: + if value != nil { + operationStddevSampConverted, err := stddevSampFunctionToWire(&value.StddevSamp) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.StddevSamp", err) + } + operationStddevSampWire = operationStddevSampConverted + } + case *AggregationFunction_Operation_VarPop: + if value != nil { + operationVarPopConverted, err := varPopFunctionToWire(&value.VarPop) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.VarPop", err) + } + operationVarPopWire = operationVarPopConverted + } + case *AggregationFunction_Operation_VarSamp: + if value != nil { + operationVarSampConverted, err := varSampFunctionToWire(&value.VarSamp) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.VarSamp", err) + } + operationVarSampWire = operationVarSampConverted + } + case *AggregationFunction_Operation_FirstN: + if value != nil { + operationFirstNConverted, err := firstNFunctionToWire(&value.FirstN) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.FirstN", err) + } + operationFirstNWire = operationFirstNConverted + } + case *AggregationFunction_Operation_LastN: + if value != nil { + operationLastNConverted, err := lastNFunctionToWire(&value.LastN) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.LastN", err) + } + operationLastNWire = operationLastNConverted + } + case *AggregationFunction_Operation_FirstDistinct: + if value != nil { + operationFirstDistinctConverted, err := firstDistinctFunctionToWire(&value.FirstDistinct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.FirstDistinct", err) + } + operationFirstDistinctWire = operationFirstDistinctConverted + } + case *AggregationFunction_Operation_LastDistinct: + if value != nil { + operationLastDistinctConverted, err := lastDistinctFunctionToWire(&value.LastDistinct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.LastDistinct", err) + } + operationLastDistinctWire = operationLastDistinctConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AggregationFunction.Operation", value) + } + return &aggregationFunctionWire{ + Avg: operationAvgWire, + CountFunction: operationCountFunctionWire, + Sum: operationSumWire, + Min: operationMinWire, + Max: operationMaxWire, + First: operationFirstWire, + Last: operationLastWire, + ApproxCountDistinct: operationApproxCountDistinctWire, + ApproxPercentile: operationApproxPercentileWire, + StddevPop: operationStddevPopWire, + StddevSamp: operationStddevSampWire, + VarPop: operationVarPopWire, + VarSamp: operationVarSampWire, + FirstN: operationFirstNWire, + LastN: operationLastNWire, + FirstDistinct: operationFirstDistinctWire, + LastDistinct: operationLastDistinctWire, + TimeWindow: timeWindowWireValue, + }, nil +} + +func aggregationFunctionFromWire(w *aggregationFunctionWire) (*AggregationFunction, error) { + if w == nil { + return nil, nil + } + operationMembers := 0 + if w.Avg != nil { + operationMembers++ + } + if w.CountFunction != nil { + operationMembers++ + } + if w.Sum != nil { + operationMembers++ + } + if w.Min != nil { + operationMembers++ + } + if w.Max != nil { + operationMembers++ + } + if w.First != nil { + operationMembers++ + } + if w.Last != nil { + operationMembers++ + } + if w.ApproxCountDistinct != nil { + operationMembers++ + } + if w.ApproxPercentile != nil { + operationMembers++ + } + if w.StddevPop != nil { + operationMembers++ + } + if w.StddevSamp != nil { + operationMembers++ + } + if w.VarPop != nil { + operationMembers++ + } + if w.VarSamp != nil { + operationMembers++ + } + if w.FirstN != nil { + operationMembers++ + } + if w.LastN != nil { + operationMembers++ + } + if w.FirstDistinct != nil { + operationMembers++ + } + if w.LastDistinct != nil { + operationMembers++ + } + if operationMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AggregationFunction.Operation") + } + timeWindowPublicValue, err := timeWindowFromWire(w.TimeWindow) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.TimeWindow", err) + } + var operationSelection isAggregationFunction_Operation + switch { + case w.Avg != nil: + operationAvgConverted, err := avgFunctionFromWire(w.Avg) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.Avg", err) + } + operationSelection = &AggregationFunction_Operation_Avg{Avg: *operationAvgConverted} + case w.CountFunction != nil: + operationCountFunctionConverted, err := countFunctionFromWire(w.CountFunction) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.CountFunction", err) + } + operationSelection = &AggregationFunction_Operation_CountFunction{CountFunction: *operationCountFunctionConverted} + case w.Sum != nil: + operationSumConverted, err := sumFunctionFromWire(w.Sum) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.Sum", err) + } + operationSelection = &AggregationFunction_Operation_Sum{Sum: *operationSumConverted} + case w.Min != nil: + operationMinConverted, err := minFunctionFromWire(w.Min) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.Min", err) + } + operationSelection = &AggregationFunction_Operation_Min{Min: *operationMinConverted} + case w.Max != nil: + operationMaxConverted, err := maxFunctionFromWire(w.Max) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.Max", err) + } + operationSelection = &AggregationFunction_Operation_Max{Max: *operationMaxConverted} + case w.First != nil: + operationFirstConverted, err := firstFunctionFromWire(w.First) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.First", err) + } + operationSelection = &AggregationFunction_Operation_First{First: *operationFirstConverted} + case w.Last != nil: + operationLastConverted, err := lastFunctionFromWire(w.Last) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.Last", err) + } + operationSelection = &AggregationFunction_Operation_Last{Last: *operationLastConverted} + case w.ApproxCountDistinct != nil: + operationApproxCountDistinctConverted, err := approxCountDistinctFunctionFromWire(w.ApproxCountDistinct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.ApproxCountDistinct", err) + } + operationSelection = &AggregationFunction_Operation_ApproxCountDistinct{ApproxCountDistinct: *operationApproxCountDistinctConverted} + case w.ApproxPercentile != nil: + operationApproxPercentileConverted, err := approxPercentileFunctionFromWire(w.ApproxPercentile) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.ApproxPercentile", err) + } + operationSelection = &AggregationFunction_Operation_ApproxPercentile{ApproxPercentile: *operationApproxPercentileConverted} + case w.StddevPop != nil: + operationStddevPopConverted, err := stddevPopFunctionFromWire(w.StddevPop) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.StddevPop", err) + } + operationSelection = &AggregationFunction_Operation_StddevPop{StddevPop: *operationStddevPopConverted} + case w.StddevSamp != nil: + operationStddevSampConverted, err := stddevSampFunctionFromWire(w.StddevSamp) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.StddevSamp", err) + } + operationSelection = &AggregationFunction_Operation_StddevSamp{StddevSamp: *operationStddevSampConverted} + case w.VarPop != nil: + operationVarPopConverted, err := varPopFunctionFromWire(w.VarPop) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.VarPop", err) + } + operationSelection = &AggregationFunction_Operation_VarPop{VarPop: *operationVarPopConverted} + case w.VarSamp != nil: + operationVarSampConverted, err := varSampFunctionFromWire(w.VarSamp) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.VarSamp", err) + } + operationSelection = &AggregationFunction_Operation_VarSamp{VarSamp: *operationVarSampConverted} + case w.FirstN != nil: + operationFirstNConverted, err := firstNFunctionFromWire(w.FirstN) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.FirstN", err) + } + operationSelection = &AggregationFunction_Operation_FirstN{FirstN: *operationFirstNConverted} + case w.LastN != nil: + operationLastNConverted, err := lastNFunctionFromWire(w.LastN) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.LastN", err) + } + operationSelection = &AggregationFunction_Operation_LastN{LastN: *operationLastNConverted} + case w.FirstDistinct != nil: + operationFirstDistinctConverted, err := firstDistinctFunctionFromWire(w.FirstDistinct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.FirstDistinct", err) + } + operationSelection = &AggregationFunction_Operation_FirstDistinct{FirstDistinct: *operationFirstDistinctConverted} + case w.LastDistinct != nil: + operationLastDistinctConverted, err := lastDistinctFunctionFromWire(w.LastDistinct) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AggregationFunction.Operation.LastDistinct", err) + } + operationSelection = &AggregationFunction_Operation_LastDistinct{LastDistinct: *operationLastDistinctConverted} + } + return &AggregationFunction{ + TimeWindow: timeWindowPublicValue, + Operation: operationSelection, + }, nil +} + +type approxCountDistinctFunctionWire struct { + Input *string `json:"input,omitempty"` + RelativeSd *float64 `json:"relative_sd,omitempty"` +} + +func approxCountDistinctFunctionToWire(v *ApproxCountDistinctFunction) (*approxCountDistinctFunctionWire, error) { + if v == nil { + return nil, nil + } + return &approxCountDistinctFunctionWire{ + Input: v.Input, + RelativeSd: v.RelativeSd, + }, nil +} + +func approxCountDistinctFunctionFromWire(w *approxCountDistinctFunctionWire) (*ApproxCountDistinctFunction, error) { + if w == nil { + return nil, nil + } + return &ApproxCountDistinctFunction{ + Input: w.Input, + RelativeSd: w.RelativeSd, + }, nil +} + +type approxPercentileFunctionWire struct { + Input *string `json:"input,omitempty"` + Percentile *float64 `json:"percentile,omitempty"` + Accuracy *int64 `json:"accuracy,omitempty"` +} + +func approxPercentileFunctionToWire(v *ApproxPercentileFunction) (*approxPercentileFunctionWire, error) { + if v == nil { + return nil, nil + } + return &approxPercentileFunctionWire{ + Input: v.Input, + Percentile: v.Percentile, + Accuracy: v.Accuracy, + }, nil +} + +func approxPercentileFunctionFromWire(w *approxPercentileFunctionWire) (*ApproxPercentileFunction, error) { + if w == nil { + return nil, nil + } + return &ApproxPercentileFunction{ + Input: w.Input, + Percentile: w.Percentile, + Accuracy: w.Accuracy, + }, nil +} + +type authConfigWire struct { + UcServiceCredentialName *string `json:"uc_service_credential_name,omitempty"` + MtlsConfig *mtlsConfigWire `json:"mtls_config,omitempty"` +} + +func authConfigToWire(v *AuthConfig) (*authConfigWire, error) { + if v == nil { + return nil, nil + } + var authConfigUcServiceCredentialNameWire *string + var authConfigMtlsConfigWire *mtlsConfigWire + switch value := v.AuthConfig.(type) { + case nil: + case *AuthConfig_AuthConfig_UcServiceCredentialName: + if value != nil { + authConfigUcServiceCredentialNameWire = new(value.UcServiceCredentialName) + } + case *AuthConfig_AuthConfig_MtlsConfig: + if value != nil { + authConfigMtlsConfigConverted, err := mtlsConfigToWire(&value.MtlsConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AuthConfig.AuthConfig.MtlsConfig", err) + } + authConfigMtlsConfigWire = authConfigMtlsConfigConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AuthConfig.AuthConfig", value) + } + return &authConfigWire{ + UcServiceCredentialName: authConfigUcServiceCredentialNameWire, + MtlsConfig: authConfigMtlsConfigWire, + }, nil +} + +func authConfigFromWire(w *authConfigWire) (*AuthConfig, error) { + if w == nil { + return nil, nil + } + authConfigMembers := 0 + if w.UcServiceCredentialName != nil { + authConfigMembers++ + } + if w.MtlsConfig != nil { + authConfigMembers++ + } + if authConfigMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AuthConfig.AuthConfig") + } + var authConfigSelection isAuthConfig_AuthConfig + switch { + case w.UcServiceCredentialName != nil: + authConfigSelection = &AuthConfig_AuthConfig_UcServiceCredentialName{UcServiceCredentialName: *w.UcServiceCredentialName} + case w.MtlsConfig != nil: + authConfigMtlsConfigConverted, err := mtlsConfigFromWire(w.MtlsConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AuthConfig.AuthConfig.MtlsConfig", err) + } + authConfigSelection = &AuthConfig_AuthConfig_MtlsConfig{MtlsConfig: *authConfigMtlsConfigConverted} + } + return &AuthConfig{ + AuthConfig: authConfigSelection, + }, nil +} + +type avgFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func avgFunctionToWire(v *AvgFunction) (*avgFunctionWire, error) { + if v == nil { + return nil, nil + } + return &avgFunctionWire{ + Input: v.Input, + }, nil +} + +func avgFunctionFromWire(w *avgFunctionWire) (*AvgFunction, error) { + if w == nil { + return nil, nil + } + return &AvgFunction{ + Input: w.Input, + }, nil +} + +type backfillSourceWire struct { + DeltaTableSource *deltaTableSourceWire `json:"delta_table_source,omitempty"` + DeltaTableName *string `json:"delta_table_name,omitempty"` +} + +func backfillSourceToWire(v *BackfillSource) (*backfillSourceWire, error) { + if v == nil { + return nil, nil + } + var backfillSourceDeltaTableSourceWire *deltaTableSourceWire + var backfillSourceDeltaTableNameWire *string + switch value := v.BackfillSource.(type) { + case nil: + case *BackfillSource_BackfillSource_DeltaTableSource: + if value != nil { + backfillSourceDeltaTableSourceConverted, err := deltaTableSourceToWire(&value.DeltaTableSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BackfillSource.BackfillSource.DeltaTableSource", err) + } + backfillSourceDeltaTableSourceWire = backfillSourceDeltaTableSourceConverted + } + case *BackfillSource_BackfillSource_DeltaTableName: + if value != nil { + backfillSourceDeltaTableNameWire = new(value.DeltaTableName) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "BackfillSource.BackfillSource", value) + } + return &backfillSourceWire{ + DeltaTableSource: backfillSourceDeltaTableSourceWire, + DeltaTableName: backfillSourceDeltaTableNameWire, + }, nil +} + +func backfillSourceFromWire(w *backfillSourceWire) (*BackfillSource, error) { + if w == nil { + return nil, nil + } + backfillSourceMembers := 0 + if w.DeltaTableSource != nil { + backfillSourceMembers++ + } + if w.DeltaTableName != nil { + backfillSourceMembers++ + } + if backfillSourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "BackfillSource.BackfillSource") + } + var backfillSourceSelection isBackfillSource_BackfillSource + switch { + case w.DeltaTableSource != nil: + backfillSourceDeltaTableSourceConverted, err := deltaTableSourceFromWire(w.DeltaTableSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BackfillSource.BackfillSource.DeltaTableSource", err) + } + backfillSourceSelection = &BackfillSource_BackfillSource_DeltaTableSource{DeltaTableSource: *backfillSourceDeltaTableSourceConverted} + case w.DeltaTableName != nil: + backfillSourceSelection = &BackfillSource_BackfillSource_DeltaTableName{DeltaTableName: *w.DeltaTableName} + } + return &BackfillSource{ + BackfillSource: backfillSourceSelection, + }, nil +} + +type batchCreateMaterializedFeaturesRequestWire struct { + Requests []createMaterializedFeatureRequestWire `json:"requests,omitempty"` +} + +func batchCreateMaterializedFeaturesRequestToWire(v *BatchCreateMaterializedFeaturesRequest) (*batchCreateMaterializedFeaturesRequestWire, error) { + if v == nil { + return nil, nil + } + requestsWireValue, err := convertSlice(v.Requests, createMaterializedFeatureRequestToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BatchCreateMaterializedFeaturesRequest.Requests", err) + } + return &batchCreateMaterializedFeaturesRequestWire{ + Requests: requestsWireValue, + }, nil +} + +type batchCreateMaterializedFeaturesResponseWire struct { + MaterializedFeatures []materializedFeatureWire `json:"materialized_features,omitempty"` +} + +func batchCreateMaterializedFeaturesResponseFromWire(w *batchCreateMaterializedFeaturesResponseWire) (*BatchCreateMaterializedFeaturesResponse, error) { + if w == nil { + return nil, nil + } + materializedFeaturesPublicValue, err := convertSlice(w.MaterializedFeatures, materializedFeatureFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BatchCreateMaterializedFeaturesResponse.MaterializedFeatures", err) + } + return &BatchCreateMaterializedFeaturesResponse{ + MaterializedFeatures: materializedFeaturesPublicValue, + }, nil +} + +type columnSelectionWire struct { + Column *string `json:"column,omitempty"` +} + +func columnSelectionToWire(v *ColumnSelection) (*columnSelectionWire, error) { + if v == nil { + return nil, nil + } + return &columnSelectionWire{ + Column: v.Column, + }, nil +} + +func columnSelectionFromWire(w *columnSelectionWire) (*ColumnSelection, error) { + if w == nil { + return nil, nil + } + return &ColumnSelection{ + Column: w.Column, + }, nil +} + +type countFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func countFunctionToWire(v *CountFunction) (*countFunctionWire, error) { + if v == nil { + return nil, nil + } + return &countFunctionWire{ + Input: v.Input, + }, nil +} + +func countFunctionFromWire(w *countFunctionWire) (*CountFunction, error) { + if w == nil { + return nil, nil + } + return &CountFunction{ + Input: w.Input, + }, nil +} + +type createFeatureRequestWire struct { + Feature *featureWire `json:"feature,omitempty"` +} + +func createFeatureRequestToWire(v *CreateFeatureRequest) (*createFeatureRequestWire, error) { + if v == nil { + return nil, nil + } + featureWireValue, err := featureToWire(v.Feature) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateFeatureRequest.Feature", err) + } + return &createFeatureRequestWire{ + Feature: featureWireValue, + }, nil +} + +type createKafkaConfigRequestWire struct { + KafkaConfig *kafkaConfigWire `json:"kafka_config,omitempty"` +} + +func createKafkaConfigRequestToWire(v *CreateKafkaConfigRequest) (*createKafkaConfigRequestWire, error) { + if v == nil { + return nil, nil + } + kafkaConfigWireValue, err := kafkaConfigToWire(v.KafkaConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateKafkaConfigRequest.KafkaConfig", err) + } + return &createKafkaConfigRequestWire{ + KafkaConfig: kafkaConfigWireValue, + }, nil +} + +type createMaterializedFeatureRequestWire struct { + MaterializedFeature *materializedFeatureWire `json:"materialized_feature,omitempty"` +} + +func createMaterializedFeatureRequestToWire(v *CreateMaterializedFeatureRequest) (*createMaterializedFeatureRequestWire, error) { + if v == nil { + return nil, nil + } + materializedFeatureWireValue, err := materializedFeatureToWire(v.MaterializedFeature) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateMaterializedFeatureRequest.MaterializedFeature", err) + } + return &createMaterializedFeatureRequestWire{ + MaterializedFeature: materializedFeatureWireValue, + }, nil +} + +type createStreamRequestWire struct { + Stream *streamWire `json:"stream,omitempty"` +} + +func createStreamRequestToWire(v *CreateStreamRequest) (*createStreamRequestWire, error) { + if v == nil { + return nil, nil + } + streamWireValue, err := streamToWire(v.Stream) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateStreamRequest.Stream", err) + } + return &createStreamRequestWire{ + Stream: streamWireValue, + }, nil +} + +type cronScheduleWire struct { + CronExpression *string `json:"cron_expression,omitempty"` +} + +func cronScheduleToWire(v *CronSchedule) (*cronScheduleWire, error) { + if v == nil { + return nil, nil + } + return &cronScheduleWire{ + CronExpression: v.CronExpression, + }, nil +} + +func cronScheduleFromWire(w *cronScheduleWire) (*CronSchedule, error) { + if w == nil { + return nil, nil + } + return &CronSchedule{ + CronExpression: w.CronExpression, + }, nil +} + +type customUdfWire struct { + FunctionPath *string `json:"function_path,omitempty"` + InputBindings []inputBindingWire `json:"input_bindings,omitempty"` +} + +func customUdfToWire(v *CustomUdf) (*customUdfWire, error) { + if v == nil { + return nil, nil + } + inputBindingsWireValue, err := convertSlice(v.InputBindings, inputBindingToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomUdf.InputBindings", err) + } + return &customUdfWire{ + FunctionPath: v.FunctionPath, + InputBindings: inputBindingsWireValue, + }, nil +} + +func customUdfFromWire(w *customUdfWire) (*CustomUdf, error) { + if w == nil { + return nil, nil + } + inputBindingsPublicValue, err := convertSlice(w.InputBindings, inputBindingFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomUdf.InputBindings", err) + } + return &CustomUdf{ + FunctionPath: w.FunctionPath, + InputBindings: inputBindingsPublicValue, + }, nil +} + +type dataSourceWire struct { + DeltaTableSource *deltaTableSourceWire `json:"delta_table_source,omitempty"` + KafkaSource *kafkaSourceWire `json:"kafka_source,omitempty"` + RequestSource *requestSourceWire `json:"request_source,omitempty"` + StreamSource *streamSourceWire `json:"stream_source,omitempty"` + Lateness *sourceLatenessWire `json:"lateness,omitempty"` +} + +func dataSourceToWire(v *DataSource) (*dataSourceWire, error) { + if v == nil { + return nil, nil + } + latenessWireValue, err := sourceLatenessToWire(v.Lateness) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataSource.Lateness", err) + } + var dataSourceDeltaTableSourceWire *deltaTableSourceWire + var dataSourceKafkaSourceWire *kafkaSourceWire + var dataSourceRequestSourceWire *requestSourceWire + var dataSourceStreamSourceWire *streamSourceWire + switch value := v.DataSource.(type) { + case nil: + case *DataSource_DataSource_DeltaTableSource: + if value != nil { + dataSourceDeltaTableSourceConverted, err := deltaTableSourceToWire(&value.DeltaTableSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataSource.DataSource.DeltaTableSource", err) + } + dataSourceDeltaTableSourceWire = dataSourceDeltaTableSourceConverted + } + case *DataSource_DataSource_KafkaSource: + if value != nil { + dataSourceKafkaSourceConverted, err := kafkaSourceToWire(&value.KafkaSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataSource.DataSource.KafkaSource", err) + } + dataSourceKafkaSourceWire = dataSourceKafkaSourceConverted + } + case *DataSource_DataSource_RequestSource: + if value != nil { + dataSourceRequestSourceConverted, err := requestSourceToWire(&value.RequestSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataSource.DataSource.RequestSource", err) + } + dataSourceRequestSourceWire = dataSourceRequestSourceConverted + } + case *DataSource_DataSource_StreamSource: + if value != nil { + dataSourceStreamSourceConverted, err := streamSourceToWire(&value.StreamSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataSource.DataSource.StreamSource", err) + } + dataSourceStreamSourceWire = dataSourceStreamSourceConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "DataSource.DataSource", value) + } + return &dataSourceWire{ + DeltaTableSource: dataSourceDeltaTableSourceWire, + KafkaSource: dataSourceKafkaSourceWire, + RequestSource: dataSourceRequestSourceWire, + StreamSource: dataSourceStreamSourceWire, + Lateness: latenessWireValue, + }, nil +} + +func dataSourceFromWire(w *dataSourceWire) (*DataSource, error) { + if w == nil { + return nil, nil + } + dataSourceMembers := 0 + if w.DeltaTableSource != nil { + dataSourceMembers++ + } + if w.KafkaSource != nil { + dataSourceMembers++ + } + if w.RequestSource != nil { + dataSourceMembers++ + } + if w.StreamSource != nil { + dataSourceMembers++ + } + if dataSourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "DataSource.DataSource") + } + latenessPublicValue, err := sourceLatenessFromWire(w.Lateness) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataSource.Lateness", err) + } + var dataSourceSelection isDataSource_DataSource + switch { + case w.DeltaTableSource != nil: + dataSourceDeltaTableSourceConverted, err := deltaTableSourceFromWire(w.DeltaTableSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataSource.DataSource.DeltaTableSource", err) + } + dataSourceSelection = &DataSource_DataSource_DeltaTableSource{DeltaTableSource: *dataSourceDeltaTableSourceConverted} + case w.KafkaSource != nil: + dataSourceKafkaSourceConverted, err := kafkaSourceFromWire(w.KafkaSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataSource.DataSource.KafkaSource", err) + } + dataSourceSelection = &DataSource_DataSource_KafkaSource{KafkaSource: *dataSourceKafkaSourceConverted} + case w.RequestSource != nil: + dataSourceRequestSourceConverted, err := requestSourceFromWire(w.RequestSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataSource.DataSource.RequestSource", err) + } + dataSourceSelection = &DataSource_DataSource_RequestSource{RequestSource: *dataSourceRequestSourceConverted} + case w.StreamSource != nil: + dataSourceStreamSourceConverted, err := streamSourceFromWire(w.StreamSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataSource.DataSource.StreamSource", err) + } + dataSourceSelection = &DataSource_DataSource_StreamSource{StreamSource: *dataSourceStreamSourceConverted} + } + return &DataSource{ + Lateness: latenessPublicValue, + DataSource: dataSourceSelection, + }, nil +} + +type deltaTableSourceWire struct { + FullName *string `json:"full_name,omitempty"` + FilterCondition *string `json:"filter_condition,omitempty"` + TransformationSql *string `json:"transformation_sql,omitempty"` + DataframeSchema *string `json:"dataframe_schema,omitempty"` +} + +func deltaTableSourceToWire(v *DeltaTableSource) (*deltaTableSourceWire, error) { + if v == nil { + return nil, nil + } + return &deltaTableSourceWire{ + FullName: v.FullName, + FilterCondition: v.FilterCondition, + TransformationSql: v.TransformationSql, + DataframeSchema: v.DataframeSchema, + }, nil +} + +func deltaTableSourceFromWire(w *deltaTableSourceWire) (*DeltaTableSource, error) { + if w == nil { + return nil, nil + } + return &DeltaTableSource{ + FullName: w.FullName, + FilterCondition: w.FilterCondition, + TransformationSql: w.TransformationSql, + DataframeSchema: w.DataframeSchema, + }, nil +} + +type directMtlsConfigWire struct { + BootstrapServers *string `json:"bootstrap_servers,omitempty"` + MtlsConfig *mtlsConfigWire `json:"mtls_config,omitempty"` +} + +func directMtlsConfigToWire(v *DirectMtlsConfig) (*directMtlsConfigWire, error) { + if v == nil { + return nil, nil + } + mtlsConfigWireValue, err := mtlsConfigToWire(v.MtlsConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DirectMtlsConfig.MtlsConfig", err) + } + return &directMtlsConfigWire{ + BootstrapServers: v.BootstrapServers, + MtlsConfig: mtlsConfigWireValue, + }, nil +} + +func directMtlsConfigFromWire(w *directMtlsConfigWire) (*DirectMtlsConfig, error) { + if w == nil { + return nil, nil + } + mtlsConfigPublicValue, err := mtlsConfigFromWire(w.MtlsConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DirectMtlsConfig.MtlsConfig", err) + } + return &DirectMtlsConfig{ + BootstrapServers: w.BootstrapServers, + MtlsConfig: mtlsConfigPublicValue, + }, nil +} + +type directSchemasWire struct { + PayloadSchema *schemaConfigWire `json:"payload_schema,omitempty"` + KeySchema *schemaConfigWire `json:"key_schema,omitempty"` +} + +func directSchemasToWire(v *DirectSchemas) (*directSchemasWire, error) { + if v == nil { + return nil, nil + } + payloadSchemaWireValue, err := schemaConfigToWire(v.PayloadSchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DirectSchemas.PayloadSchema", err) + } + keySchemaWireValue, err := schemaConfigToWire(v.KeySchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DirectSchemas.KeySchema", err) + } + return &directSchemasWire{ + PayloadSchema: payloadSchemaWireValue, + KeySchema: keySchemaWireValue, + }, nil +} + +func directSchemasFromWire(w *directSchemasWire) (*DirectSchemas, error) { + if w == nil { + return nil, nil + } + payloadSchemaPublicValue, err := schemaConfigFromWire(w.PayloadSchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DirectSchemas.PayloadSchema", err) + } + keySchemaPublicValue, err := schemaConfigFromWire(w.KeySchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DirectSchemas.KeySchema", err) + } + return &DirectSchemas{ + PayloadSchema: payloadSchemaPublicValue, + KeySchema: keySchemaPublicValue, + }, nil +} + +type entityColumnWire struct { + Name *string `json:"name,omitempty"` +} + +func entityColumnToWire(v *EntityColumn) (*entityColumnWire, error) { + if v == nil { + return nil, nil + } + return &entityColumnWire{ + Name: v.Name, + }, nil +} + +func entityColumnFromWire(w *entityColumnWire) (*EntityColumn, error) { + if w == nil { + return nil, nil + } + return &EntityColumn{ + Name: w.Name, + }, nil +} + +type featureWire struct { + FullName *string `json:"full_name,omitempty"` + Source *dataSourceWire `json:"source,omitempty"` + Function *functionWire `json:"function,omitempty"` + Description *string `json:"description,omitempty"` + LineageContext *lineageContextWire `json:"lineage_context,omitempty"` + Entities []entityColumnWire `json:"entities,omitempty"` + TimeseriesColumn *timeseriesColumnWire `json:"timeseries_column,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + Name *string `json:"name,omitempty"` + CreatedAt *types.Time `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` +} + +func featureToWire(v *Feature) (*featureWire, error) { + if v == nil { + return nil, nil + } + sourceWireValue, err := dataSourceToWire(v.Source) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Feature.Source", err) + } + functionWireValue, err := functionToWire(v.Function) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Feature.Function", err) + } + lineageContextWireValue, err := lineageContextToWire(v.LineageContext) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Feature.LineageContext", err) + } + entitiesWireValue, err := convertSlice(v.Entities, entityColumnToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Feature.Entities", err) + } + timeseriesColumnWireValue, err := timeseriesColumnToWire(v.TimeseriesColumn) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Feature.TimeseriesColumn", err) + } + return &featureWire{ + FullName: v.FullName, + Source: sourceWireValue, + Function: functionWireValue, + Description: v.Description, + LineageContext: lineageContextWireValue, + Entities: entitiesWireValue, + TimeseriesColumn: timeseriesColumnWireValue, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + Name: v.Name, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + }, nil +} + +func featureFromWire(w *featureWire) (*Feature, error) { + if w == nil { + return nil, nil + } + sourcePublicValue, err := dataSourceFromWire(w.Source) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Feature.Source", err) + } + functionPublicValue, err := functionFromWire(w.Function) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Feature.Function", err) + } + lineageContextPublicValue, err := lineageContextFromWire(w.LineageContext) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Feature.LineageContext", err) + } + entitiesPublicValue, err := convertSlice(w.Entities, entityColumnFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Feature.Entities", err) + } + timeseriesColumnPublicValue, err := timeseriesColumnFromWire(w.TimeseriesColumn) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Feature.TimeseriesColumn", err) + } + return &Feature{ + FullName: w.FullName, + Source: sourcePublicValue, + Function: functionPublicValue, + Description: w.Description, + LineageContext: lineageContextPublicValue, + Entities: entitiesPublicValue, + TimeseriesColumn: timeseriesColumnPublicValue, + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + Name: w.Name, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + }, nil +} + +type fieldDefinitionWire struct { + Name *string `json:"name,omitempty"` + DataType ScalarDataType `json:"data_type,omitempty"` +} + +func fieldDefinitionToWire(v *FieldDefinition) (*fieldDefinitionWire, error) { + if v == nil { + return nil, nil + } + return &fieldDefinitionWire{ + Name: v.Name, + DataType: v.DataType, + }, nil +} + +func fieldDefinitionFromWire(w *fieldDefinitionWire) (*FieldDefinition, error) { + if w == nil { + return nil, nil + } + return &FieldDefinition{ + Name: w.Name, + DataType: w.DataType, + }, nil +} + +type firstDistinctFunctionWire struct { + Input *string `json:"input,omitempty"` + N *int64 `json:"n,omitempty"` +} + +func firstDistinctFunctionToWire(v *FirstDistinctFunction) (*firstDistinctFunctionWire, error) { + if v == nil { + return nil, nil + } + return &firstDistinctFunctionWire{ + Input: v.Input, + N: v.N, + }, nil +} + +func firstDistinctFunctionFromWire(w *firstDistinctFunctionWire) (*FirstDistinctFunction, error) { + if w == nil { + return nil, nil + } + return &FirstDistinctFunction{ + Input: w.Input, + N: w.N, + }, nil +} + +type firstFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func firstFunctionToWire(v *FirstFunction) (*firstFunctionWire, error) { + if v == nil { + return nil, nil + } + return &firstFunctionWire{ + Input: v.Input, + }, nil +} + +func firstFunctionFromWire(w *firstFunctionWire) (*FirstFunction, error) { + if w == nil { + return nil, nil + } + return &FirstFunction{ + Input: w.Input, + }, nil +} + +type firstNFunctionWire struct { + Input *string `json:"input,omitempty"` + N *int64 `json:"n,omitempty"` +} + +func firstNFunctionToWire(v *FirstNFunction) (*firstNFunctionWire, error) { + if v == nil { + return nil, nil + } + return &firstNFunctionWire{ + Input: v.Input, + N: v.N, + }, nil +} + +func firstNFunctionFromWire(w *firstNFunctionWire) (*FirstNFunction, error) { + if w == nil { + return nil, nil + } + return &FirstNFunction{ + Input: w.Input, + N: w.N, + }, nil +} + +type flatSchemaWire struct { + Fields []fieldDefinitionWire `json:"fields,omitempty"` +} + +func flatSchemaToWire(v *FlatSchema) (*flatSchemaWire, error) { + if v == nil { + return nil, nil + } + fieldsWireValue, err := convertSlice(v.Fields, fieldDefinitionToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FlatSchema.Fields", err) + } + return &flatSchemaWire{ + Fields: fieldsWireValue, + }, nil +} + +func flatSchemaFromWire(w *flatSchemaWire) (*FlatSchema, error) { + if w == nil { + return nil, nil + } + fieldsPublicValue, err := convertSlice(w.Fields, fieldDefinitionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FlatSchema.Fields", err) + } + return &FlatSchema{ + Fields: fieldsPublicValue, + }, nil +} + +type functionWire struct { + AggregationFunction *aggregationFunctionWire `json:"aggregation_function,omitempty"` + ColumnSelection *columnSelectionWire `json:"column_selection,omitempty"` + CustomUdf *customUdfWire `json:"custom_udf,omitempty"` +} + +func functionToWire(v *Function) (*functionWire, error) { + if v == nil { + return nil, nil + } + var functionAggregationFunctionWire *aggregationFunctionWire + var functionColumnSelectionWire *columnSelectionWire + var functionCustomUdfWire *customUdfWire + switch value := v.Function.(type) { + case nil: + case *Function_Function_AggregationFunction: + if value != nil { + functionAggregationFunctionConverted, err := aggregationFunctionToWire(&value.AggregationFunction) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Function.Function.AggregationFunction", err) + } + functionAggregationFunctionWire = functionAggregationFunctionConverted + } + case *Function_Function_ColumnSelection: + if value != nil { + functionColumnSelectionConverted, err := columnSelectionToWire(&value.ColumnSelection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Function.Function.ColumnSelection", err) + } + functionColumnSelectionWire = functionColumnSelectionConverted + } + case *Function_Function_CustomUdf: + if value != nil { + functionCustomUdfConverted, err := customUdfToWire(&value.CustomUdf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Function.Function.CustomUdf", err) + } + functionCustomUdfWire = functionCustomUdfConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Function.Function", value) + } + return &functionWire{ + AggregationFunction: functionAggregationFunctionWire, + ColumnSelection: functionColumnSelectionWire, + CustomUdf: functionCustomUdfWire, + }, nil +} + +func functionFromWire(w *functionWire) (*Function, error) { + if w == nil { + return nil, nil + } + functionMembers := 0 + if w.AggregationFunction != nil { + functionMembers++ + } + if w.ColumnSelection != nil { + functionMembers++ + } + if w.CustomUdf != nil { + functionMembers++ + } + if functionMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Function.Function") + } + var functionSelection isFunction_Function + switch { + case w.AggregationFunction != nil: + functionAggregationFunctionConverted, err := aggregationFunctionFromWire(w.AggregationFunction) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Function.Function.AggregationFunction", err) + } + functionSelection = &Function_Function_AggregationFunction{AggregationFunction: *functionAggregationFunctionConverted} + case w.ColumnSelection != nil: + functionColumnSelectionConverted, err := columnSelectionFromWire(w.ColumnSelection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Function.Function.ColumnSelection", err) + } + functionSelection = &Function_Function_ColumnSelection{ColumnSelection: *functionColumnSelectionConverted} + case w.CustomUdf != nil: + functionCustomUdfConverted, err := customUdfFromWire(w.CustomUdf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Function.Function.CustomUdf", err) + } + functionSelection = &Function_Function_CustomUdf{CustomUdf: *functionCustomUdfConverted} + } + return &Function{ + Function: functionSelection, + }, nil +} + +type ingestionConfigWire struct { + IngestionDestination *ingestionDestinationWire `json:"ingestion_destination,omitempty"` + BackfillSource *backfillSourceWire `json:"backfill_source,omitempty"` + DeduplicationColumns []string `json:"deduplication_columns,omitempty"` + IngestionPipelineId *string `json:"ingestion_pipeline_id,omitempty"` + IngestionJobId *int64 `json:"ingestion_job_id,omitempty"` + BackfillJobId *int64 `json:"backfill_job_id,omitempty"` +} + +func ingestionConfigToWire(v *IngestionConfig) (*ingestionConfigWire, error) { + if v == nil { + return nil, nil + } + ingestionDestinationWireValue, err := ingestionDestinationToWire(v.IngestionDestination) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionConfig.IngestionDestination", err) + } + backfillSourceWireValue, err := backfillSourceToWire(v.BackfillSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionConfig.BackfillSource", err) + } + return &ingestionConfigWire{ + IngestionDestination: ingestionDestinationWireValue, + BackfillSource: backfillSourceWireValue, + DeduplicationColumns: v.DeduplicationColumns, + IngestionPipelineId: v.IngestionPipelineId, + IngestionJobId: v.IngestionJobId, + BackfillJobId: v.BackfillJobId, + }, nil +} + +func ingestionConfigFromWire(w *ingestionConfigWire) (*IngestionConfig, error) { + if w == nil { + return nil, nil + } + ingestionDestinationPublicValue, err := ingestionDestinationFromWire(w.IngestionDestination) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionConfig.IngestionDestination", err) + } + backfillSourcePublicValue, err := backfillSourceFromWire(w.BackfillSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionConfig.BackfillSource", err) + } + return &IngestionConfig{ + IngestionDestination: ingestionDestinationPublicValue, + BackfillSource: backfillSourcePublicValue, + DeduplicationColumns: w.DeduplicationColumns, + IngestionPipelineId: w.IngestionPipelineId, + IngestionJobId: w.IngestionJobId, + BackfillJobId: w.BackfillJobId, + }, nil +} + +type ingestionDestinationWire struct { + DeltaTableName *string `json:"delta_table_name,omitempty"` +} + +func ingestionDestinationToWire(v *IngestionDestination) (*ingestionDestinationWire, error) { + if v == nil { + return nil, nil + } + var ingestionDestinationDeltaTableNameWire *string + switch value := v.IngestionDestination.(type) { + case nil: + case *IngestionDestination_IngestionDestination_DeltaTableName: + if value != nil { + ingestionDestinationDeltaTableNameWire = new(value.DeltaTableName) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "IngestionDestination.IngestionDestination", value) + } + return &ingestionDestinationWire{ + DeltaTableName: ingestionDestinationDeltaTableNameWire, + }, nil +} + +func ingestionDestinationFromWire(w *ingestionDestinationWire) (*IngestionDestination, error) { + if w == nil { + return nil, nil + } + ingestionDestinationMembers := 0 + if w.DeltaTableName != nil { + ingestionDestinationMembers++ + } + if ingestionDestinationMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "IngestionDestination.IngestionDestination") + } + var ingestionDestinationSelection isIngestionDestination_IngestionDestination + switch { + case w.DeltaTableName != nil: + ingestionDestinationSelection = &IngestionDestination_IngestionDestination_DeltaTableName{DeltaTableName: *w.DeltaTableName} + } + return &IngestionDestination{ + IngestionDestination: ingestionDestinationSelection, + }, nil +} + +type inputBindingWire struct { + Parameter *string `json:"parameter,omitempty"` + Column *string `json:"column,omitempty"` +} + +func inputBindingToWire(v *InputBinding) (*inputBindingWire, error) { + if v == nil { + return nil, nil + } + return &inputBindingWire{ + Parameter: v.Parameter, + Column: v.Column, + }, nil +} + +func inputBindingFromWire(w *inputBindingWire) (*InputBinding, error) { + if w == nil { + return nil, nil + } + return &InputBinding{ + Parameter: w.Parameter, + Column: w.Column, + }, nil +} + +type jobContextWire struct { + JobId *int64 `json:"job_id,omitempty"` + JobRunId *int64 `json:"job_run_id,omitempty"` +} + +func jobContextToWire(v *JobContext) (*jobContextWire, error) { + if v == nil { + return nil, nil + } + return &jobContextWire{ + JobId: v.JobId, + JobRunId: v.JobRunId, + }, nil +} + +func jobContextFromWire(w *jobContextWire) (*JobContext, error) { + if w == nil { + return nil, nil + } + return &JobContext{ + JobId: w.JobId, + JobRunId: w.JobRunId, + }, nil +} + +type kafkaConfigWire struct { + Name *string `json:"name,omitempty"` + BootstrapServers *string `json:"bootstrap_servers,omitempty"` + SubscriptionMode *subscriptionModeWire `json:"subscription_mode,omitempty"` + AuthConfig *authConfigWire `json:"auth_config,omitempty"` + KeySchema *schemaConfigWire `json:"key_schema,omitempty"` + ValueSchema *schemaConfigWire `json:"value_schema,omitempty"` + ExtraOptions map[string]string `json:"extra_options,omitempty"` + BackfillSource *backfillSourceWire `json:"backfill_source,omitempty"` + IngestionConfig *ingestionConfigWire `json:"ingestion_config,omitempty"` +} + +func kafkaConfigToWire(v *KafkaConfig) (*kafkaConfigWire, error) { + if v == nil { + return nil, nil + } + subscriptionModeWireValue, err := subscriptionModeToWire(v.SubscriptionMode) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.SubscriptionMode", err) + } + authConfigWireValue, err := authConfigToWire(v.AuthConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.AuthConfig", err) + } + keySchemaWireValue, err := schemaConfigToWire(v.KeySchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.KeySchema", err) + } + valueSchemaWireValue, err := schemaConfigToWire(v.ValueSchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.ValueSchema", err) + } + backfillSourceWireValue, err := backfillSourceToWire(v.BackfillSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.BackfillSource", err) + } + ingestionConfigWireValue, err := ingestionConfigToWire(v.IngestionConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.IngestionConfig", err) + } + return &kafkaConfigWire{ + Name: v.Name, + BootstrapServers: v.BootstrapServers, + SubscriptionMode: subscriptionModeWireValue, + AuthConfig: authConfigWireValue, + KeySchema: keySchemaWireValue, + ValueSchema: valueSchemaWireValue, + ExtraOptions: v.ExtraOptions, + BackfillSource: backfillSourceWireValue, + IngestionConfig: ingestionConfigWireValue, + }, nil +} + +func kafkaConfigFromWire(w *kafkaConfigWire) (*KafkaConfig, error) { + if w == nil { + return nil, nil + } + subscriptionModePublicValue, err := subscriptionModeFromWire(w.SubscriptionMode) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.SubscriptionMode", err) + } + authConfigPublicValue, err := authConfigFromWire(w.AuthConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.AuthConfig", err) + } + keySchemaPublicValue, err := schemaConfigFromWire(w.KeySchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.KeySchema", err) + } + valueSchemaPublicValue, err := schemaConfigFromWire(w.ValueSchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.ValueSchema", err) + } + backfillSourcePublicValue, err := backfillSourceFromWire(w.BackfillSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.BackfillSource", err) + } + ingestionConfigPublicValue, err := ingestionConfigFromWire(w.IngestionConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaConfig.IngestionConfig", err) + } + return &KafkaConfig{ + Name: w.Name, + BootstrapServers: w.BootstrapServers, + SubscriptionMode: subscriptionModePublicValue, + AuthConfig: authConfigPublicValue, + KeySchema: keySchemaPublicValue, + ValueSchema: valueSchemaPublicValue, + ExtraOptions: w.ExtraOptions, + BackfillSource: backfillSourcePublicValue, + IngestionConfig: ingestionConfigPublicValue, + }, nil +} + +type kafkaSourceWire struct { + Name *string `json:"name,omitempty"` + FilterCondition *string `json:"filter_condition,omitempty"` +} + +func kafkaSourceToWire(v *KafkaSource) (*kafkaSourceWire, error) { + if v == nil { + return nil, nil + } + return &kafkaSourceWire{ + Name: v.Name, + FilterCondition: v.FilterCondition, + }, nil +} + +func kafkaSourceFromWire(w *kafkaSourceWire) (*KafkaSource, error) { + if w == nil { + return nil, nil + } + return &KafkaSource{ + Name: w.Name, + FilterCondition: w.FilterCondition, + }, nil +} + +type kafkaStreamConfigWire struct { + SubscriptionMode *kafkaSubscriptionModeWire `json:"subscription_mode,omitempty"` + ExtraOptions map[string]string `json:"extra_options,omitempty"` +} + +func kafkaStreamConfigToWire(v *KafkaStreamConfig) (*kafkaStreamConfigWire, error) { + if v == nil { + return nil, nil + } + subscriptionModeWireValue, err := kafkaSubscriptionModeToWire(v.SubscriptionMode) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaStreamConfig.SubscriptionMode", err) + } + return &kafkaStreamConfigWire{ + SubscriptionMode: subscriptionModeWireValue, + ExtraOptions: v.ExtraOptions, + }, nil +} + +func kafkaStreamConfigFromWire(w *kafkaStreamConfigWire) (*KafkaStreamConfig, error) { + if w == nil { + return nil, nil + } + subscriptionModePublicValue, err := kafkaSubscriptionModeFromWire(w.SubscriptionMode) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaStreamConfig.SubscriptionMode", err) + } + return &KafkaStreamConfig{ + SubscriptionMode: subscriptionModePublicValue, + ExtraOptions: w.ExtraOptions, + }, nil +} + +type kafkaSubscriptionModeWire struct { + Assign *string `json:"assign,omitempty"` + Subscribe *string `json:"subscribe,omitempty"` + SubscribePattern *string `json:"subscribe_pattern,omitempty"` +} + +func kafkaSubscriptionModeToWire(v *KafkaSubscriptionMode) (*kafkaSubscriptionModeWire, error) { + if v == nil { + return nil, nil + } + var subscriptionModeAssignWire *string + var subscriptionModeSubscribeWire *string + var subscriptionModeSubscribePatternWire *string + switch value := v.SubscriptionMode.(type) { + case nil: + case *KafkaSubscriptionMode_SubscriptionMode_Assign: + if value != nil { + subscriptionModeAssignWire = new(value.Assign) + } + case *KafkaSubscriptionMode_SubscriptionMode_Subscribe: + if value != nil { + subscriptionModeSubscribeWire = new(value.Subscribe) + } + case *KafkaSubscriptionMode_SubscriptionMode_SubscribePattern: + if value != nil { + subscriptionModeSubscribePatternWire = new(value.SubscribePattern) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "KafkaSubscriptionMode.SubscriptionMode", value) + } + return &kafkaSubscriptionModeWire{ + Assign: subscriptionModeAssignWire, + Subscribe: subscriptionModeSubscribeWire, + SubscribePattern: subscriptionModeSubscribePatternWire, + }, nil +} + +func kafkaSubscriptionModeFromWire(w *kafkaSubscriptionModeWire) (*KafkaSubscriptionMode, error) { + if w == nil { + return nil, nil + } + subscriptionModeMembers := 0 + if w.Assign != nil { + subscriptionModeMembers++ + } + if w.Subscribe != nil { + subscriptionModeMembers++ + } + if w.SubscribePattern != nil { + subscriptionModeMembers++ + } + if subscriptionModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "KafkaSubscriptionMode.SubscriptionMode") + } + var subscriptionModeSelection isKafkaSubscriptionMode_SubscriptionMode + switch { + case w.Assign != nil: + subscriptionModeSelection = &KafkaSubscriptionMode_SubscriptionMode_Assign{Assign: *w.Assign} + case w.Subscribe != nil: + subscriptionModeSelection = &KafkaSubscriptionMode_SubscriptionMode_Subscribe{Subscribe: *w.Subscribe} + case w.SubscribePattern != nil: + subscriptionModeSelection = &KafkaSubscriptionMode_SubscriptionMode_SubscribePattern{SubscribePattern: *w.SubscribePattern} + } + return &KafkaSubscriptionMode{ + SubscriptionMode: subscriptionModeSelection, + }, nil +} + +type kinesisStreamConfigWire struct { + StreamNames *streamNameListWire `json:"stream_names,omitempty"` + StreamArns *streamArnListWire `json:"stream_arns,omitempty"` + ExtraOptions map[string]string `json:"extra_options,omitempty"` +} + +func kinesisStreamConfigToWire(v *KinesisStreamConfig) (*kinesisStreamConfigWire, error) { + if v == nil { + return nil, nil + } + var streamIdentifierStreamNamesWire *streamNameListWire + var streamIdentifierStreamArnsWire *streamArnListWire + switch value := v.StreamIdentifier.(type) { + case nil: + case *KinesisStreamConfig_StreamIdentifier_StreamNames: + if value != nil { + streamIdentifierStreamNamesConverted, err := streamNameListToWire(&value.StreamNames) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KinesisStreamConfig.StreamIdentifier.StreamNames", err) + } + streamIdentifierStreamNamesWire = streamIdentifierStreamNamesConverted + } + case *KinesisStreamConfig_StreamIdentifier_StreamArns: + if value != nil { + streamIdentifierStreamArnsConverted, err := streamArnListToWire(&value.StreamArns) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KinesisStreamConfig.StreamIdentifier.StreamArns", err) + } + streamIdentifierStreamArnsWire = streamIdentifierStreamArnsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "KinesisStreamConfig.StreamIdentifier", value) + } + return &kinesisStreamConfigWire{ + StreamNames: streamIdentifierStreamNamesWire, + StreamArns: streamIdentifierStreamArnsWire, + ExtraOptions: v.ExtraOptions, + }, nil +} + +func kinesisStreamConfigFromWire(w *kinesisStreamConfigWire) (*KinesisStreamConfig, error) { + if w == nil { + return nil, nil + } + streamIdentifierMembers := 0 + if w.StreamNames != nil { + streamIdentifierMembers++ + } + if w.StreamArns != nil { + streamIdentifierMembers++ + } + if streamIdentifierMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "KinesisStreamConfig.StreamIdentifier") + } + var streamIdentifierSelection isKinesisStreamConfig_StreamIdentifier + switch { + case w.StreamNames != nil: + streamIdentifierStreamNamesConverted, err := streamNameListFromWire(w.StreamNames) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KinesisStreamConfig.StreamIdentifier.StreamNames", err) + } + streamIdentifierSelection = &KinesisStreamConfig_StreamIdentifier_StreamNames{StreamNames: *streamIdentifierStreamNamesConverted} + case w.StreamArns != nil: + streamIdentifierStreamArnsConverted, err := streamArnListFromWire(w.StreamArns) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KinesisStreamConfig.StreamIdentifier.StreamArns", err) + } + streamIdentifierSelection = &KinesisStreamConfig_StreamIdentifier_StreamArns{StreamArns: *streamIdentifierStreamArnsConverted} + } + return &KinesisStreamConfig{ + ExtraOptions: w.ExtraOptions, + StreamIdentifier: streamIdentifierSelection, + }, nil +} + +type lastDistinctFunctionWire struct { + Input *string `json:"input,omitempty"` + N *int64 `json:"n,omitempty"` +} + +func lastDistinctFunctionToWire(v *LastDistinctFunction) (*lastDistinctFunctionWire, error) { + if v == nil { + return nil, nil + } + return &lastDistinctFunctionWire{ + Input: v.Input, + N: v.N, + }, nil +} + +func lastDistinctFunctionFromWire(w *lastDistinctFunctionWire) (*LastDistinctFunction, error) { + if w == nil { + return nil, nil + } + return &LastDistinctFunction{ + Input: w.Input, + N: w.N, + }, nil +} + +type lastFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func lastFunctionToWire(v *LastFunction) (*lastFunctionWire, error) { + if v == nil { + return nil, nil + } + return &lastFunctionWire{ + Input: v.Input, + }, nil +} + +func lastFunctionFromWire(w *lastFunctionWire) (*LastFunction, error) { + if w == nil { + return nil, nil + } + return &LastFunction{ + Input: w.Input, + }, nil +} + +type lastNFunctionWire struct { + Input *string `json:"input,omitempty"` + N *int64 `json:"n,omitempty"` +} + +func lastNFunctionToWire(v *LastNFunction) (*lastNFunctionWire, error) { + if v == nil { + return nil, nil + } + return &lastNFunctionWire{ + Input: v.Input, + N: v.N, + }, nil +} + +func lastNFunctionFromWire(w *lastNFunctionWire) (*LastNFunction, error) { + if w == nil { + return nil, nil + } + return &LastNFunction{ + Input: w.Input, + N: w.N, + }, nil +} + +type lineageContextWire struct { + NotebookId *int64 `json:"notebook_id,omitempty"` + JobContext *jobContextWire `json:"job_context,omitempty"` +} + +func lineageContextToWire(v *LineageContext) (*lineageContextWire, error) { + if v == nil { + return nil, nil + } + jobContextWireValue, err := jobContextToWire(v.JobContext) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LineageContext.JobContext", err) + } + return &lineageContextWire{ + NotebookId: v.NotebookId, + JobContext: jobContextWireValue, + }, nil +} + +func lineageContextFromWire(w *lineageContextWire) (*LineageContext, error) { + if w == nil { + return nil, nil + } + jobContextPublicValue, err := jobContextFromWire(w.JobContext) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LineageContext.JobContext", err) + } + return &LineageContext{ + NotebookId: w.NotebookId, + JobContext: jobContextPublicValue, + }, nil +} + +type listFeaturesRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` +} + +func listFeaturesRequestToWire(v *ListFeaturesRequest) (*listFeaturesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listFeaturesRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + }, nil +} + +type listFeaturesResponseWire struct { + Features []featureWire `json:"features,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listFeaturesResponseFromWire(w *listFeaturesResponseWire) (*ListFeaturesResponse, error) { + if w == nil { + return nil, nil + } + featuresPublicValue, err := convertSlice(w.Features, featureFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListFeaturesResponse.Features", err) + } + return &ListFeaturesResponse{ + Features: featuresPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listKafkaConfigsRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listKafkaConfigsRequestToWire(v *ListKafkaConfigsRequest) (*listKafkaConfigsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listKafkaConfigsRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listKafkaConfigsResponseWire struct { + KafkaConfigs []kafkaConfigWire `json:"kafka_configs,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listKafkaConfigsResponseFromWire(w *listKafkaConfigsResponseWire) (*ListKafkaConfigsResponse, error) { + if w == nil { + return nil, nil + } + kafkaConfigsPublicValue, err := convertSlice(w.KafkaConfigs, kafkaConfigFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListKafkaConfigsResponse.KafkaConfigs", err) + } + return &ListKafkaConfigsResponse{ + KafkaConfigs: kafkaConfigsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listMaterializedFeaturesRequestWire struct { + FeatureName *string `json:"feature_name,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listMaterializedFeaturesRequestToWire(v *ListMaterializedFeaturesRequest) (*listMaterializedFeaturesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listMaterializedFeaturesRequestWire{ + FeatureName: v.FeatureName, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listMaterializedFeaturesResponseWire struct { + MaterializedFeatures []materializedFeatureWire `json:"materialized_features,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listMaterializedFeaturesResponseFromWire(w *listMaterializedFeaturesResponseWire) (*ListMaterializedFeaturesResponse, error) { + if w == nil { + return nil, nil + } + materializedFeaturesPublicValue, err := convertSlice(w.MaterializedFeatures, materializedFeatureFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListMaterializedFeaturesResponse.MaterializedFeatures", err) + } + return &ListMaterializedFeaturesResponse{ + MaterializedFeatures: materializedFeaturesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listStreamsRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listStreamsRequestToWire(v *ListStreamsRequest) (*listStreamsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listStreamsRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listStreamsResponseWire struct { + Streams []streamWire `json:"streams,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listStreamsResponseFromWire(w *listStreamsResponseWire) (*ListStreamsResponse, error) { + if w == nil { + return nil, nil + } + streamsPublicValue, err := convertSlice(w.Streams, streamFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListStreamsResponse.Streams", err) + } + return &ListStreamsResponse{ + Streams: streamsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type materializedFeatureWire struct { + MaterializedFeatureId *string `json:"materialized_feature_id,omitempty"` + FeatureName *string `json:"feature_name,omitempty"` + OfflineStoreConfig *offlineStoreConfigWire `json:"offline_store_config,omitempty"` + OnlineStoreConfig *onlineStoreConfigWire `json:"online_store_config,omitempty"` + TableName *string `json:"table_name,omitempty"` + PipelineScheduleState MaterializedFeature_PipelineScheduleState `json:"pipeline_schedule_state,omitempty"` + LastMaterializationTime *types.Time `json:"last_materialization_time,omitempty"` + IsOnline *bool `json:"is_online,omitempty"` + CronScheduleTrigger *cronScheduleWire `json:"cron_schedule_trigger,omitempty"` + TableTrigger *tableTriggerWire `json:"table_trigger,omitempty"` + StreamingMode *streamingModeWire `json:"streaming_mode,omitempty"` +} + +func materializedFeatureToWire(v *MaterializedFeature) (*materializedFeatureWire, error) { + if v == nil { + return nil, nil + } + var destinationOfflineStoreConfigWire *offlineStoreConfigWire + var destinationOnlineStoreConfigWire *onlineStoreConfigWire + switch value := v.Destination.(type) { + case nil: + case *MaterializedFeature_Destination_OfflineStoreConfig: + if value != nil { + destinationOfflineStoreConfigConverted, err := offlineStoreConfigToWire(&value.OfflineStoreConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MaterializedFeature.Destination.OfflineStoreConfig", err) + } + destinationOfflineStoreConfigWire = destinationOfflineStoreConfigConverted + } + case *MaterializedFeature_Destination_OnlineStoreConfig: + if value != nil { + destinationOnlineStoreConfigConverted, err := onlineStoreConfigToWire(&value.OnlineStoreConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MaterializedFeature.Destination.OnlineStoreConfig", err) + } + destinationOnlineStoreConfigWire = destinationOnlineStoreConfigConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "MaterializedFeature.Destination", value) + } + var triggerCronScheduleTriggerWire *cronScheduleWire + var triggerTableTriggerWire *tableTriggerWire + var triggerStreamingModeWire *streamingModeWire + switch value := v.Trigger.(type) { + case nil: + case *MaterializedFeature_Trigger_CronScheduleTrigger: + if value != nil { + triggerCronScheduleTriggerConverted, err := cronScheduleToWire(&value.CronScheduleTrigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MaterializedFeature.Trigger.CronScheduleTrigger", err) + } + triggerCronScheduleTriggerWire = triggerCronScheduleTriggerConverted + } + case *MaterializedFeature_Trigger_TableTrigger: + if value != nil { + triggerTableTriggerConverted, err := tableTriggerToWire(&value.TableTrigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MaterializedFeature.Trigger.TableTrigger", err) + } + triggerTableTriggerWire = triggerTableTriggerConverted + } + case *MaterializedFeature_Trigger_StreamingMode: + if value != nil { + triggerStreamingModeConverted, err := streamingModeToWire(&value.StreamingMode) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MaterializedFeature.Trigger.StreamingMode", err) + } + triggerStreamingModeWire = triggerStreamingModeConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "MaterializedFeature.Trigger", value) + } + return &materializedFeatureWire{ + MaterializedFeatureId: v.MaterializedFeatureId, + FeatureName: v.FeatureName, + OfflineStoreConfig: destinationOfflineStoreConfigWire, + OnlineStoreConfig: destinationOnlineStoreConfigWire, + TableName: v.TableName, + PipelineScheduleState: v.PipelineScheduleState, + LastMaterializationTime: v.LastMaterializationTime, + IsOnline: v.IsOnline, + CronScheduleTrigger: triggerCronScheduleTriggerWire, + TableTrigger: triggerTableTriggerWire, + StreamingMode: triggerStreamingModeWire, + }, nil +} + +func materializedFeatureFromWire(w *materializedFeatureWire) (*MaterializedFeature, error) { + if w == nil { + return nil, nil + } + destinationMembers := 0 + if w.OfflineStoreConfig != nil { + destinationMembers++ + } + if w.OnlineStoreConfig != nil { + destinationMembers++ + } + if destinationMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "MaterializedFeature.Destination") + } + triggerMembers := 0 + if w.CronScheduleTrigger != nil { + triggerMembers++ + } + if w.TableTrigger != nil { + triggerMembers++ + } + if w.StreamingMode != nil { + triggerMembers++ + } + if triggerMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "MaterializedFeature.Trigger") + } + var destinationSelection isMaterializedFeature_Destination + switch { + case w.OfflineStoreConfig != nil: + destinationOfflineStoreConfigConverted, err := offlineStoreConfigFromWire(w.OfflineStoreConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MaterializedFeature.Destination.OfflineStoreConfig", err) + } + destinationSelection = &MaterializedFeature_Destination_OfflineStoreConfig{OfflineStoreConfig: *destinationOfflineStoreConfigConverted} + case w.OnlineStoreConfig != nil: + destinationOnlineStoreConfigConverted, err := onlineStoreConfigFromWire(w.OnlineStoreConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MaterializedFeature.Destination.OnlineStoreConfig", err) + } + destinationSelection = &MaterializedFeature_Destination_OnlineStoreConfig{OnlineStoreConfig: *destinationOnlineStoreConfigConverted} + } + var triggerSelection isMaterializedFeature_Trigger + switch { + case w.CronScheduleTrigger != nil: + triggerCronScheduleTriggerConverted, err := cronScheduleFromWire(w.CronScheduleTrigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MaterializedFeature.Trigger.CronScheduleTrigger", err) + } + triggerSelection = &MaterializedFeature_Trigger_CronScheduleTrigger{CronScheduleTrigger: *triggerCronScheduleTriggerConverted} + case w.TableTrigger != nil: + triggerTableTriggerConverted, err := tableTriggerFromWire(w.TableTrigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MaterializedFeature.Trigger.TableTrigger", err) + } + triggerSelection = &MaterializedFeature_Trigger_TableTrigger{TableTrigger: *triggerTableTriggerConverted} + case w.StreamingMode != nil: + triggerStreamingModeConverted, err := streamingModeFromWire(w.StreamingMode) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MaterializedFeature.Trigger.StreamingMode", err) + } + triggerSelection = &MaterializedFeature_Trigger_StreamingMode{StreamingMode: *triggerStreamingModeConverted} + } + return &MaterializedFeature{ + MaterializedFeatureId: w.MaterializedFeatureId, + FeatureName: w.FeatureName, + TableName: w.TableName, + PipelineScheduleState: w.PipelineScheduleState, + LastMaterializationTime: w.LastMaterializationTime, + IsOnline: w.IsOnline, + Destination: destinationSelection, + Trigger: triggerSelection, + }, nil +} + +type maxFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func maxFunctionToWire(v *MaxFunction) (*maxFunctionWire, error) { + if v == nil { + return nil, nil + } + return &maxFunctionWire{ + Input: v.Input, + }, nil +} + +func maxFunctionFromWire(w *maxFunctionWire) (*MaxFunction, error) { + if w == nil { + return nil, nil + } + return &MaxFunction{ + Input: w.Input, + }, nil +} + +type minFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func minFunctionToWire(v *MinFunction) (*minFunctionWire, error) { + if v == nil { + return nil, nil + } + return &minFunctionWire{ + Input: v.Input, + }, nil +} + +func minFunctionFromWire(w *minFunctionWire) (*MinFunction, error) { + if w == nil { + return nil, nil + } + return &MinFunction{ + Input: w.Input, + }, nil +} + +type mtlsConfigWire struct { + KeystoreLocation *string `json:"keystore_location,omitempty"` + KeystorePasswordRef *secretScopeReferenceWire `json:"keystore_password_ref,omitempty"` + KeyPasswordRef *secretScopeReferenceWire `json:"key_password_ref,omitempty"` + TruststoreLocation *string `json:"truststore_location,omitempty"` + TruststorePasswordRef *secretScopeReferenceWire `json:"truststore_password_ref,omitempty"` + DisableHostnameVerification *bool `json:"disable_hostname_verification,omitempty"` +} + +func mtlsConfigToWire(v *MtlsConfig) (*mtlsConfigWire, error) { + if v == nil { + return nil, nil + } + keystorePasswordRefWireValue, err := secretScopeReferenceToWire(v.KeystorePasswordRef) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MtlsConfig.KeystorePasswordRef", err) + } + keyPasswordRefWireValue, err := secretScopeReferenceToWire(v.KeyPasswordRef) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MtlsConfig.KeyPasswordRef", err) + } + truststorePasswordRefWireValue, err := secretScopeReferenceToWire(v.TruststorePasswordRef) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MtlsConfig.TruststorePasswordRef", err) + } + return &mtlsConfigWire{ + KeystoreLocation: v.KeystoreLocation, + KeystorePasswordRef: keystorePasswordRefWireValue, + KeyPasswordRef: keyPasswordRefWireValue, + TruststoreLocation: v.TruststoreLocation, + TruststorePasswordRef: truststorePasswordRefWireValue, + DisableHostnameVerification: v.DisableHostnameVerification, + }, nil +} + +func mtlsConfigFromWire(w *mtlsConfigWire) (*MtlsConfig, error) { + if w == nil { + return nil, nil + } + keystorePasswordRefPublicValue, err := secretScopeReferenceFromWire(w.KeystorePasswordRef) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MtlsConfig.KeystorePasswordRef", err) + } + keyPasswordRefPublicValue, err := secretScopeReferenceFromWire(w.KeyPasswordRef) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MtlsConfig.KeyPasswordRef", err) + } + truststorePasswordRefPublicValue, err := secretScopeReferenceFromWire(w.TruststorePasswordRef) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MtlsConfig.TruststorePasswordRef", err) + } + return &MtlsConfig{ + KeystoreLocation: w.KeystoreLocation, + KeystorePasswordRef: keystorePasswordRefPublicValue, + KeyPasswordRef: keyPasswordRefPublicValue, + TruststoreLocation: w.TruststoreLocation, + TruststorePasswordRef: truststorePasswordRefPublicValue, + DisableHostnameVerification: w.DisableHostnameVerification, + }, nil +} + +type offlineStoreConfigWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + TableNamePrefix *string `json:"table_name_prefix,omitempty"` +} + +func offlineStoreConfigToWire(v *OfflineStoreConfig) (*offlineStoreConfigWire, error) { + if v == nil { + return nil, nil + } + return &offlineStoreConfigWire{ + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + TableNamePrefix: v.TableNamePrefix, + }, nil +} + +func offlineStoreConfigFromWire(w *offlineStoreConfigWire) (*OfflineStoreConfig, error) { + if w == nil { + return nil, nil + } + return &OfflineStoreConfig{ + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + TableNamePrefix: w.TableNamePrefix, + }, nil +} + +type onlineStoreConfigWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + TableNamePrefix *string `json:"table_name_prefix,omitempty"` + OnlineStoreName *string `json:"online_store_name,omitempty"` +} + +func onlineStoreConfigToWire(v *OnlineStoreConfig) (*onlineStoreConfigWire, error) { + if v == nil { + return nil, nil + } + return &onlineStoreConfigWire{ + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + TableNamePrefix: v.TableNamePrefix, + OnlineStoreName: v.OnlineStoreName, + }, nil +} + +func onlineStoreConfigFromWire(w *onlineStoreConfigWire) (*OnlineStoreConfig, error) { + if w == nil { + return nil, nil + } + return &OnlineStoreConfig{ + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + TableNamePrefix: w.TableNamePrefix, + OnlineStoreName: w.OnlineStoreName, + }, nil +} + +type protoSchemaSpecWire struct { + SchemaText *string `json:"schema_text,omitempty"` + MessageName *string `json:"message_name,omitempty"` +} + +func protoSchemaSpecToWire(v *ProtoSchemaSpec) (*protoSchemaSpecWire, error) { + if v == nil { + return nil, nil + } + return &protoSchemaSpecWire{ + SchemaText: v.SchemaText, + MessageName: v.MessageName, + }, nil +} + +func protoSchemaSpecFromWire(w *protoSchemaSpecWire) (*ProtoSchemaSpec, error) { + if w == nil { + return nil, nil + } + return &ProtoSchemaSpec{ + SchemaText: w.SchemaText, + MessageName: w.MessageName, + }, nil +} + +type requestSourceWire struct { + FlatSchema *flatSchemaWire `json:"flat_schema,omitempty"` +} + +func requestSourceToWire(v *RequestSource) (*requestSourceWire, error) { + if v == nil { + return nil, nil + } + var schemaFlatSchemaWire *flatSchemaWire + switch value := v.Schema.(type) { + case nil: + case *RequestSource_Schema_FlatSchema: + if value != nil { + schemaFlatSchemaConverted, err := flatSchemaToWire(&value.FlatSchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RequestSource.Schema.FlatSchema", err) + } + schemaFlatSchemaWire = schemaFlatSchemaConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "RequestSource.Schema", value) + } + return &requestSourceWire{ + FlatSchema: schemaFlatSchemaWire, + }, nil +} + +func requestSourceFromWire(w *requestSourceWire) (*RequestSource, error) { + if w == nil { + return nil, nil + } + schemaMembers := 0 + if w.FlatSchema != nil { + schemaMembers++ + } + if schemaMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "RequestSource.Schema") + } + var schemaSelection isRequestSource_Schema + switch { + case w.FlatSchema != nil: + schemaFlatSchemaConverted, err := flatSchemaFromWire(w.FlatSchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RequestSource.Schema.FlatSchema", err) + } + schemaSelection = &RequestSource_Schema_FlatSchema{FlatSchema: *schemaFlatSchemaConverted} + } + return &RequestSource{ + Schema: schemaSelection, + }, nil +} + +type rollingWindowWire struct { + WindowDuration *types.Duration `json:"window_duration,omitempty"` + Delay *types.Duration `json:"delay,omitempty"` +} + +func rollingWindowToWire(v *RollingWindow) (*rollingWindowWire, error) { + if v == nil { + return nil, nil + } + return &rollingWindowWire{ + WindowDuration: v.WindowDuration, + Delay: v.Delay, + }, nil +} + +func rollingWindowFromWire(w *rollingWindowWire) (*RollingWindow, error) { + if w == nil { + return nil, nil + } + return &RollingWindow{ + WindowDuration: w.WindowDuration, + Delay: w.Delay, + }, nil +} + +type sawtoothWindowWire struct { + WindowDuration *types.Duration `json:"window_duration,omitempty"` + Delay *types.Duration `json:"delay,omitempty"` +} + +func sawtoothWindowToWire(v *SawtoothWindow) (*sawtoothWindowWire, error) { + if v == nil { + return nil, nil + } + return &sawtoothWindowWire{ + WindowDuration: v.WindowDuration, + Delay: v.Delay, + }, nil +} + +func sawtoothWindowFromWire(w *sawtoothWindowWire) (*SawtoothWindow, error) { + if w == nil { + return nil, nil + } + return &SawtoothWindow{ + WindowDuration: w.WindowDuration, + Delay: w.Delay, + }, nil +} + +type schemaConfigWire struct { + JsonSchema *string `json:"json_schema,omitempty"` + AvroSchema *string `json:"avro_schema,omitempty"` + ProtoSchema *protoSchemaSpecWire `json:"proto_schema,omitempty"` +} + +func schemaConfigToWire(v *SchemaConfig) (*schemaConfigWire, error) { + if v == nil { + return nil, nil + } + var schemaJsonSchemaWire *string + var schemaAvroSchemaWire *string + var schemaProtoSchemaWire *protoSchemaSpecWire + switch value := v.Schema.(type) { + case nil: + case *SchemaConfig_Schema_JsonSchema: + if value != nil { + schemaJsonSchemaWire = new(value.JsonSchema) + } + case *SchemaConfig_Schema_AvroSchema: + if value != nil { + schemaAvroSchemaWire = new(value.AvroSchema) + } + case *SchemaConfig_Schema_ProtoSchema: + if value != nil { + schemaProtoSchemaConverted, err := protoSchemaSpecToWire(&value.ProtoSchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaConfig.Schema.ProtoSchema", err) + } + schemaProtoSchemaWire = schemaProtoSchemaConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SchemaConfig.Schema", value) + } + return &schemaConfigWire{ + JsonSchema: schemaJsonSchemaWire, + AvroSchema: schemaAvroSchemaWire, + ProtoSchema: schemaProtoSchemaWire, + }, nil +} + +func schemaConfigFromWire(w *schemaConfigWire) (*SchemaConfig, error) { + if w == nil { + return nil, nil + } + schemaMembers := 0 + if w.JsonSchema != nil { + schemaMembers++ + } + if w.AvroSchema != nil { + schemaMembers++ + } + if w.ProtoSchema != nil { + schemaMembers++ + } + if schemaMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SchemaConfig.Schema") + } + var schemaSelection isSchemaConfig_Schema + switch { + case w.JsonSchema != nil: + schemaSelection = &SchemaConfig_Schema_JsonSchema{JsonSchema: *w.JsonSchema} + case w.AvroSchema != nil: + schemaSelection = &SchemaConfig_Schema_AvroSchema{AvroSchema: *w.AvroSchema} + case w.ProtoSchema != nil: + schemaProtoSchemaConverted, err := protoSchemaSpecFromWire(w.ProtoSchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaConfig.Schema.ProtoSchema", err) + } + schemaSelection = &SchemaConfig_Schema_ProtoSchema{ProtoSchema: *schemaProtoSchemaConverted} + } + return &SchemaConfig{ + Schema: schemaSelection, + }, nil +} + +type schemaLocatorWire struct { + ConfluentSchema *schemaLocator_ConfluentSchemaWire `json:"confluent_schema,omitempty"` + Format SchemaLocator_Format `json:"format,omitempty"` +} + +func schemaLocatorToWire(v *SchemaLocator) (*schemaLocatorWire, error) { + if v == nil { + return nil, nil + } + var registrySchemaConfluentSchemaWire *schemaLocator_ConfluentSchemaWire + switch value := v.RegistrySchema.(type) { + case nil: + case *SchemaLocator_RegistrySchema_ConfluentSchema: + if value != nil { + registrySchemaConfluentSchemaConverted, err := schemaLocator_ConfluentSchemaToWire(&value.ConfluentSchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaLocator.RegistrySchema.ConfluentSchema", err) + } + registrySchemaConfluentSchemaWire = registrySchemaConfluentSchemaConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SchemaLocator.RegistrySchema", value) + } + return &schemaLocatorWire{ + ConfluentSchema: registrySchemaConfluentSchemaWire, + Format: v.Format, + }, nil +} + +func schemaLocatorFromWire(w *schemaLocatorWire) (*SchemaLocator, error) { + if w == nil { + return nil, nil + } + registrySchemaMembers := 0 + if w.ConfluentSchema != nil { + registrySchemaMembers++ + } + if registrySchemaMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SchemaLocator.RegistrySchema") + } + var registrySchemaSelection isSchemaLocator_RegistrySchema + switch { + case w.ConfluentSchema != nil: + registrySchemaConfluentSchemaConverted, err := schemaLocator_ConfluentSchemaFromWire(w.ConfluentSchema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaLocator.RegistrySchema.ConfluentSchema", err) + } + registrySchemaSelection = &SchemaLocator_RegistrySchema_ConfluentSchema{ConfluentSchema: *registrySchemaConfluentSchemaConverted} + } + return &SchemaLocator{ + Format: w.Format, + RegistrySchema: registrySchemaSelection, + }, nil +} + +type schemaLocator_ConfluentSchemaWire struct { + Subject *string `json:"subject,omitempty"` +} + +func schemaLocator_ConfluentSchemaToWire(v *SchemaLocator_ConfluentSchema) (*schemaLocator_ConfluentSchemaWire, error) { + if v == nil { + return nil, nil + } + return &schemaLocator_ConfluentSchemaWire{ + Subject: v.Subject, + }, nil +} + +func schemaLocator_ConfluentSchemaFromWire(w *schemaLocator_ConfluentSchemaWire) (*SchemaLocator_ConfluentSchema, error) { + if w == nil { + return nil, nil + } + return &SchemaLocator_ConfluentSchema{ + Subject: w.Subject, + }, nil +} + +type schemaRegistryConfigWire struct { + UcConnection *string `json:"uc_connection,omitempty"` + ApiSecretRef *secretScopeReferenceWire `json:"api_secret_ref,omitempty"` + PayloadSchemaLocator *schemaLocatorWire `json:"payload_schema_locator,omitempty"` + KeySchemaLocator *schemaLocatorWire `json:"key_schema_locator,omitempty"` +} + +func schemaRegistryConfigToWire(v *SchemaRegistryConfig) (*schemaRegistryConfigWire, error) { + if v == nil { + return nil, nil + } + apiSecretRefWireValue, err := secretScopeReferenceToWire(v.ApiSecretRef) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaRegistryConfig.ApiSecretRef", err) + } + payloadSchemaLocatorWireValue, err := schemaLocatorToWire(v.PayloadSchemaLocator) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaRegistryConfig.PayloadSchemaLocator", err) + } + keySchemaLocatorWireValue, err := schemaLocatorToWire(v.KeySchemaLocator) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaRegistryConfig.KeySchemaLocator", err) + } + return &schemaRegistryConfigWire{ + UcConnection: v.UcConnection, + ApiSecretRef: apiSecretRefWireValue, + PayloadSchemaLocator: payloadSchemaLocatorWireValue, + KeySchemaLocator: keySchemaLocatorWireValue, + }, nil +} + +func schemaRegistryConfigFromWire(w *schemaRegistryConfigWire) (*SchemaRegistryConfig, error) { + if w == nil { + return nil, nil + } + apiSecretRefPublicValue, err := secretScopeReferenceFromWire(w.ApiSecretRef) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaRegistryConfig.ApiSecretRef", err) + } + payloadSchemaLocatorPublicValue, err := schemaLocatorFromWire(w.PayloadSchemaLocator) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaRegistryConfig.PayloadSchemaLocator", err) + } + keySchemaLocatorPublicValue, err := schemaLocatorFromWire(w.KeySchemaLocator) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaRegistryConfig.KeySchemaLocator", err) + } + return &SchemaRegistryConfig{ + UcConnection: w.UcConnection, + ApiSecretRef: apiSecretRefPublicValue, + PayloadSchemaLocator: payloadSchemaLocatorPublicValue, + KeySchemaLocator: keySchemaLocatorPublicValue, + }, nil +} + +type secretScopeReferenceWire struct { + Scope *string `json:"scope,omitempty"` + Key *string `json:"key,omitempty"` +} + +func secretScopeReferenceToWire(v *SecretScopeReference) (*secretScopeReferenceWire, error) { + if v == nil { + return nil, nil + } + return &secretScopeReferenceWire{ + Scope: v.Scope, + Key: v.Key, + }, nil +} + +func secretScopeReferenceFromWire(w *secretScopeReferenceWire) (*SecretScopeReference, error) { + if w == nil { + return nil, nil + } + return &SecretScopeReference{ + Scope: w.Scope, + Key: w.Key, + }, nil +} + +type slidingWindowWire struct { + WindowDuration *types.Duration `json:"window_duration,omitempty"` + SlideDuration *types.Duration `json:"slide_duration,omitempty"` + Delay *types.Duration `json:"delay,omitempty"` + Offset *types.Duration `json:"offset,omitempty"` +} + +func slidingWindowToWire(v *SlidingWindow) (*slidingWindowWire, error) { + if v == nil { + return nil, nil + } + return &slidingWindowWire{ + WindowDuration: v.WindowDuration, + SlideDuration: v.SlideDuration, + Delay: v.Delay, + Offset: v.Offset, + }, nil +} + +func slidingWindowFromWire(w *slidingWindowWire) (*SlidingWindow, error) { + if w == nil { + return nil, nil + } + return &SlidingWindow{ + WindowDuration: w.WindowDuration, + SlideDuration: w.SlideDuration, + Delay: w.Delay, + Offset: w.Offset, + }, nil +} + +type sourceLatenessWire struct { + SettlingDelay *types.Duration `json:"settling_delay,omitempty"` +} + +func sourceLatenessToWire(v *SourceLateness) (*sourceLatenessWire, error) { + if v == nil { + return nil, nil + } + return &sourceLatenessWire{ + SettlingDelay: v.SettlingDelay, + }, nil +} + +func sourceLatenessFromWire(w *sourceLatenessWire) (*SourceLateness, error) { + if w == nil { + return nil, nil + } + return &SourceLateness{ + SettlingDelay: w.SettlingDelay, + }, nil +} + +type stddevPopFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func stddevPopFunctionToWire(v *StddevPopFunction) (*stddevPopFunctionWire, error) { + if v == nil { + return nil, nil + } + return &stddevPopFunctionWire{ + Input: v.Input, + }, nil +} + +func stddevPopFunctionFromWire(w *stddevPopFunctionWire) (*StddevPopFunction, error) { + if w == nil { + return nil, nil + } + return &StddevPopFunction{ + Input: w.Input, + }, nil +} + +type stddevSampFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func stddevSampFunctionToWire(v *StddevSampFunction) (*stddevSampFunctionWire, error) { + if v == nil { + return nil, nil + } + return &stddevSampFunctionWire{ + Input: v.Input, + }, nil +} + +func stddevSampFunctionFromWire(w *stddevSampFunctionWire) (*StddevSampFunction, error) { + if w == nil { + return nil, nil + } + return &StddevSampFunction{ + Input: w.Input, + }, nil +} + +type streamWire struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + SourceConfig *streamSourceConfigWire `json:"source_config,omitempty"` + ConnectionConfig *streamConnectionConfigWire `json:"connection_config,omitempty"` + SchemaConfig *streamSchemaConfigWire `json:"schema_config,omitempty"` + IngestionConfig *ingestionConfigWire `json:"ingestion_config,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` +} + +func streamToWire(v *Stream) (*streamWire, error) { + if v == nil { + return nil, nil + } + sourceConfigWireValue, err := streamSourceConfigToWire(v.SourceConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Stream.SourceConfig", err) + } + connectionConfigWireValue, err := streamConnectionConfigToWire(v.ConnectionConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Stream.ConnectionConfig", err) + } + schemaConfigWireValue, err := streamSchemaConfigToWire(v.SchemaConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Stream.SchemaConfig", err) + } + ingestionConfigWireValue, err := ingestionConfigToWire(v.IngestionConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Stream.IngestionConfig", err) + } + return &streamWire{ + Name: v.Name, + Description: v.Description, + SourceConfig: sourceConfigWireValue, + ConnectionConfig: connectionConfigWireValue, + SchemaConfig: schemaConfigWireValue, + IngestionConfig: ingestionConfigWireValue, + CreateTime: v.CreateTime, + CreatedBy: v.CreatedBy, + UpdateTime: v.UpdateTime, + UpdatedBy: v.UpdatedBy, + BrowseOnly: v.BrowseOnly, + }, nil +} + +func streamFromWire(w *streamWire) (*Stream, error) { + if w == nil { + return nil, nil + } + sourceConfigPublicValue, err := streamSourceConfigFromWire(w.SourceConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Stream.SourceConfig", err) + } + connectionConfigPublicValue, err := streamConnectionConfigFromWire(w.ConnectionConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Stream.ConnectionConfig", err) + } + schemaConfigPublicValue, err := streamSchemaConfigFromWire(w.SchemaConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Stream.SchemaConfig", err) + } + ingestionConfigPublicValue, err := ingestionConfigFromWire(w.IngestionConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Stream.IngestionConfig", err) + } + return &Stream{ + Name: w.Name, + Description: w.Description, + SourceConfig: sourceConfigPublicValue, + ConnectionConfig: connectionConfigPublicValue, + SchemaConfig: schemaConfigPublicValue, + IngestionConfig: ingestionConfigPublicValue, + CreateTime: w.CreateTime, + CreatedBy: w.CreatedBy, + UpdateTime: w.UpdateTime, + UpdatedBy: w.UpdatedBy, + BrowseOnly: w.BrowseOnly, + }, nil +} + +type streamArnListWire struct { + Arns []string `json:"arns,omitempty"` +} + +func streamArnListToWire(v *StreamArnList) (*streamArnListWire, error) { + if v == nil { + return nil, nil + } + return &streamArnListWire{ + Arns: v.Arns, + }, nil +} + +func streamArnListFromWire(w *streamArnListWire) (*StreamArnList, error) { + if w == nil { + return nil, nil + } + return &StreamArnList{ + Arns: w.Arns, + }, nil +} + +type streamConnectionConfigWire struct { + UcConnectionName *string `json:"uc_connection_name,omitempty"` + DirectMtlsConfig *directMtlsConfigWire `json:"direct_mtls_config,omitempty"` +} + +func streamConnectionConfigToWire(v *StreamConnectionConfig) (*streamConnectionConfigWire, error) { + if v == nil { + return nil, nil + } + var connectionConfigUcConnectionNameWire *string + var connectionConfigDirectMtlsConfigWire *directMtlsConfigWire + switch value := v.ConnectionConfig.(type) { + case nil: + case *StreamConnectionConfig_ConnectionConfig_UcConnectionName: + if value != nil { + connectionConfigUcConnectionNameWire = new(value.UcConnectionName) + } + case *StreamConnectionConfig_ConnectionConfig_DirectMtlsConfig: + if value != nil { + connectionConfigDirectMtlsConfigConverted, err := directMtlsConfigToWire(&value.DirectMtlsConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StreamConnectionConfig.ConnectionConfig.DirectMtlsConfig", err) + } + connectionConfigDirectMtlsConfigWire = connectionConfigDirectMtlsConfigConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "StreamConnectionConfig.ConnectionConfig", value) + } + return &streamConnectionConfigWire{ + UcConnectionName: connectionConfigUcConnectionNameWire, + DirectMtlsConfig: connectionConfigDirectMtlsConfigWire, + }, nil +} + +func streamConnectionConfigFromWire(w *streamConnectionConfigWire) (*StreamConnectionConfig, error) { + if w == nil { + return nil, nil + } + connectionConfigMembers := 0 + if w.UcConnectionName != nil { + connectionConfigMembers++ + } + if w.DirectMtlsConfig != nil { + connectionConfigMembers++ + } + if connectionConfigMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "StreamConnectionConfig.ConnectionConfig") + } + var connectionConfigSelection isStreamConnectionConfig_ConnectionConfig + switch { + case w.UcConnectionName != nil: + connectionConfigSelection = &StreamConnectionConfig_ConnectionConfig_UcConnectionName{UcConnectionName: *w.UcConnectionName} + case w.DirectMtlsConfig != nil: + connectionConfigDirectMtlsConfigConverted, err := directMtlsConfigFromWire(w.DirectMtlsConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StreamConnectionConfig.ConnectionConfig.DirectMtlsConfig", err) + } + connectionConfigSelection = &StreamConnectionConfig_ConnectionConfig_DirectMtlsConfig{DirectMtlsConfig: *connectionConfigDirectMtlsConfigConverted} + } + return &StreamConnectionConfig{ + ConnectionConfig: connectionConfigSelection, + }, nil +} + +type streamNameListWire struct { + Names []string `json:"names,omitempty"` +} + +func streamNameListToWire(v *StreamNameList) (*streamNameListWire, error) { + if v == nil { + return nil, nil + } + return &streamNameListWire{ + Names: v.Names, + }, nil +} + +func streamNameListFromWire(w *streamNameListWire) (*StreamNameList, error) { + if w == nil { + return nil, nil + } + return &StreamNameList{ + Names: w.Names, + }, nil +} + +type streamSchemaConfigWire struct { + DirectSchemas *directSchemasWire `json:"direct_schemas,omitempty"` + SchemaRegistryConfig *schemaRegistryConfigWire `json:"schema_registry_config,omitempty"` +} + +func streamSchemaConfigToWire(v *StreamSchemaConfig) (*streamSchemaConfigWire, error) { + if v == nil { + return nil, nil + } + var schemaConfigDirectSchemasWire *directSchemasWire + var schemaConfigSchemaRegistryConfigWire *schemaRegistryConfigWire + switch value := v.SchemaConfig.(type) { + case nil: + case *StreamSchemaConfig_SchemaConfig_DirectSchemas: + if value != nil { + schemaConfigDirectSchemasConverted, err := directSchemasToWire(&value.DirectSchemas) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StreamSchemaConfig.SchemaConfig.DirectSchemas", err) + } + schemaConfigDirectSchemasWire = schemaConfigDirectSchemasConverted + } + case *StreamSchemaConfig_SchemaConfig_SchemaRegistryConfig: + if value != nil { + schemaConfigSchemaRegistryConfigConverted, err := schemaRegistryConfigToWire(&value.SchemaRegistryConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StreamSchemaConfig.SchemaConfig.SchemaRegistryConfig", err) + } + schemaConfigSchemaRegistryConfigWire = schemaConfigSchemaRegistryConfigConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "StreamSchemaConfig.SchemaConfig", value) + } + return &streamSchemaConfigWire{ + DirectSchemas: schemaConfigDirectSchemasWire, + SchemaRegistryConfig: schemaConfigSchemaRegistryConfigWire, + }, nil +} + +func streamSchemaConfigFromWire(w *streamSchemaConfigWire) (*StreamSchemaConfig, error) { + if w == nil { + return nil, nil + } + schemaConfigMembers := 0 + if w.DirectSchemas != nil { + schemaConfigMembers++ + } + if w.SchemaRegistryConfig != nil { + schemaConfigMembers++ + } + if schemaConfigMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "StreamSchemaConfig.SchemaConfig") + } + var schemaConfigSelection isStreamSchemaConfig_SchemaConfig + switch { + case w.DirectSchemas != nil: + schemaConfigDirectSchemasConverted, err := directSchemasFromWire(w.DirectSchemas) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StreamSchemaConfig.SchemaConfig.DirectSchemas", err) + } + schemaConfigSelection = &StreamSchemaConfig_SchemaConfig_DirectSchemas{DirectSchemas: *schemaConfigDirectSchemasConverted} + case w.SchemaRegistryConfig != nil: + schemaConfigSchemaRegistryConfigConverted, err := schemaRegistryConfigFromWire(w.SchemaRegistryConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StreamSchemaConfig.SchemaConfig.SchemaRegistryConfig", err) + } + schemaConfigSelection = &StreamSchemaConfig_SchemaConfig_SchemaRegistryConfig{SchemaRegistryConfig: *schemaConfigSchemaRegistryConfigConverted} + } + return &StreamSchemaConfig{ + SchemaConfig: schemaConfigSelection, + }, nil +} + +type streamSourceWire struct { + FullName *string `json:"full_name,omitempty"` + FilterCondition *string `json:"filter_condition,omitempty"` + TransformationSql *string `json:"transformation_sql,omitempty"` + DataframeSchema *string `json:"dataframe_schema,omitempty"` +} + +func streamSourceToWire(v *StreamSource) (*streamSourceWire, error) { + if v == nil { + return nil, nil + } + return &streamSourceWire{ + FullName: v.FullName, + FilterCondition: v.FilterCondition, + TransformationSql: v.TransformationSql, + DataframeSchema: v.DataframeSchema, + }, nil +} + +func streamSourceFromWire(w *streamSourceWire) (*StreamSource, error) { + if w == nil { + return nil, nil + } + return &StreamSource{ + FullName: w.FullName, + FilterCondition: w.FilterCondition, + TransformationSql: w.TransformationSql, + DataframeSchema: w.DataframeSchema, + }, nil +} + +type streamSourceConfigWire struct { + KafkaStreamConfig *kafkaStreamConfigWire `json:"kafka_stream_config,omitempty"` + KinesisStreamConfig *kinesisStreamConfigWire `json:"kinesis_stream_config,omitempty"` +} + +func streamSourceConfigToWire(v *StreamSourceConfig) (*streamSourceConfigWire, error) { + if v == nil { + return nil, nil + } + var sourceConfigKafkaStreamConfigWire *kafkaStreamConfigWire + var sourceConfigKinesisStreamConfigWire *kinesisStreamConfigWire + switch value := v.SourceConfig.(type) { + case nil: + case *StreamSourceConfig_SourceConfig_KafkaStreamConfig: + if value != nil { + sourceConfigKafkaStreamConfigConverted, err := kafkaStreamConfigToWire(&value.KafkaStreamConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StreamSourceConfig.SourceConfig.KafkaStreamConfig", err) + } + sourceConfigKafkaStreamConfigWire = sourceConfigKafkaStreamConfigConverted + } + case *StreamSourceConfig_SourceConfig_KinesisStreamConfig: + if value != nil { + sourceConfigKinesisStreamConfigConverted, err := kinesisStreamConfigToWire(&value.KinesisStreamConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StreamSourceConfig.SourceConfig.KinesisStreamConfig", err) + } + sourceConfigKinesisStreamConfigWire = sourceConfigKinesisStreamConfigConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "StreamSourceConfig.SourceConfig", value) + } + return &streamSourceConfigWire{ + KafkaStreamConfig: sourceConfigKafkaStreamConfigWire, + KinesisStreamConfig: sourceConfigKinesisStreamConfigWire, + }, nil +} + +func streamSourceConfigFromWire(w *streamSourceConfigWire) (*StreamSourceConfig, error) { + if w == nil { + return nil, nil + } + sourceConfigMembers := 0 + if w.KafkaStreamConfig != nil { + sourceConfigMembers++ + } + if w.KinesisStreamConfig != nil { + sourceConfigMembers++ + } + if sourceConfigMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "StreamSourceConfig.SourceConfig") + } + var sourceConfigSelection isStreamSourceConfig_SourceConfig + switch { + case w.KafkaStreamConfig != nil: + sourceConfigKafkaStreamConfigConverted, err := kafkaStreamConfigFromWire(w.KafkaStreamConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StreamSourceConfig.SourceConfig.KafkaStreamConfig", err) + } + sourceConfigSelection = &StreamSourceConfig_SourceConfig_KafkaStreamConfig{KafkaStreamConfig: *sourceConfigKafkaStreamConfigConverted} + case w.KinesisStreamConfig != nil: + sourceConfigKinesisStreamConfigConverted, err := kinesisStreamConfigFromWire(w.KinesisStreamConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StreamSourceConfig.SourceConfig.KinesisStreamConfig", err) + } + sourceConfigSelection = &StreamSourceConfig_SourceConfig_KinesisStreamConfig{KinesisStreamConfig: *sourceConfigKinesisStreamConfigConverted} + } + return &StreamSourceConfig{ + SourceConfig: sourceConfigSelection, + }, nil +} + +type streamingModeWire struct { + Mode StreamingMode_StreamingModeType `json:"mode,omitempty"` + FreshnessTarget *string `json:"freshness_target,omitempty"` +} + +func streamingModeToWire(v *StreamingMode) (*streamingModeWire, error) { + if v == nil { + return nil, nil + } + return &streamingModeWire{ + Mode: v.Mode, + FreshnessTarget: v.FreshnessTarget, + }, nil +} + +func streamingModeFromWire(w *streamingModeWire) (*StreamingMode, error) { + if w == nil { + return nil, nil + } + return &StreamingMode{ + Mode: w.Mode, + FreshnessTarget: w.FreshnessTarget, + }, nil +} + +type subscriptionModeWire struct { + Assign *string `json:"assign,omitempty"` + Subscribe *string `json:"subscribe,omitempty"` + SubscribePattern *string `json:"subscribe_pattern,omitempty"` +} + +func subscriptionModeToWire(v *SubscriptionMode) (*subscriptionModeWire, error) { + if v == nil { + return nil, nil + } + var subscriptionModeAssignWire *string + var subscriptionModeSubscribeWire *string + var subscriptionModeSubscribePatternWire *string + switch value := v.SubscriptionMode.(type) { + case nil: + case *SubscriptionMode_SubscriptionMode_Assign: + if value != nil { + subscriptionModeAssignWire = new(value.Assign) + } + case *SubscriptionMode_SubscriptionMode_Subscribe: + if value != nil { + subscriptionModeSubscribeWire = new(value.Subscribe) + } + case *SubscriptionMode_SubscriptionMode_SubscribePattern: + if value != nil { + subscriptionModeSubscribePatternWire = new(value.SubscribePattern) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SubscriptionMode.SubscriptionMode", value) + } + return &subscriptionModeWire{ + Assign: subscriptionModeAssignWire, + Subscribe: subscriptionModeSubscribeWire, + SubscribePattern: subscriptionModeSubscribePatternWire, + }, nil +} + +func subscriptionModeFromWire(w *subscriptionModeWire) (*SubscriptionMode, error) { + if w == nil { + return nil, nil + } + subscriptionModeMembers := 0 + if w.Assign != nil { + subscriptionModeMembers++ + } + if w.Subscribe != nil { + subscriptionModeMembers++ + } + if w.SubscribePattern != nil { + subscriptionModeMembers++ + } + if subscriptionModeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SubscriptionMode.SubscriptionMode") + } + var subscriptionModeSelection isSubscriptionMode_SubscriptionMode + switch { + case w.Assign != nil: + subscriptionModeSelection = &SubscriptionMode_SubscriptionMode_Assign{Assign: *w.Assign} + case w.Subscribe != nil: + subscriptionModeSelection = &SubscriptionMode_SubscriptionMode_Subscribe{Subscribe: *w.Subscribe} + case w.SubscribePattern != nil: + subscriptionModeSelection = &SubscriptionMode_SubscriptionMode_SubscribePattern{SubscribePattern: *w.SubscribePattern} + } + return &SubscriptionMode{ + SubscriptionMode: subscriptionModeSelection, + }, nil +} + +type sumFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func sumFunctionToWire(v *SumFunction) (*sumFunctionWire, error) { + if v == nil { + return nil, nil + } + return &sumFunctionWire{ + Input: v.Input, + }, nil +} + +func sumFunctionFromWire(w *sumFunctionWire) (*SumFunction, error) { + if w == nil { + return nil, nil + } + return &SumFunction{ + Input: w.Input, + }, nil +} + +type tableTriggerWire struct { +} + +func tableTriggerToWire(v *TableTrigger) (*tableTriggerWire, error) { + if v == nil { + return nil, nil + } + return &tableTriggerWire{}, nil +} + +func tableTriggerFromWire(w *tableTriggerWire) (*TableTrigger, error) { + if w == nil { + return nil, nil + } + return &TableTrigger{}, nil +} + +type timeWindowWire struct { + Tumbling *tumblingWindowWire `json:"tumbling,omitempty"` + Sliding *slidingWindowWire `json:"sliding,omitempty"` + Rolling *rollingWindowWire `json:"rolling,omitempty"` + Sawtooth *sawtoothWindowWire `json:"sawtooth,omitempty"` + StartTime *types.Time `json:"start_time,omitempty"` +} + +func timeWindowToWire(v *TimeWindow) (*timeWindowWire, error) { + if v == nil { + return nil, nil + } + var windowTypeTumblingWire *tumblingWindowWire + var windowTypeSlidingWire *slidingWindowWire + var windowTypeRollingWire *rollingWindowWire + var windowTypeSawtoothWire *sawtoothWindowWire + switch value := v.WindowType.(type) { + case nil: + case *TimeWindow_WindowType_Tumbling: + if value != nil { + windowTypeTumblingConverted, err := tumblingWindowToWire(&value.Tumbling) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TimeWindow.WindowType.Tumbling", err) + } + windowTypeTumblingWire = windowTypeTumblingConverted + } + case *TimeWindow_WindowType_Sliding: + if value != nil { + windowTypeSlidingConverted, err := slidingWindowToWire(&value.Sliding) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TimeWindow.WindowType.Sliding", err) + } + windowTypeSlidingWire = windowTypeSlidingConverted + } + case *TimeWindow_WindowType_Rolling: + if value != nil { + windowTypeRollingConverted, err := rollingWindowToWire(&value.Rolling) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TimeWindow.WindowType.Rolling", err) + } + windowTypeRollingWire = windowTypeRollingConverted + } + case *TimeWindow_WindowType_Sawtooth: + if value != nil { + windowTypeSawtoothConverted, err := sawtoothWindowToWire(&value.Sawtooth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TimeWindow.WindowType.Sawtooth", err) + } + windowTypeSawtoothWire = windowTypeSawtoothConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "TimeWindow.WindowType", value) + } + return &timeWindowWire{ + Tumbling: windowTypeTumblingWire, + Sliding: windowTypeSlidingWire, + Rolling: windowTypeRollingWire, + Sawtooth: windowTypeSawtoothWire, + StartTime: v.StartTime, + }, nil +} + +func timeWindowFromWire(w *timeWindowWire) (*TimeWindow, error) { + if w == nil { + return nil, nil + } + windowTypeMembers := 0 + if w.Tumbling != nil { + windowTypeMembers++ + } + if w.Sliding != nil { + windowTypeMembers++ + } + if w.Rolling != nil { + windowTypeMembers++ + } + if w.Sawtooth != nil { + windowTypeMembers++ + } + if windowTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "TimeWindow.WindowType") + } + var windowTypeSelection isTimeWindow_WindowType + switch { + case w.Tumbling != nil: + windowTypeTumblingConverted, err := tumblingWindowFromWire(w.Tumbling) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TimeWindow.WindowType.Tumbling", err) + } + windowTypeSelection = &TimeWindow_WindowType_Tumbling{Tumbling: *windowTypeTumblingConverted} + case w.Sliding != nil: + windowTypeSlidingConverted, err := slidingWindowFromWire(w.Sliding) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TimeWindow.WindowType.Sliding", err) + } + windowTypeSelection = &TimeWindow_WindowType_Sliding{Sliding: *windowTypeSlidingConverted} + case w.Rolling != nil: + windowTypeRollingConverted, err := rollingWindowFromWire(w.Rolling) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TimeWindow.WindowType.Rolling", err) + } + windowTypeSelection = &TimeWindow_WindowType_Rolling{Rolling: *windowTypeRollingConverted} + case w.Sawtooth != nil: + windowTypeSawtoothConverted, err := sawtoothWindowFromWire(w.Sawtooth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TimeWindow.WindowType.Sawtooth", err) + } + windowTypeSelection = &TimeWindow_WindowType_Sawtooth{Sawtooth: *windowTypeSawtoothConverted} + } + return &TimeWindow{ + StartTime: w.StartTime, + WindowType: windowTypeSelection, + }, nil +} + +type timeseriesColumnWire struct { + Name *string `json:"name,omitempty"` +} + +func timeseriesColumnToWire(v *TimeseriesColumn) (*timeseriesColumnWire, error) { + if v == nil { + return nil, nil + } + return ×eriesColumnWire{ + Name: v.Name, + }, nil +} + +func timeseriesColumnFromWire(w *timeseriesColumnWire) (*TimeseriesColumn, error) { + if w == nil { + return nil, nil + } + return &TimeseriesColumn{ + Name: w.Name, + }, nil +} + +type tumblingWindowWire struct { + WindowDuration *types.Duration `json:"window_duration,omitempty"` + Delay *types.Duration `json:"delay,omitempty"` + Offset *types.Duration `json:"offset,omitempty"` +} + +func tumblingWindowToWire(v *TumblingWindow) (*tumblingWindowWire, error) { + if v == nil { + return nil, nil + } + return &tumblingWindowWire{ + WindowDuration: v.WindowDuration, + Delay: v.Delay, + Offset: v.Offset, + }, nil +} + +func tumblingWindowFromWire(w *tumblingWindowWire) (*TumblingWindow, error) { + if w == nil { + return nil, nil + } + return &TumblingWindow{ + WindowDuration: w.WindowDuration, + Delay: w.Delay, + Offset: w.Offset, + }, nil +} + +type updateFeatureRequestWire struct { + Feature *featureWire `json:"feature,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateFeatureRequestToWire(v *UpdateFeatureRequest) (*updateFeatureRequestWire, error) { + if v == nil { + return nil, nil + } + featureWireValue, err := featureToWire(v.Feature) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateFeatureRequest.Feature", err) + } + return &updateFeatureRequestWire{ + Feature: featureWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateKafkaConfigRequestWire struct { + KafkaConfig *kafkaConfigWire `json:"kafka_config,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateKafkaConfigRequestToWire(v *UpdateKafkaConfigRequest) (*updateKafkaConfigRequestWire, error) { + if v == nil { + return nil, nil + } + kafkaConfigWireValue, err := kafkaConfigToWire(v.KafkaConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateKafkaConfigRequest.KafkaConfig", err) + } + return &updateKafkaConfigRequestWire{ + KafkaConfig: kafkaConfigWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateMaterializedFeatureRequestWire struct { + MaterializedFeature *materializedFeatureWire `json:"materialized_feature,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateMaterializedFeatureRequestToWire(v *UpdateMaterializedFeatureRequest) (*updateMaterializedFeatureRequestWire, error) { + if v == nil { + return nil, nil + } + materializedFeatureWireValue, err := materializedFeatureToWire(v.MaterializedFeature) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateMaterializedFeatureRequest.MaterializedFeature", err) + } + return &updateMaterializedFeatureRequestWire{ + MaterializedFeature: materializedFeatureWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateStreamRequestWire struct { + Stream *streamWire `json:"stream,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateStreamRequestToWire(v *UpdateStreamRequest) (*updateStreamRequestWire, error) { + if v == nil { + return nil, nil + } + streamWireValue, err := streamToWire(v.Stream) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateStreamRequest.Stream", err) + } + return &updateStreamRequestWire{ + Stream: streamWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type varPopFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func varPopFunctionToWire(v *VarPopFunction) (*varPopFunctionWire, error) { + if v == nil { + return nil, nil + } + return &varPopFunctionWire{ + Input: v.Input, + }, nil +} + +func varPopFunctionFromWire(w *varPopFunctionWire) (*VarPopFunction, error) { + if w == nil { + return nil, nil + } + return &VarPopFunction{ + Input: w.Input, + }, nil +} + +type varSampFunctionWire struct { + Input *string `json:"input,omitempty"` +} + +func varSampFunctionToWire(v *VarSampFunction) (*varSampFunctionWire, error) { + if v == nil { + return nil, nil + } + return &varSampFunctionWire{ + Input: v.Input, + }, nil +} + +func varSampFunctionFromWire(w *varSampFunctionWire) (*VarSampFunction, error) { + if w == nil { + return nil, nil + } + return &VarSampFunction{ + Input: w.Input, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/featurestore/.package.json b/featurestore/.package.json new file mode 100644 index 0000000..f5ed7d6 --- /dev/null +++ b/featurestore/.package.json @@ -0,0 +1,3 @@ +{ + "package": "featurestore" +} diff --git a/featurestore/CHANGELOG.md b/featurestore/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/featurestore/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/featurestore/README.md b/featurestore/README.md new file mode 100644 index 0000000..a89e7aa --- /dev/null +++ b/featurestore/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/featurestore + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/featurestore@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/featurestore/v1" + +client, err := featurestore.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/featurestore/go.mod b/featurestore/go.mod new file mode 100644 index 0000000..ad3ebb8 --- /dev/null +++ b/featurestore/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/featurestore + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/featurestore/internal/version.go b/featurestore/internal/version.go new file mode 100644 index 0000000..fa9758c --- /dev/null +++ b/featurestore/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-featurestore" + +const Version = "0.0.1-dev.1" diff --git a/featurestore/v1/client.go b/featurestore/v1/client.go new file mode 100755 index 0000000..c5d1730 --- /dev/null +++ b/featurestore/v1/client.go @@ -0,0 +1,556 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package featurestore + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/featurestore/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create an Online Feature Store. +func (c *internalClient) CreateOnlineStore(ctx context.Context, req *CreateOnlineStoreRequest, opts ...call.Option) (*OnlineStore, error) { + wireReq, err := createOnlineStoreRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.OnlineStore) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-store/online-stores" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *OnlineStore + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp onlineStoreWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = onlineStoreFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete an Online Feature Store. +func (c *internalClient) DeleteOnlineStore(ctx context.Context, req *DeleteOnlineStoreRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-store/online-stores/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete online table. +func (c *internalClient) DeleteOnlineTable(ctx context.Context, req *DeleteOnlineTableRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-store/online-tables/") + pb.singleSegment(*req.OnlineTableName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Get an Online Feature Store. +func (c *internalClient) GetOnlineStore(ctx context.Context, req *GetOnlineStoreRequest, opts ...call.Option) (*OnlineStore, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-store/online-stores/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *OnlineStore + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp onlineStoreWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = onlineStoreFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List Online Feature Stores. +func (c *internalClient) ListOnlineStores(ctx context.Context, req *ListOnlineStoresRequest, opts ...call.Option) (*ListOnlineStoresResponse, error) { + wireReq, err := listOnlineStoresRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/feature-store/online-stores" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListOnlineStoresResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listOnlineStoresResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listOnlineStoresResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListOnlineStoresIter returns an iterator that iterates +// over the results of ListOnlineStores. +// +// For example: +// +// for item, err := range c.ListOnlineStoresIter(ctx, &ListOnlineStoresRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListOnlineStores call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListOnlineStores directly. +func (c *internalClient) ListOnlineStoresIter(ctx context.Context, req *ListOnlineStoresRequest, opts ...call.Option) iter.Seq2[*OnlineStore, error] { + return func(yield func(*OnlineStore, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListOnlineStoresRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListOnlineStores(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.OnlineStores { + if !yield(&resp.OnlineStores[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Publish features. +func (c *internalClient) PublishTable(ctx context.Context, req *PublishTableRequest, opts ...call.Option) (*PublishTableResponse, error) { + wireReq, err := publishTableRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-store/tables/") + pb.singleSegment(*req.SourceTableName) + pb.literal("/publish") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PublishTableResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp publishTableResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = publishTableResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update an Online Feature Store. +func (c *internalClient) UpdateOnlineStore(ctx context.Context, req *UpdateOnlineStoreRequest, opts ...call.Option) (*OnlineStore, error) { + wireReq, err := updateOnlineStoreRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.OnlineStore) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/feature-store/online-stores/") + pb.singleSegment(*req.OnlineStore.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *OnlineStore + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp onlineStoreWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = onlineStoreFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/featurestore/v1/genhelper.go b/featurestore/v1/genhelper.go new file mode 100755 index 0000000..2cc6647 --- /dev/null +++ b/featurestore/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package featurestore + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/featurestore/v1/model.go b/featurestore/v1/model.go new file mode 100755 index 0000000..9514181 --- /dev/null +++ b/featurestore/v1/model.go @@ -0,0 +1,129 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package featurestore + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type OnlineStore_State string + +const ( + OnlineStore_State_Unspecified OnlineStore_State = "" + // The online store is being brought online. + OnlineStore_State_Starting OnlineStore_State = "STARTING" + // The online store is active and ready to use. + OnlineStore_State_Available OnlineStore_State = "AVAILABLE" + // The online store is being deleted. + OnlineStore_State_Deleting OnlineStore_State = "DELETING" + // The online store is stopped. + OnlineStore_State_Stopped OnlineStore_State = "STOPPED" + // The online store is being updated. + OnlineStore_State_Updating OnlineStore_State = "UPDATING" + // The online store is failing over. + OnlineStore_State_FailingOver OnlineStore_State = "FAILING_OVER" +) + +type PublishSpec_PublishMode string + +const ( + PublishSpec_PublishMode_Unspecified PublishSpec_PublishMode = "" + // Pipeline runs continuously after syncing the initial data. Requires the + // source table to have Change Data Feed (CDF) enabled. + PublishSpec_PublishMode_Continuous PublishSpec_PublishMode = "CONTINUOUS" + // Pipeline stops after syncing the initial data and can be triggered later + // (manually, through a cron job or through data triggers). Requires the source + // table to have Change Data Feed (CDF) enabled. + PublishSpec_PublishMode_Triggered PublishSpec_PublishMode = "TRIGGERED" + // Pipeline stops after syncing the initial data and can be triggered later + // (manually, through a cron job or through data triggers). Successive updates + // always perform a full copy of the source table data (no incremental updates). + // Does not require the source table to have Change Data Feed (CDF) enabled. + PublishSpec_PublishMode_Snapshot PublishSpec_PublishMode = "SNAPSHOT" +) + +type CreateOnlineStoreRequest struct { + // Online store to create. + OnlineStore *OnlineStore +} + +type DeleteOnlineStoreRequest struct { + // Name of the online store to delete. + Name *string +} + +type DeleteOnlineTableRequest struct { + // The full three-part (catalog, schema, table) name of the online table. + OnlineTableName *string +} + +type GetOnlineStoreRequest struct { + // Name of the online store to get. + Name *string +} + +type ListOnlineStoresRequest struct { + // Pagination token to go to the next page based on a previous query. + PageToken *string + // The maximum number of results to return. Defaults to 100 if not specified. + PageSize *int +} + +type ListOnlineStoresResponse struct { + // List of online stores. + OnlineStores []OnlineStore + // Pagination token to request the next page of results for this query. + NextPageToken *string +} + +// An OnlineStore is a logical database instance that stores and serves features +// online.. +type OnlineStore struct { + // The name of the online store. This is the unique identifier for the online + // store. + Name *string `fieldmask:"name"` + // The email of the creator of the online store. + Creator *string `fieldmask:"creator"` + // The timestamp when the online store was created. + CreationTime *types.Time `fieldmask:"creation_time"` + // The current state of the online store. + State OnlineStore_State `fieldmask:"state"` + // The capacity of the online store. Valid values are "CU_1", "CU_2", "CU_4", + // "CU_8". + Capacity *string `fieldmask:"capacity"` + // The number of read replicas for the online store. Defaults to 0. + ReadReplicaCount *int `fieldmask:"read_replica_count"` + // The usage policy applied to the online store to track billing. + UsagePolicyId *string `fieldmask:"usage_policy_id"` +} + +type PublishSpec struct { + // The name of the target online store. + OnlineStore *string + // The full three-part (catalog, schema, table) name of the online table. + OnlineTableName *string + // The publish mode of the pipeline that syncs the online table with the source + // table. + PublishMode PublishSpec_PublishMode +} + +type PublishTableRequest struct { + // The full three-part (catalog, schema, table) name of the source table. + SourceTableName *string + // The specification for publishing the online table from the source table. + PublishSpec *PublishSpec +} + +type PublishTableResponse struct { + // The full three-part (catalog, schema, table) name of the online table. + OnlineTableName *string + // The ID of the pipeline that syncs the online table with the source table. + PipelineId *string +} + +type UpdateOnlineStoreRequest struct { + // Online store to update. + OnlineStore *OnlineStore + // The list of fields to update. + UpdateMask *types.FieldMask[OnlineStore] +} diff --git a/featurestore/v1/wire.go b/featurestore/v1/wire.go new file mode 100755 index 0000000..2559172 --- /dev/null +++ b/featurestore/v1/wire.go @@ -0,0 +1,193 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package featurestore + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createOnlineStoreRequestWire struct { + OnlineStore *onlineStoreWire `json:"online_store,omitempty"` +} + +func createOnlineStoreRequestToWire(v *CreateOnlineStoreRequest) (*createOnlineStoreRequestWire, error) { + if v == nil { + return nil, nil + } + onlineStoreWireValue, err := onlineStoreToWire(v.OnlineStore) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateOnlineStoreRequest.OnlineStore", err) + } + return &createOnlineStoreRequestWire{ + OnlineStore: onlineStoreWireValue, + }, nil +} + +type listOnlineStoresRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listOnlineStoresRequestToWire(v *ListOnlineStoresRequest) (*listOnlineStoresRequestWire, error) { + if v == nil { + return nil, nil + } + return &listOnlineStoresRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listOnlineStoresResponseWire struct { + OnlineStores []onlineStoreWire `json:"online_stores,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listOnlineStoresResponseFromWire(w *listOnlineStoresResponseWire) (*ListOnlineStoresResponse, error) { + if w == nil { + return nil, nil + } + onlineStoresPublicValue, err := convertSlice(w.OnlineStores, onlineStoreFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListOnlineStoresResponse.OnlineStores", err) + } + return &ListOnlineStoresResponse{ + OnlineStores: onlineStoresPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type onlineStoreWire struct { + Name *string `json:"name,omitempty"` + Creator *string `json:"creator,omitempty"` + CreationTime *types.Time `json:"creation_time,omitempty"` + State OnlineStore_State `json:"state,omitempty"` + Capacity *string `json:"capacity,omitempty"` + ReadReplicaCount *int `json:"read_replica_count,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` +} + +func onlineStoreToWire(v *OnlineStore) (*onlineStoreWire, error) { + if v == nil { + return nil, nil + } + return &onlineStoreWire{ + Name: v.Name, + Creator: v.Creator, + CreationTime: v.CreationTime, + State: v.State, + Capacity: v.Capacity, + ReadReplicaCount: v.ReadReplicaCount, + UsagePolicyId: v.UsagePolicyId, + }, nil +} + +func onlineStoreFromWire(w *onlineStoreWire) (*OnlineStore, error) { + if w == nil { + return nil, nil + } + return &OnlineStore{ + Name: w.Name, + Creator: w.Creator, + CreationTime: w.CreationTime, + State: w.State, + Capacity: w.Capacity, + ReadReplicaCount: w.ReadReplicaCount, + UsagePolicyId: w.UsagePolicyId, + }, nil +} + +type publishSpecWire struct { + OnlineStore *string `json:"online_store,omitempty"` + OnlineTableName *string `json:"online_table_name,omitempty"` + PublishMode PublishSpec_PublishMode `json:"publish_mode,omitempty"` +} + +func publishSpecToWire(v *PublishSpec) (*publishSpecWire, error) { + if v == nil { + return nil, nil + } + return &publishSpecWire{ + OnlineStore: v.OnlineStore, + OnlineTableName: v.OnlineTableName, + PublishMode: v.PublishMode, + }, nil +} + +type publishTableRequestWire struct { + SourceTableName *string `json:"source_table_name,omitempty"` + PublishSpec *publishSpecWire `json:"publish_spec,omitempty"` +} + +func publishTableRequestToWire(v *PublishTableRequest) (*publishTableRequestWire, error) { + if v == nil { + return nil, nil + } + publishSpecWireValue, err := publishSpecToWire(v.PublishSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PublishTableRequest.PublishSpec", err) + } + return &publishTableRequestWire{ + SourceTableName: v.SourceTableName, + PublishSpec: publishSpecWireValue, + }, nil +} + +type publishTableResponseWire struct { + OnlineTableName *string `json:"online_table_name,omitempty"` + PipelineId *string `json:"pipeline_id,omitempty"` +} + +func publishTableResponseFromWire(w *publishTableResponseWire) (*PublishTableResponse, error) { + if w == nil { + return nil, nil + } + return &PublishTableResponse{ + OnlineTableName: w.OnlineTableName, + PipelineId: w.PipelineId, + }, nil +} + +type updateOnlineStoreRequestWire struct { + OnlineStore *onlineStoreWire `json:"online_store,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateOnlineStoreRequestToWire(v *UpdateOnlineStoreRequest) (*updateOnlineStoreRequestWire, error) { + if v == nil { + return nil, nil + } + onlineStoreWireValue, err := onlineStoreToWire(v.OnlineStore) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateOnlineStoreRequest.OnlineStore", err) + } + return &updateOnlineStoreRequestWire{ + OnlineStore: onlineStoreWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/files/.package.json b/files/.package.json new file mode 100644 index 0000000..3279868 --- /dev/null +++ b/files/.package.json @@ -0,0 +1,3 @@ +{ + "package": "files" +} diff --git a/files/CHANGELOG.md b/files/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/files/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/files/README.md b/files/README.md new file mode 100644 index 0000000..f1a55c7 --- /dev/null +++ b/files/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/files + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/files@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/files/v2" + +client, err := files.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/files/go.mod b/files/go.mod index c4de586..0768d9f 100644 --- a/files/go.mod +++ b/files/go.mod @@ -9,9 +9,12 @@ replace github.com/databricks/sdk-go/core => ../core replace github.com/databricks/sdk-go/options => ../options require ( - github.com/databricks/sdk-go/auth v0.0.0-dev - github.com/databricks/sdk-go/core v0.0.1-dev - github.com/databricks/sdk-go/options v0.0.0-dev + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 ) -require gopkg.in/ini.v1 v1.67.0 // indirect +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/files/go.sum b/files/go.sum index 1bda96d..18b54be 100644 --- a/files/go.sum +++ b/files/go.sum @@ -6,6 +6,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/files/internal/version.go b/files/internal/version.go index 245eb61..ca94a8a 100644 --- a/files/internal/version.go +++ b/files/internal/version.go @@ -2,4 +2,4 @@ package internal const ModuleName = "sdk-go-files" -const Version = "0.0.0-dev.1" +const Version = "0.0.1-dev.1" diff --git a/files/v2/client.go b/files/v2/client.go old mode 100644 new mode 100755 index 746f34c..403704e --- a/files/v2/client.go +++ b/files/v2/client.go @@ -37,7 +37,7 @@ type internalClient struct { httpClient *http.Client credentials auth.Credentials logger *slog.Logger - userAgent string + userAgent func() (string, error) host string workspaceID string accountID string @@ -53,12 +53,15 @@ func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { if err := cfg.Resolve(); err != nil { return nil, err } - info, err := clientinfo.Default().With( - internal.ModuleName, internal.Version, - "auth", cfg.Credentials.Name(), - ) - if err != nil { - return nil, err + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil } return &Client{ @@ -66,7 +69,7 @@ func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { httpClient: cfg.HTTPClient, credentials: cfg.Credentials, logger: cfg.Logger, - userAgent: info.String(), + userAgent: userAgent, host: cfg.Host, workspaceID: cfg.WorkspaceID, accountID: cfg.AccountID, @@ -81,16 +84,20 @@ func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { // If the block of data exceeds 1 MB, this call will throw an exception with // “MAX_BLOCK_SIZE_EXCEEDED“. func (c *internalClient) AddBlock(ctx context.Context, req *AddBlockRequest, opts ...call.Option) (*AddBlockResponse, error) { - body, err := json.Marshal(addBlockRequestToWire(req)) + wireReq, err := addBlockRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) if err != nil { return nil, err } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -108,6 +115,7 @@ func (c *internalClient) AddBlock(ctx context.Context, req *AddBlockRequest, opt Method: "POST", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, Body: bytes.NewBuffer(body), }) @@ -137,16 +145,20 @@ func (c *internalClient) AddBlock(ctx context.Context, req *AddBlockRequest, opt // Closes the stream specified by the input handle. If the handle does not // exist, this call throws an exception with “RESOURCE_DOES_NOT_EXIST“. func (c *internalClient) Close(ctx context.Context, req *CloseRequest, opts ...call.Option) (*CloseResponse, error) { - body, err := json.Marshal(closeRequestToWire(req)) + wireReq, err := closeRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) if err != nil { return nil, err } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -164,6 +176,7 @@ func (c *internalClient) Close(ctx context.Context, req *CloseRequest, opts ...c Method: "POST", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, Body: bytes.NewBuffer(body), }) @@ -201,16 +214,20 @@ func (c *internalClient) Close(ctx context.Context, req *CloseRequest, opts ...c // “add-block“ calls with the handle you have. 3. Issue a “close“ call with // the handle you have. func (c *internalClient) Create(ctx context.Context, req *CreateRequest, opts ...call.Option) (*CreateResponse, error) { - body, err := json.Marshal(createRequestToWire(req)) + wireReq, err := createRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) if err != nil { return nil, err } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -228,6 +245,7 @@ func (c *internalClient) Create(ctx context.Context, req *CreateRequest, opts .. Method: "POST", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, Body: bytes.NewBuffer(body), }) @@ -247,7 +265,10 @@ func (c *internalClient) Create(ctx context.Context, req *CreateRequest, opts .. if err := json.Unmarshal(respBody, &wireResp); err != nil { return err } - resp = createResponseFromWire(&wireResp) + resp, err = createResponseFromWire(&wireResp) + if err != nil { + return err + } return nil } @@ -276,16 +297,20 @@ func (c *internalClient) Create(ctx context.Context, req *CreateRequest, opts .. // such as selective deletes, and the possibility to automate periodic delete // jobs. func (c *internalClient) Delete(ctx context.Context, req *DeleteRequest, opts ...call.Option) (*DeleteResponse, error) { - body, err := json.Marshal(deleteRequestToWire(req)) + wireReq, err := deleteRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) if err != nil { return nil, err } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -303,6 +328,7 @@ func (c *internalClient) Delete(ctx context.Context, req *DeleteRequest, opts .. Method: "POST", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, Body: bytes.NewBuffer(body), }) @@ -332,12 +358,16 @@ func (c *internalClient) Delete(ctx context.Context, req *DeleteRequest, opts .. // Gets the file information for a file or directory. If the file or directory // does not exist, this call throws an exception with `RESOURCE_DOES_NOT_EXIST`. func (c *internalClient) GetStatus(ctx context.Context, req *GetStatusRequest, opts ...call.Option) (*GetStatusResponse, error) { + wireReq, err := getStatusRequestToWire(req) + if err != nil { + return nil, err + } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -345,7 +375,7 @@ func (c *internalClient) GetStatus(ctx context.Context, req *GetStatusRequest, o } baseURL.Path = "/api/2.0/dbfs/get-status" queryParams := url.Values{} - if err := addQueryValue(queryParams, "path", req.Path); err != nil { + if err := addQueryValue(queryParams, "path", wireReq.Path); err != nil { return nil, err } baseURL.RawQuery = queryParams.Encode() @@ -358,6 +388,7 @@ func (c *internalClient) GetStatus(ctx context.Context, req *GetStatusRequest, o Method: "GET", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, }) if err != nil { @@ -376,7 +407,10 @@ func (c *internalClient) GetStatus(ctx context.Context, req *GetStatusRequest, o if err := json.Unmarshal(respBody, &wireResp); err != nil { return err } - resp = getStatusResponseFromWire(&wireResp) + resp, err = getStatusResponseFromWire(&wireResp) + if err != nil { + return err + } return nil } @@ -398,12 +432,16 @@ func (c *internalClient) GetStatus(ctx context.Context, req *GetStatusRequest, o // system utility (dbutils.fs)](/dev-tools/databricks-utils.html#dbutils-fs), // which provides the same functionality without timing out. func (c *internalClient) List(ctx context.Context, req *ListStatusRequest, opts ...call.Option) (*ListStatusResponse, error) { + wireReq, err := listStatusRequestToWire(req) + if err != nil { + return nil, err + } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -411,7 +449,7 @@ func (c *internalClient) List(ctx context.Context, req *ListStatusRequest, opts } baseURL.Path = "/api/2.0/dbfs/list" queryParams := url.Values{} - if err := addQueryValue(queryParams, "path", req.Path); err != nil { + if err := addQueryValue(queryParams, "path", wireReq.Path); err != nil { return nil, err } baseURL.RawQuery = queryParams.Encode() @@ -424,6 +462,7 @@ func (c *internalClient) List(ctx context.Context, req *ListStatusRequest, opts Method: "GET", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, }) if err != nil { @@ -442,7 +481,10 @@ func (c *internalClient) List(ctx context.Context, req *ListStatusRequest, opts if err := json.Unmarshal(respBody, &wireResp); err != nil { return err } - resp = listStatusResponseFromWire(&wireResp) + resp, err = listStatusResponseFromWire(&wireResp) + if err != nil { + return err + } return nil } @@ -458,16 +500,20 @@ func (c *internalClient) List(ctx context.Context, req *ListStatusRequest, opts // this operation fails, it might have succeeded in creating some of the // necessary parent directories. func (c *internalClient) Mkdirs(ctx context.Context, req *MkDirsRequest, opts ...call.Option) (*MkDirsResponse, error) { - body, err := json.Marshal(mkDirsRequestToWire(req)) + wireReq, err := mkDirsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) if err != nil { return nil, err } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -485,6 +531,7 @@ func (c *internalClient) Mkdirs(ctx context.Context, req *MkDirsRequest, opts .. Method: "POST", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, Body: bytes.NewBuffer(body), }) @@ -517,16 +564,20 @@ func (c *internalClient) Mkdirs(ctx context.Context, req *MkDirsRequest, opts .. // this call throws an exception with `RESOURCE_ALREADY_EXISTS`. If the given // source path is a directory, this call always recursively moves all files. func (c *internalClient) Move(ctx context.Context, req *MoveRequest, opts ...call.Option) (*MoveResponse, error) { - body, err := json.Marshal(moveRequestToWire(req)) + wireReq, err := moveRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) if err != nil { return nil, err } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -544,6 +595,7 @@ func (c *internalClient) Move(ctx context.Context, req *MoveRequest, opts ...cal Method: "POST", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, Body: bytes.NewBuffer(body), }) @@ -583,16 +635,20 @@ func (c *internalClient) Move(ctx context.Context, req *MoveRequest, opts ...cal // If you want to upload large files, use the streaming upload. For details, see // :method:dbfs/create, :method:dbfs/addBlock, :method:dbfs/close. func (c *internalClient) Put(ctx context.Context, req *PutRequest, opts ...call.Option) (*PutResponse, error) { - body, err := json.Marshal(putRequestToWire(req)) + wireReq, err := putRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) if err != nil { return nil, err } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -610,6 +666,7 @@ func (c *internalClient) Put(ctx context.Context, req *PutRequest, opts ...call. Method: "POST", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, Body: bytes.NewBuffer(body), }) @@ -645,12 +702,16 @@ func (c *internalClient) Put(ctx context.Context, req *PutRequest, opts ...call. // If `offset + length` exceeds the number of bytes in a file, it reads the // contents until the end of file. func (c *internalClient) Read(ctx context.Context, req *ReadRequest, opts ...call.Option) (*ReadResponse, error) { + wireReq, err := readRequestToWire(req) + if err != nil { + return nil, err + } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -658,13 +719,13 @@ func (c *internalClient) Read(ctx context.Context, req *ReadRequest, opts ...cal } baseURL.Path = "/api/2.0/dbfs/read" queryParams := url.Values{} - if err := addQueryValue(queryParams, "path", req.Path); err != nil { + if err := addQueryValue(queryParams, "path", wireReq.Path); err != nil { return nil, err } - if err := addQueryValue(queryParams, "offset", req.Offset); err != nil { + if err := addQueryValue(queryParams, "offset", wireReq.Offset); err != nil { return nil, err } - if err := addQueryValue(queryParams, "length", req.Length); err != nil { + if err := addQueryValue(queryParams, "length", wireReq.Length); err != nil { return nil, err } baseURL.RawQuery = queryParams.Encode() @@ -677,6 +738,7 @@ func (c *internalClient) Read(ctx context.Context, req *ReadRequest, opts ...cal Method: "GET", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, }) if err != nil { @@ -695,7 +757,10 @@ func (c *internalClient) Read(ctx context.Context, req *ReadRequest, opts ...cal if err := json.Unmarshal(respBody, &wireResp); err != nil { return err } - resp = readResponseFromWire(&wireResp) + resp, err = readResponseFromWire(&wireResp) + if err != nil { + return err + } return nil } @@ -712,10 +777,10 @@ func (c *internalClient) Read(ctx context.Context, req *ReadRequest, opts ...cal func (c *internalClient) CreateDirectory(ctx context.Context, req *CreateDirectoryRequest, opts ...call.Option) (*CreateDirectoryResponse, error) { headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -736,6 +801,7 @@ func (c *internalClient) CreateDirectory(ctx context.Context, req *CreateDirecto Method: "PUT", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, }) if err != nil { @@ -769,10 +835,10 @@ func (c *internalClient) CreateDirectory(ctx context.Context, req *CreateDirecto func (c *internalClient) DeleteDirectory(ctx context.Context, req *DeleteDirectoryRequest, opts ...call.Option) (*DeleteDirectoryResponse, error) { headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -793,6 +859,7 @@ func (c *internalClient) DeleteDirectory(ctx context.Context, req *DeleteDirecto Method: "DELETE", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, }) if err != nil { @@ -822,10 +889,10 @@ func (c *internalClient) DeleteDirectory(ctx context.Context, req *DeleteDirecto func (c *internalClient) DeleteFile(ctx context.Context, req *DeleteFileRequest, opts ...call.Option) (*DeleteFileResponse, error) { headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -846,6 +913,7 @@ func (c *internalClient) DeleteFile(ctx context.Context, req *DeleteFileRequest, Method: "DELETE", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, }) if err != nil { @@ -877,9 +945,6 @@ func (c *internalClient) DeleteFile(ctx context.Context, req *DeleteFileRequest, func (c *internalClient) DownloadFile(ctx context.Context, req *DownloadFileRequest, opts ...call.Option) (*DownloadFileResponse, error) { headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") headers.Set("Accept", "application/octet-stream") if req.Range != nil { @@ -888,6 +953,9 @@ func (c *internalClient) DownloadFile(ctx context.Context, req *DownloadFileRequ if req.IfUnmodifiedSince != nil { headers.Set("If-Unmodified-Since", fmt.Sprintf("%v", *req.IfUnmodifiedSince)) } + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -908,6 +976,7 @@ func (c *internalClient) DownloadFile(ctx context.Context, req *DownloadFileRequ Method: "GET", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, }) if err != nil { @@ -961,10 +1030,10 @@ func (c *internalClient) DownloadFile(ctx context.Context, req *DownloadFileRequ func (c *internalClient) GetDirectoryMetadata(ctx context.Context, req *GetDirectoryMetadataRequest, opts ...call.Option) (*GetDirectoryMetadataResponse, error) { headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -985,6 +1054,7 @@ func (c *internalClient) GetDirectoryMetadata(ctx context.Context, req *GetDirec Method: "HEAD", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, }) if err != nil { @@ -1015,9 +1085,6 @@ func (c *internalClient) GetDirectoryMetadata(ctx context.Context, req *GetDirec func (c *internalClient) GetFileMetadata(ctx context.Context, req *GetFileMetadataRequest, opts ...call.Option) (*GetFileMetadataResponse, error) { headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") if req.Range != nil { headers.Set("Range", fmt.Sprintf("%v", *req.Range)) @@ -1025,6 +1092,9 @@ func (c *internalClient) GetFileMetadata(ctx context.Context, req *GetFileMetada if req.IfUnmodifiedSince != nil { headers.Set("If-Unmodified-Since", fmt.Sprintf("%v", *req.IfUnmodifiedSince)) } + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -1045,6 +1115,7 @@ func (c *internalClient) GetFileMetadata(ctx context.Context, req *GetFileMetada Method: "HEAD", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, }) if err != nil { @@ -1088,12 +1159,16 @@ func (c *internalClient) GetFileMetadata(ctx context.Context, req *GetFileMetada // Returns the contents of a directory. If there is no directory at the // specified path, the API returns an HTTP 404 error. func (c *internalClient) ListDirectoryContents(ctx context.Context, req *ListDirectoryContentsRequest, opts ...call.Option) (*ListDirectoryResponse, error) { + wireReq, err := listDirectoryContentsRequestToWire(req) + if err != nil { + return nil, err + } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -1104,10 +1179,10 @@ func (c *internalClient) ListDirectoryContents(ctx context.Context, req *ListDir pb.multiSegments(*req.DirectoryPath) baseURL.Path, baseURL.RawPath = pb.build() queryParams := url.Values{} - if err := addQueryValue(queryParams, "page_size", req.PageSize); err != nil { + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { return nil, err } - if err := addQueryValue(queryParams, "page_token", req.PageToken); err != nil { + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { return nil, err } baseURL.RawQuery = queryParams.Encode() @@ -1120,6 +1195,7 @@ func (c *internalClient) ListDirectoryContents(ctx context.Context, req *ListDir Method: "GET", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, }) if err != nil { @@ -1138,7 +1214,10 @@ func (c *internalClient) ListDirectoryContents(ctx context.Context, req *ListDir if err := json.Unmarshal(respBody, &wireResp); err != nil { return err } - resp = listDirectoryResponseFromWire(&wireResp) + resp, err = listDirectoryResponseFromWire(&wireResp) + if err != nil { + return err + } return nil } @@ -1167,16 +1246,11 @@ func (c *internalClient) ListDirectoryContents(ctx context.Context, req *ListDir // ListDirectoryContents directly. func (c *internalClient) ListDirectoryContentsIter(ctx context.Context, req *ListDirectoryContentsRequest, opts ...call.Option) iter.Seq2[*DirectoryEntry, error] { return func(yield func(*DirectoryEntry, error) bool) { - // Deep copy the request via JSON round-trip to avoid modifying the original. - reqBody, err := json.Marshal(req) - if err != nil { - yield(nil, err) - return - } + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. pageReq := ListDirectoryContentsRequest{} - if err := json.Unmarshal(reqBody, &pageReq); err != nil { - yield(nil, err) - return + if req != nil { + pageReq = *req } for { resp, err := c.ListDirectoryContents(ctx, &pageReq, opts...) @@ -1203,12 +1277,16 @@ func (c *internalClient) ListDirectoryContentsIter(ctx context.Context, req *Lis // exactly the bytes sent in the request body. If the request is successful, // there is no response body. func (c *internalClient) UploadFile(ctx context.Context, req *UploadFileRequest, opts ...call.Option) (*UploadFileResponse, error) { + wireReq, err := uploadFileRequestToWire(req) + if err != nil { + return nil, err + } headers := http.Header{} - if c.userAgent != "" { - headers.Set("User-Agent", c.userAgent) - } headers.Set("Content-Type", "application/octet-stream") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } baseURL, err := url.Parse(c.host) if err != nil { @@ -1219,7 +1297,7 @@ func (c *internalClient) UploadFile(ctx context.Context, req *UploadFileRequest, pb.multiSegments(*req.FilePath) baseURL.Path, baseURL.RawPath = pb.build() queryParams := url.Values{} - if err := addQueryValue(queryParams, "overwrite", req.Overwrite); err != nil { + if err := addQueryValue(queryParams, "overwrite", wireReq.Overwrite); err != nil { return nil, err } baseURL.RawQuery = queryParams.Encode() @@ -1243,6 +1321,7 @@ func (c *internalClient) UploadFile(ctx context.Context, req *UploadFileRequest, Method: "PUT", URL: urlStr, Credentials: c.credentials, + UserAgent: c.userAgent, Headers: headers, Body: reqBody, }) diff --git a/files/v2/ext_upload_control.go b/files/v2/ext_upload_control.go index 8beab49..e62f71b 100644 --- a/files/v2/ext_upload_control.go +++ b/files/v2/ext_upload_control.go @@ -6,10 +6,10 @@ package files // owns the single-shot octet-stream PUT used for small files and as the // multipart/resumable fallback. // -// These calls run over the client's own authenticated transport (the same one -// the generated methods use); the parts/chunks then transfer directly to cloud -// storage over the URLs minted here (see the cloudstorage subpackage), carrying -// no Databricks credentials. +// These calls attach the client's credentials per request (via newHTTPRequest, +// the same helper the generated methods use); the parts/chunks then transfer +// directly to cloud storage over the URLs minted here (see the cloudstorage +// subpackage), carrying no Databricks credentials. import ( "bytes" @@ -168,11 +168,18 @@ func (e *engine) uploadSingleShot(ctx context.Context, path string, overwrite *b return fmt.Errorf("rewinding upload body: %w", err) } } - req, err := http.NewRequestWithContext(ctx, http.MethodPut, urlStr, body) + headers := http.Header{} + headers.Set("Content-Type", "application/octet-stream") + req, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: http.MethodPut, + URL: urlStr, + Credentials: e.c.credentials, + Headers: headers, + Body: body, + }) if err != nil { return err } - req.Header.Set("Content-Type", "application/octet-stream") e.setWorkspaceHeader(req) _, _, err = executeHTTPCall(httpCallOptions{req: req, client: e.c.httpClient, logger: e.c.logger}) return err @@ -268,7 +275,8 @@ func (e *engine) createAbortURL(ctx context.Context, path, token string) (presig // controlPlaneJSON performs an authenticated JSON request against the Files API // control plane, retrying transient failures via core/ops. reqBody and out may // be nil. A fresh request is built on each attempt so retries re-apply -// credentials (the auth transport handles token refresh) and rewind the body. +// credentials (newHTTPRequest re-reads them, picking up any token refresh) and +// rewind the body. func (e *engine) controlPlaneJSON(ctx context.Context, method, path string, query url.Values, reqBody, out any) error { urlStr, err := e.controlPlaneURL(path, query) if err != nil { @@ -286,11 +294,18 @@ func (e *engine) controlPlaneJSON(ctx context.Context, method, path string, quer if bodyBytes != nil { rdr = bytes.NewReader(bodyBytes) } - req, err := http.NewRequestWithContext(ctx, method, urlStr, rdr) + headers := http.Header{} + headers.Set("Content-Type", "application/json") + req, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: method, + URL: urlStr, + Credentials: e.c.credentials, + Headers: headers, + Body: rdr, + }) if err != nil { return err } - req.Header.Set("Content-Type", "application/json") e.setWorkspaceHeader(req) respBody, _, err := executeHTTPCall(httpCallOptions{req: req, client: e.c.httpClient, logger: e.c.logger}) if err != nil { @@ -310,7 +325,8 @@ func (e *engine) newControlPlaneRetrier() ops.Retrier { // setWorkspaceHeader applies the workspace routing header when the client is // workspace-scoped. The Files API control plane routes a request to the right -// workspace by this header; the auth transport supplies only the credentials. +// workspace by this header; the credentials are attached separately by +// newHTTPRequest. func (e *engine) setWorkspaceHeader(req *http.Request) { if e.c.workspaceID != "" { req.Header.Set("X-Databricks-Workspace-Id", e.c.workspaceID) diff --git a/files/v2/ext_upload_control_test.go b/files/v2/ext_upload_control_test.go index 4500f73..78eaf4c 100644 --- a/files/v2/ext_upload_control_test.go +++ b/files/v2/ext_upload_control_test.go @@ -11,14 +11,31 @@ import ( ) // newControlEngine builds an engine whose control plane points at an httptest -// server running h. +// server running h. h is only reached by a request that carries the client's +// credentials: like the real control plane, an unauthenticated call is rejected +// rather than served, so every test here also covers that invariant. func newControlEngine(t *testing.T, h http.HandlerFunc) *engine { t.Helper() - srv := httptest.NewServer(h) + srv := httptest.NewServer(requireCredentials(t, h)) t.Cleanup(srv.Close) return newEngine(buildUploadClient(t, srv.URL, srv.Client(), "")) } +// requireCredentials rejects a control-plane request that does not carry +// testToken, the way the Files API rejects one with "Credential was not sent". +func requireCredentials(t *testing.T, h http.HandlerFunc) http.HandlerFunc { + t.Helper() + return func(w http.ResponseWriter, r *http.Request) { + if got := r.Header.Get("Authorization"); got != testToken { + t.Errorf("%s %s: Authorization = %q, want %q", r.Method, r.URL.Path, got, testToken) + w.WriteHeader(http.StatusUnauthorized) + _, _ = io.WriteString(w, `{"error_code":"UNAUTHENTICATED","message":"Credential was not sent or was of an unsupported type"}`) + return + } + h(w, r) + } +} + func TestInitiate(t *testing.T) { c := newControlEngine(t, func(w http.ResponseWriter, r *http.Request) { if !strings.HasPrefix(r.URL.Path, "/api/2.0/fs/files/") { diff --git a/files/v2/ext_upload_test.go b/files/v2/ext_upload_test.go index ae7c576..f28e7ee 100644 --- a/files/v2/ext_upload_test.go +++ b/files/v2/ext_upload_test.go @@ -22,13 +22,21 @@ import ( "github.com/databricks/sdk-go/options/client" ) -// stubCredentials is a no-op credential for tests: NewClient requires -// credentials, but these tests exercise the control plane through a fake server -// that ignores auth headers. -type stubCredentials struct{} +// testToken is the Authorization value a Databricks-authenticated request in +// these tests carries. Control-plane calls must attach it; presigned +// cloud-storage transfers must not. +const testToken = "Bearer test-token" -func (stubCredentials) Name() string { return "stub" } -func (stubCredentials) AuthHeaders(context.Context) ([]auth.Header, error) { return nil, nil } +// testCredentials stamps testToken on every request the client builds. It emits +// a real value rather than nothing so that a request which drops the client's +// credentials is distinguishable from one that carries them. +type testCredentials struct{} + +func (testCredentials) Name() string { return "test" } + +func (testCredentials) AuthHeaders(context.Context) ([]auth.Header, error) { + return []auth.Header{{Key: "Authorization", Value: testToken}}, nil +} // buildUploadClient builds a v2 Client whose control plane is served by hc and // addressed at host, with an optional workspace ID for the routing header. @@ -37,7 +45,7 @@ func buildUploadClient(t *testing.T, host string, hc *http.Client, workspaceID s opts := []client.Option{ client.WithHost(host), client.WithHTTPClient(hc), - client.WithCredentials(stubCredentials{}), + client.WithCredentials(testCredentials{}), client.WithLogger(slog.New(slog.NewTextHandler(io.Discard, nil))), // Keep tests hermetic: without this, an unset workspace ID would be // filled from the developer's local profile. @@ -111,8 +119,27 @@ func newFakeServer(t *testing.T, mode string) *fakeServer { func (f *fakeServer) base() string { return f.srv.URL } +// isControlPlane reports whether a path is a Files API control-plane endpoint, +// as opposed to a presigned cloud-storage URL this server also mints. +func isControlPlane(path string) bool { return strings.HasPrefix(path, "/api/2.0/fs/") } + func (f *fakeServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { path := r.URL.Path + + // Enforce the credential split the real deployment enforces, so any upload + // test fails when a call authenticates wrongly: the control plane rejects a + // request without the client's credentials ("Credential was not sent"), and a + // presigned cloud URL must never receive them. + if isControlPlane(path) && r.Header.Get("Authorization") != testToken { + w.WriteHeader(http.StatusUnauthorized) + _, _ = io.WriteString(w, `{"error_code":"UNAUTHENTICATED","message":"Credential was not sent or was of an unsupported type"}`) + return + } + if strings.HasPrefix(path, "/cloud/") && r.Header.Get("Authorization") != "" { + http.Error(w, "presigned cloud URL received Databricks credentials", http.StatusInternalServerError) + return + } + switch { case r.Method == http.MethodPost && strings.HasSuffix(path, "/create-upload-part-urls"): f.handleCreatePartURLs(w, r) diff --git a/files/v2/genhelper.go b/files/v2/genhelper.go old mode 100644 new mode 100755 index d9f1542..3571a65 --- a/files/v2/genhelper.go +++ b/files/v2/genhelper.go @@ -30,6 +30,7 @@ type httpRequestOptions struct { Method string URL string Credentials auth.Credentials + UserAgent func() (string, error) Headers http.Header Body io.Reader } @@ -52,6 +53,16 @@ func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request req.Header.Add(h.Key, h.Value) } } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } return req, nil } @@ -134,6 +145,7 @@ func executeCall(ctx context.Context, op func(context.Context) error, opts []cal } return ops.Execute(ctx, op, opsOpts...) } + func addQueryValue(params url.Values, key string, value any) error { data, err := json.Marshal(value) if err != nil { diff --git a/files/v2/model.go b/files/v2/model.go old mode 100644 new mode 100755 index 4875cde..d8c9e19 --- a/files/v2/model.go +++ b/files/v2/model.go @@ -7,14 +7,17 @@ import ( ) type AddBlockRequest struct { + // The handle on an open stream. Handle *int64 - Data []byte + // The base64-encoded data to append to the stream. This has a limit of 1 MB. + Data []byte } type AddBlockResponse struct { } type CloseRequest struct { + // The handle on an open stream. Handle *int64 } @@ -23,6 +26,7 @@ type CloseResponse struct { // Create a directory. type CreateDirectoryRequest struct { + // The absolute path of a directory. DirectoryPath *string } @@ -30,16 +34,21 @@ type CreateDirectoryResponse struct { } type CreateRequest struct { - Path *string + // The path of the new file. The path should be the absolute DBFS path. + Path *string + // The flag that specifies whether to overwrite existing file/files. Overwrite *bool } type CreateResponse struct { + // Handle which should subsequently be passed into the AddBlock and Close calls + // when writing to a file through a stream. Handle *int64 } // Delete a directory. type DeleteDirectoryRequest struct { + // The absolute path of a directory. DirectoryPath *string } @@ -48,6 +57,7 @@ type DeleteDirectoryResponse struct { // Delete a file. type DeleteFileRequest struct { + // The absolute path of the file. FilePath *string } @@ -55,7 +65,11 @@ type DeleteFileResponse struct { } type DeleteRequest struct { - Path *string + // The path of the file or directory to delete. The path should be the absolute + // DBFS path. + Path *string + // Whether or not to recursively delete the directory's contents. Deleting empty + // directories can be done without providing the recursive flag. Recursive *bool } @@ -63,37 +77,59 @@ type DeleteResponse struct { } type DirectoryEntry struct { - FileSize *int - IsDirectory *bool + // The length of the file in bytes. This field is omitted for directories. + FileSize *int + // True if the path is a directory. + IsDirectory *bool + // Last modification time of given file in milliseconds since unix epoch. LastModified *int - Name *string - Path *string + // The name of the file or directory. This is the last component of the path. + Name *string + // The absolute path of the file or directory. + Path *string } // Download a file. type DownloadFileRequest struct { - FilePath *string - Range *string + // The absolute path of the file. + FilePath *string + // The range of bytes to retrieve. The range is inclusive and zero-based, see + // [RFC 9110] for further details. + // + // [RFC 9110]: https://datatracker.ietf.org/doc/html/rfc9110#name-range + Range *string + // Download the file only if it has not been modified since the specified + // timestamp. If it has, a 412 Precondition Failed error will be returned. See + // [RFC 9110] for further details. + // + // [RFC 9110]: https://datatracker.ietf.org/doc/html/rfc9110#name-if-unmodified-since IfUnmodifiedSince *string } type DownloadFileResponse struct { + // The length of the HTTP response body in bytes. ContentLength *int64 ContentType *string Contents io.ReadCloser - LastModified *string + // The last modified time of the file in HTTP-date (RFC 7231) format. + LastModified *string } // Stores the attributes of a file or directory.. type FileInfo struct { - Path *string - IsDir *bool - FileSize *int64 + // The absolute path of the file or directory. + Path *string + // True if the path is a directory. + IsDir *bool + // The length of the file in bytes. Set to 0 for directories. + FileSize *int64 + // Last modification time of given file in milliseconds since epoch. ModificationTime *int64 } // Get directory metadata. type GetDirectoryMetadataRequest struct { + // The absolute path of a directory. DirectoryPath *string } @@ -102,49 +138,90 @@ type GetDirectoryMetadataResponse struct { // Get file metadata. type GetFileMetadataRequest struct { - FilePath *string - Range *string + // The absolute path of the file. + FilePath *string + // The range of bytes to retrieve. The range is inclusive and zero-based, see + // [RFC 9110] for further details. + // + // [RFC 9110]: https://datatracker.ietf.org/doc/html/rfc9110#name-range + Range *string + // Download the file only if it has not been modified since the specified + // timestamp. If it has, a 412 Precondition Failed error will be returned. See + // [RFC 9110] for further details. + // + // [RFC 9110]: https://datatracker.ietf.org/doc/html/rfc9110#name-if-unmodified-since IfUnmodifiedSince *string } type GetFileMetadataResponse struct { + // The length of the HTTP response body in bytes. ContentLength *int64 ContentType *string - LastModified *string + // The last modified time of the file in HTTP-date (RFC 7231) format. + LastModified *string } type GetStatusRequest struct { + // The path of the file or directory. The path should be the absolute DBFS path. Path *string } type GetStatusResponse struct { - Path *string - IsDir *bool - FileSize *int64 + // The absolute path of the file or directory. + Path *string + // True if the path is a directory. + IsDir *bool + // The length of the file in bytes. Set to 0 for directories. + FileSize *int64 + // Last modification time of given file in milliseconds since epoch. ModificationTime *int64 } // List directory contents. type ListDirectoryContentsRequest struct { + // The absolute path of a directory. DirectoryPath *string - PageSize *int64 - PageToken *string + // The maximum number of directory entries to return. The response may contain + // fewer entries. If the response contains a `next_page_token`, there may be + // more entries, even if fewer than `page_size` entries are in the response. + // + // We recommend not to set this value unless you are intentionally listing less + // than the complete directory contents. + // + // If unspecified, at most 1000 directory entries will be returned. The maximum + // value is 1000. Values above 1000 will be coerced to 1000. + PageSize *int64 + // An opaque page token which was the `next_page_token` in the response of the + // previous request to list the contents of this directory. Provide this token + // to retrieve the next page of directory entries. When providing a + // `page_token`, all other parameters provided to the request must match the + // previous request. To list all of the entries in a directory, it is necessary + // to continue requesting pages of entries until the response contains no + // `next_page_token`. Note that the number of entries returned must not be used + // to determine when the listing is complete. + PageToken *string } type ListDirectoryResponse struct { - Contents []DirectoryEntry + // Array of DirectoryEntry. + Contents []DirectoryEntry + // A token, which can be sent as `page_token` to retrieve the next page. NextPageToken *string } type ListStatusRequest struct { + // The path of the file or directory. The path should be the absolute DBFS path. Path *string } type ListStatusResponse struct { + // A list of FileInfo's that describe contents of directory or file. See example + // above. Files []FileInfo } type MkDirsRequest struct { + // The path of the new directory. The path should be the absolute DBFS path. Path *string } @@ -152,7 +229,11 @@ type MkDirsResponse struct { } type MoveRequest struct { - SourcePath *string + // The source path of the file or directory. The path should be the absolute + // DBFS path. + SourcePath *string + // The destination path of the file or directory. The path should be the + // absolute DBFS path. DestinationPath *string } @@ -160,8 +241,11 @@ type MoveResponse struct { } type PutRequest struct { - Path *string - Contents []byte + // The path of the new file. The path should be the absolute DBFS path. + Path *string + // This parameter might be absent, and instead a posted file will be used. + Contents []byte + // The flag that specifies whether to overwrite existing file/files. Overwrite *bool } @@ -169,20 +253,31 @@ type PutResponse struct { } type ReadRequest struct { - Path *string + // The path of the file to read. The path should be the absolute DBFS path. + Path *string + // The offset to read from in bytes. Offset *int64 + // The number of bytes to read starting from the offset. This has a limit of 1 + // MB, and a default value of 0.5 MB. Length *int64 } type ReadResponse struct { + // The number of bytes read (could be less than ``length`` if we hit end of + // file). This refers to number of bytes read in unencoded version (response + // data is base64-encoded). BytesRead *int64 - Data []byte + // The base64-encoded contents of the file read. + Data []byte } // Upload a file. type UploadFileRequest struct { - FilePath *string - Contents io.ReadCloser + // The absolute path of the file. + FilePath *string + Contents io.ReadCloser + // If true or unspecified, an existing file will be overwritten. If false, an + // error will be returned if the path points to an existing file. Overwrite *bool } diff --git a/files/v2/wire.go b/files/v2/wire.go old mode 100644 new mode 100755 index fcea436..2e4e31e --- a/files/v2/wire.go +++ b/files/v2/wire.go @@ -2,124 +2,36 @@ package files +import ( + "fmt" +) + type addBlockRequestWire struct { Handle *int64 `json:"handle,omitempty"` Data []byte `json:"data,omitempty"` } -func addBlockRequestToWire(v *AddBlockRequest) *addBlockRequestWire { +func addBlockRequestToWire(v *AddBlockRequest) (*addBlockRequestWire, error) { if v == nil { - return nil + return nil, nil } return &addBlockRequestWire{ Handle: v.Handle, Data: v.Data, - } -} - -func addBlockRequestFromWire(w *addBlockRequestWire) *AddBlockRequest { - if w == nil { - return nil - } - return &AddBlockRequest{ - Handle: w.Handle, - Data: w.Data, - } -} - -type addBlockResponseWire struct { -} - -func addBlockResponseToWire(v *AddBlockResponse) *addBlockResponseWire { - if v == nil { - return nil - } - return &addBlockResponseWire{} -} - -func addBlockResponseFromWire(w *addBlockResponseWire) *AddBlockResponse { - if w == nil { - return nil - } - return &AddBlockResponse{} + }, nil } type closeRequestWire struct { Handle *int64 `json:"handle,omitempty"` } -func closeRequestToWire(v *CloseRequest) *closeRequestWire { +func closeRequestToWire(v *CloseRequest) (*closeRequestWire, error) { if v == nil { - return nil + return nil, nil } return &closeRequestWire{ Handle: v.Handle, - } -} - -func closeRequestFromWire(w *closeRequestWire) *CloseRequest { - if w == nil { - return nil - } - return &CloseRequest{ - Handle: w.Handle, - } -} - -type closeResponseWire struct { -} - -func closeResponseToWire(v *CloseResponse) *closeResponseWire { - if v == nil { - return nil - } - return &closeResponseWire{} -} - -func closeResponseFromWire(w *closeResponseWire) *CloseResponse { - if w == nil { - return nil - } - return &CloseResponse{} -} - -type createDirectoryRequestWire struct { - DirectoryPath *string `json:"directory_path,omitempty"` -} - -func createDirectoryRequestToWire(v *CreateDirectoryRequest) *createDirectoryRequestWire { - if v == nil { - return nil - } - return &createDirectoryRequestWire{ - DirectoryPath: v.DirectoryPath, - } -} - -func createDirectoryRequestFromWire(w *createDirectoryRequestWire) *CreateDirectoryRequest { - if w == nil { - return nil - } - return &CreateDirectoryRequest{ - DirectoryPath: w.DirectoryPath, - } -} - -type createDirectoryResponseWire struct { -} - -func createDirectoryResponseToWire(v *CreateDirectoryResponse) *createDirectoryResponseWire { - if v == nil { - return nil - } - return &createDirectoryResponseWire{} -} - -func createDirectoryResponseFromWire(w *createDirectoryResponseWire) *CreateDirectoryResponse { - if w == nil { - return nil - } - return &CreateDirectoryResponse{} + }, nil } type createRequestWire struct { @@ -127,124 +39,27 @@ type createRequestWire struct { Overwrite *bool `json:"overwrite,omitempty"` } -func createRequestToWire(v *CreateRequest) *createRequestWire { +func createRequestToWire(v *CreateRequest) (*createRequestWire, error) { if v == nil { - return nil + return nil, nil } return &createRequestWire{ Path: v.Path, Overwrite: v.Overwrite, - } -} - -func createRequestFromWire(w *createRequestWire) *CreateRequest { - if w == nil { - return nil - } - return &CreateRequest{ - Path: w.Path, - Overwrite: w.Overwrite, - } + }, nil } type createResponseWire struct { Handle *int64 `json:"handle,omitempty"` } -func createResponseToWire(v *CreateResponse) *createResponseWire { - if v == nil { - return nil - } - return &createResponseWire{ - Handle: v.Handle, - } -} - -func createResponseFromWire(w *createResponseWire) *CreateResponse { +func createResponseFromWire(w *createResponseWire) (*CreateResponse, error) { if w == nil { - return nil + return nil, nil } return &CreateResponse{ Handle: w.Handle, - } -} - -type deleteDirectoryRequestWire struct { - DirectoryPath *string `json:"directory_path,omitempty"` -} - -func deleteDirectoryRequestToWire(v *DeleteDirectoryRequest) *deleteDirectoryRequestWire { - if v == nil { - return nil - } - return &deleteDirectoryRequestWire{ - DirectoryPath: v.DirectoryPath, - } -} - -func deleteDirectoryRequestFromWire(w *deleteDirectoryRequestWire) *DeleteDirectoryRequest { - if w == nil { - return nil - } - return &DeleteDirectoryRequest{ - DirectoryPath: w.DirectoryPath, - } -} - -type deleteDirectoryResponseWire struct { -} - -func deleteDirectoryResponseToWire(v *DeleteDirectoryResponse) *deleteDirectoryResponseWire { - if v == nil { - return nil - } - return &deleteDirectoryResponseWire{} -} - -func deleteDirectoryResponseFromWire(w *deleteDirectoryResponseWire) *DeleteDirectoryResponse { - if w == nil { - return nil - } - return &DeleteDirectoryResponse{} -} - -type deleteFileRequestWire struct { - FilePath *string `json:"file_path,omitempty"` -} - -func deleteFileRequestToWire(v *DeleteFileRequest) *deleteFileRequestWire { - if v == nil { - return nil - } - return &deleteFileRequestWire{ - FilePath: v.FilePath, - } -} - -func deleteFileRequestFromWire(w *deleteFileRequestWire) *DeleteFileRequest { - if w == nil { - return nil - } - return &DeleteFileRequest{ - FilePath: w.FilePath, - } -} - -type deleteFileResponseWire struct { -} - -func deleteFileResponseToWire(v *DeleteFileResponse) *deleteFileResponseWire { - if v == nil { - return nil - } - return &deleteFileResponseWire{} -} - -func deleteFileResponseFromWire(w *deleteFileResponseWire) *DeleteFileResponse { - if w == nil { - return nil - } - return &DeleteFileResponse{} + }, nil } type deleteRequestWire struct { @@ -252,41 +67,14 @@ type deleteRequestWire struct { Recursive *bool `json:"recursive,omitempty"` } -func deleteRequestToWire(v *DeleteRequest) *deleteRequestWire { +func deleteRequestToWire(v *DeleteRequest) (*deleteRequestWire, error) { if v == nil { - return nil + return nil, nil } return &deleteRequestWire{ Path: v.Path, Recursive: v.Recursive, - } -} - -func deleteRequestFromWire(w *deleteRequestWire) *DeleteRequest { - if w == nil { - return nil - } - return &DeleteRequest{ - Path: w.Path, - Recursive: w.Recursive, - } -} - -type deleteResponseWire struct { -} - -func deleteResponseToWire(v *DeleteResponse) *deleteResponseWire { - if v == nil { - return nil - } - return &deleteResponseWire{} -} - -func deleteResponseFromWire(w *deleteResponseWire) *DeleteResponse { - if w == nil { - return nil - } - return &DeleteResponse{} + }, nil } type directoryEntryWire struct { @@ -297,22 +85,9 @@ type directoryEntryWire struct { Path *string `json:"path,omitempty"` } -func directoryEntryToWire(v *DirectoryEntry) *directoryEntryWire { - if v == nil { - return nil - } - return &directoryEntryWire{ - FileSize: v.FileSize, - IsDirectory: v.IsDirectory, - LastModified: v.LastModified, - Name: v.Name, - Path: v.Path, - } -} - -func directoryEntryFromWire(w *directoryEntryWire) *DirectoryEntry { +func directoryEntryFromWire(w *directoryEntryWire) (*DirectoryEntry, error) { if w == nil { - return nil + return nil, nil } return &DirectoryEntry{ FileSize: w.FileSize, @@ -320,46 +95,7 @@ func directoryEntryFromWire(w *directoryEntryWire) *DirectoryEntry { LastModified: w.LastModified, Name: w.Name, Path: w.Path, - } -} - -type downloadFileRequestWire struct { - FilePath *string `json:"file_path,omitempty"` -} - -func downloadFileRequestToWire(v *DownloadFileRequest) *downloadFileRequestWire { - if v == nil { - return nil - } - return &downloadFileRequestWire{ - FilePath: v.FilePath, - } -} - -func downloadFileRequestFromWire(w *downloadFileRequestWire) *DownloadFileRequest { - if w == nil { - return nil - } - return &DownloadFileRequest{ - FilePath: w.FilePath, - } -} - -type downloadFileResponseWire struct { -} - -func downloadFileResponseToWire(v *DownloadFileResponse) *downloadFileResponseWire { - if v == nil { - return nil - } - return &downloadFileResponseWire{} -} - -func downloadFileResponseFromWire(w *downloadFileResponseWire) *DownloadFileResponse { - if w == nil { - return nil - } - return &DownloadFileResponse{} + }, nil } type fileInfoWire struct { @@ -369,128 +105,29 @@ type fileInfoWire struct { ModificationTime *int64 `json:"modification_time,omitempty"` } -func fileInfoToWire(v *FileInfo) *fileInfoWire { - if v == nil { - return nil - } - return &fileInfoWire{ - Path: v.Path, - IsDir: v.IsDir, - FileSize: v.FileSize, - ModificationTime: v.ModificationTime, - } -} - -func fileInfoFromWire(w *fileInfoWire) *FileInfo { +func fileInfoFromWire(w *fileInfoWire) (*FileInfo, error) { if w == nil { - return nil + return nil, nil } return &FileInfo{ Path: w.Path, IsDir: w.IsDir, FileSize: w.FileSize, ModificationTime: w.ModificationTime, - } -} - -type getDirectoryMetadataRequestWire struct { - DirectoryPath *string `json:"directory_path,omitempty"` -} - -func getDirectoryMetadataRequestToWire(v *GetDirectoryMetadataRequest) *getDirectoryMetadataRequestWire { - if v == nil { - return nil - } - return &getDirectoryMetadataRequestWire{ - DirectoryPath: v.DirectoryPath, - } -} - -func getDirectoryMetadataRequestFromWire(w *getDirectoryMetadataRequestWire) *GetDirectoryMetadataRequest { - if w == nil { - return nil - } - return &GetDirectoryMetadataRequest{ - DirectoryPath: w.DirectoryPath, - } -} - -type getDirectoryMetadataResponseWire struct { -} - -func getDirectoryMetadataResponseToWire(v *GetDirectoryMetadataResponse) *getDirectoryMetadataResponseWire { - if v == nil { - return nil - } - return &getDirectoryMetadataResponseWire{} -} - -func getDirectoryMetadataResponseFromWire(w *getDirectoryMetadataResponseWire) *GetDirectoryMetadataResponse { - if w == nil { - return nil - } - return &GetDirectoryMetadataResponse{} -} - -type getFileMetadataRequestWire struct { - FilePath *string `json:"file_path,omitempty"` -} - -func getFileMetadataRequestToWire(v *GetFileMetadataRequest) *getFileMetadataRequestWire { - if v == nil { - return nil - } - return &getFileMetadataRequestWire{ - FilePath: v.FilePath, - } -} - -func getFileMetadataRequestFromWire(w *getFileMetadataRequestWire) *GetFileMetadataRequest { - if w == nil { - return nil - } - return &GetFileMetadataRequest{ - FilePath: w.FilePath, - } -} - -type getFileMetadataResponseWire struct { -} - -func getFileMetadataResponseToWire(v *GetFileMetadataResponse) *getFileMetadataResponseWire { - if v == nil { - return nil - } - return &getFileMetadataResponseWire{} -} - -func getFileMetadataResponseFromWire(w *getFileMetadataResponseWire) *GetFileMetadataResponse { - if w == nil { - return nil - } - return &GetFileMetadataResponse{} + }, nil } type getStatusRequestWire struct { Path *string `json:"path,omitempty"` } -func getStatusRequestToWire(v *GetStatusRequest) *getStatusRequestWire { +func getStatusRequestToWire(v *GetStatusRequest) (*getStatusRequestWire, error) { if v == nil { - return nil + return nil, nil } return &getStatusRequestWire{ Path: v.Path, - } -} - -func getStatusRequestFromWire(w *getStatusRequestWire) *GetStatusRequest { - if w == nil { - return nil - } - return &GetStatusRequest{ - Path: w.Path, - } + }, nil } type getStatusResponseWire struct { @@ -500,28 +137,16 @@ type getStatusResponseWire struct { ModificationTime *int64 `json:"modification_time,omitempty"` } -func getStatusResponseToWire(v *GetStatusResponse) *getStatusResponseWire { - if v == nil { - return nil - } - return &getStatusResponseWire{ - Path: v.Path, - IsDir: v.IsDir, - FileSize: v.FileSize, - ModificationTime: v.ModificationTime, - } -} - -func getStatusResponseFromWire(w *getStatusResponseWire) *GetStatusResponse { +func getStatusResponseFromWire(w *getStatusResponseWire) (*GetStatusResponse, error) { if w == nil { - return nil + return nil, nil } return &GetStatusResponse{ Path: w.Path, IsDir: w.IsDir, FileSize: w.FileSize, ModificationTime: w.ModificationTime, - } + }, nil } type listDirectoryContentsRequestWire struct { @@ -530,26 +155,15 @@ type listDirectoryContentsRequestWire struct { PageToken *string `json:"page_token,omitempty"` } -func listDirectoryContentsRequestToWire(v *ListDirectoryContentsRequest) *listDirectoryContentsRequestWire { +func listDirectoryContentsRequestToWire(v *ListDirectoryContentsRequest) (*listDirectoryContentsRequestWire, error) { if v == nil { - return nil + return nil, nil } return &listDirectoryContentsRequestWire{ DirectoryPath: v.DirectoryPath, PageSize: v.PageSize, PageToken: v.PageToken, - } -} - -func listDirectoryContentsRequestFromWire(w *listDirectoryContentsRequestWire) *ListDirectoryContentsRequest { - if w == nil { - return nil - } - return &ListDirectoryContentsRequest{ - DirectoryPath: w.DirectoryPath, - PageSize: w.PageSize, - PageToken: w.PageToken, - } + }, nil } type listDirectoryResponseWire struct { @@ -557,107 +171,61 @@ type listDirectoryResponseWire struct { NextPageToken *string `json:"next_page_token,omitempty"` } -func listDirectoryResponseToWire(v *ListDirectoryResponse) *listDirectoryResponseWire { - if v == nil { - return nil - } - return &listDirectoryResponseWire{ - Contents: convertSlice(v.Contents, directoryEntryToWire), - NextPageToken: v.NextPageToken, - } -} - -func listDirectoryResponseFromWire(w *listDirectoryResponseWire) *ListDirectoryResponse { +func listDirectoryResponseFromWire(w *listDirectoryResponseWire) (*ListDirectoryResponse, error) { if w == nil { - return nil + return nil, nil + } + contentsPublicValue, err := convertSlice(w.Contents, directoryEntryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListDirectoryResponse.Contents", err) } return &ListDirectoryResponse{ - Contents: convertSlice(w.Contents, directoryEntryFromWire), + Contents: contentsPublicValue, NextPageToken: w.NextPageToken, - } + }, nil } type listStatusRequestWire struct { Path *string `json:"path,omitempty"` } -func listStatusRequestToWire(v *ListStatusRequest) *listStatusRequestWire { +func listStatusRequestToWire(v *ListStatusRequest) (*listStatusRequestWire, error) { if v == nil { - return nil + return nil, nil } return &listStatusRequestWire{ Path: v.Path, - } -} - -func listStatusRequestFromWire(w *listStatusRequestWire) *ListStatusRequest { - if w == nil { - return nil - } - return &ListStatusRequest{ - Path: w.Path, - } + }, nil } type listStatusResponseWire struct { Files []fileInfoWire `json:"files,omitempty"` } -func listStatusResponseToWire(v *ListStatusResponse) *listStatusResponseWire { - if v == nil { - return nil - } - return &listStatusResponseWire{ - Files: convertSlice(v.Files, fileInfoToWire), - } -} - -func listStatusResponseFromWire(w *listStatusResponseWire) *ListStatusResponse { +func listStatusResponseFromWire(w *listStatusResponseWire) (*ListStatusResponse, error) { if w == nil { - return nil + return nil, nil } - return &ListStatusResponse{ - Files: convertSlice(w.Files, fileInfoFromWire), + filesPublicValue, err := convertSlice(w.Files, fileInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListStatusResponse.Files", err) } + return &ListStatusResponse{ + Files: filesPublicValue, + }, nil } type mkDirsRequestWire struct { Path *string `json:"path,omitempty"` } -func mkDirsRequestToWire(v *MkDirsRequest) *mkDirsRequestWire { +func mkDirsRequestToWire(v *MkDirsRequest) (*mkDirsRequestWire, error) { if v == nil { - return nil + return nil, nil } return &mkDirsRequestWire{ Path: v.Path, - } -} - -func mkDirsRequestFromWire(w *mkDirsRequestWire) *MkDirsRequest { - if w == nil { - return nil - } - return &MkDirsRequest{ - Path: w.Path, - } -} - -type mkDirsResponseWire struct { -} - -func mkDirsResponseToWire(v *MkDirsResponse) *mkDirsResponseWire { - if v == nil { - return nil - } - return &mkDirsResponseWire{} -} - -func mkDirsResponseFromWire(w *mkDirsResponseWire) *MkDirsResponse { - if w == nil { - return nil - } - return &MkDirsResponse{} + }, nil } type moveRequestWire struct { @@ -665,41 +233,14 @@ type moveRequestWire struct { DestinationPath *string `json:"destination_path,omitempty"` } -func moveRequestToWire(v *MoveRequest) *moveRequestWire { +func moveRequestToWire(v *MoveRequest) (*moveRequestWire, error) { if v == nil { - return nil + return nil, nil } return &moveRequestWire{ SourcePath: v.SourcePath, DestinationPath: v.DestinationPath, - } -} - -func moveRequestFromWire(w *moveRequestWire) *MoveRequest { - if w == nil { - return nil - } - return &MoveRequest{ - SourcePath: w.SourcePath, - DestinationPath: w.DestinationPath, - } -} - -type moveResponseWire struct { -} - -func moveResponseToWire(v *MoveResponse) *moveResponseWire { - if v == nil { - return nil - } - return &moveResponseWire{} -} - -func moveResponseFromWire(w *moveResponseWire) *MoveResponse { - if w == nil { - return nil - } - return &MoveResponse{} + }, nil } type putRequestWire struct { @@ -708,43 +249,15 @@ type putRequestWire struct { Overwrite *bool `json:"overwrite,omitempty"` } -func putRequestToWire(v *PutRequest) *putRequestWire { +func putRequestToWire(v *PutRequest) (*putRequestWire, error) { if v == nil { - return nil + return nil, nil } return &putRequestWire{ Path: v.Path, Contents: v.Contents, Overwrite: v.Overwrite, - } -} - -func putRequestFromWire(w *putRequestWire) *PutRequest { - if w == nil { - return nil - } - return &PutRequest{ - Path: w.Path, - Contents: w.Contents, - Overwrite: w.Overwrite, - } -} - -type putResponseWire struct { -} - -func putResponseToWire(v *PutResponse) *putResponseWire { - if v == nil { - return nil - } - return &putResponseWire{} -} - -func putResponseFromWire(w *putResponseWire) *PutResponse { - if w == nil { - return nil - } - return &PutResponse{} + }, nil } type readRequestWire struct { @@ -753,26 +266,15 @@ type readRequestWire struct { Length *int64 `json:"length,omitempty"` } -func readRequestToWire(v *ReadRequest) *readRequestWire { +func readRequestToWire(v *ReadRequest) (*readRequestWire, error) { if v == nil { - return nil + return nil, nil } return &readRequestWire{ Path: v.Path, Offset: v.Offset, Length: v.Length, - } -} - -func readRequestFromWire(w *readRequestWire) *ReadRequest { - if w == nil { - return nil - } - return &ReadRequest{ - Path: w.Path, - Offset: w.Offset, - Length: w.Length, - } + }, nil } type readResponseWire struct { @@ -780,24 +282,14 @@ type readResponseWire struct { Data []byte `json:"data,omitempty"` } -func readResponseToWire(v *ReadResponse) *readResponseWire { - if v == nil { - return nil - } - return &readResponseWire{ - BytesRead: v.BytesRead, - Data: v.Data, - } -} - -func readResponseFromWire(w *readResponseWire) *ReadResponse { +func readResponseFromWire(w *readResponseWire) (*ReadResponse, error) { if w == nil { - return nil + return nil, nil } return &ReadResponse{ BytesRead: w.BytesRead, Data: w.Data, - } + }, nil } type uploadFileRequestWire struct { @@ -805,50 +297,27 @@ type uploadFileRequestWire struct { Overwrite *bool `json:"overwrite,omitempty"` } -func uploadFileRequestToWire(v *UploadFileRequest) *uploadFileRequestWire { +func uploadFileRequestToWire(v *UploadFileRequest) (*uploadFileRequestWire, error) { if v == nil { - return nil + return nil, nil } return &uploadFileRequestWire{ FilePath: v.FilePath, Overwrite: v.Overwrite, - } -} - -func uploadFileRequestFromWire(w *uploadFileRequestWire) *UploadFileRequest { - if w == nil { - return nil - } - return &UploadFileRequest{ - FilePath: w.FilePath, - Overwrite: w.Overwrite, - } -} - -type uploadFileResponseWire struct { -} - -func uploadFileResponseToWire(v *UploadFileResponse) *uploadFileResponseWire { - if v == nil { - return nil - } - return &uploadFileResponseWire{} -} - -func uploadFileResponseFromWire(w *uploadFileResponseWire) *UploadFileResponse { - if w == nil { - return nil - } - return &UploadFileResponse{} + }, nil } -func convertSlice[T, W any](s []T, conv func(*T) *W) []W { +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { if s == nil { - return nil + return nil, nil } out := make([]W, len(s)) for i := range s { - out[i] = *conv(&s[i]) + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted } - return out + return out, nil } diff --git a/forecasting/.package.json b/forecasting/.package.json new file mode 100644 index 0000000..0252b19 --- /dev/null +++ b/forecasting/.package.json @@ -0,0 +1,3 @@ +{ + "package": "forecasting" +} diff --git a/forecasting/CHANGELOG.md b/forecasting/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/forecasting/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/forecasting/README.md b/forecasting/README.md new file mode 100644 index 0000000..edb5f2f --- /dev/null +++ b/forecasting/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/forecasting + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/forecasting@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/forecasting/v1" + +client, err := forecasting.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/forecasting/go.mod b/forecasting/go.mod new file mode 100644 index 0000000..b893731 --- /dev/null +++ b/forecasting/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/forecasting + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/forecasting/internal/version.go b/forecasting/internal/version.go new file mode 100644 index 0000000..7369ac1 --- /dev/null +++ b/forecasting/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-forecasting" + +const Version = "0.0.1-dev.1" diff --git a/forecasting/v1/client.go b/forecasting/v1/client.go new file mode 100755 index 0000000..91c6ae0 --- /dev/null +++ b/forecasting/v1/client.go @@ -0,0 +1,280 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package forecasting + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/forecasting/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a serverless forecasting experiment. Returns the experiment ID. +func (c *internalClient) createForecastingExperimentBase(ctx context.Context, req *CreateForecastingExperimentRequest, opts ...call.Option) (*CreateForecastingExperimentResponse, error) { + wireReq, err := createForecastingExperimentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/automl/create-forecasting-experiment" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateForecastingExperimentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createForecastingExperimentResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createForecastingExperimentResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a serverless forecasting experiment. Returns the experiment ID. +func (c *internalClient) CreateForecastingExperiment(ctx context.Context, req *CreateForecastingExperimentRequest, opts ...call.Option) (*CreateForecastingExperimentWaiter, error) { + resp, err := c.createForecastingExperimentBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.ExperimentId == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "ExperimentId") + } + return &CreateForecastingExperimentWaiter{ + poll: c.GetForecastingExperiment, + experimentId: *resp.ExperimentId, + }, nil +} + +// CreateForecastingExperimentWaiter tracks the state of the operation started by CreateForecastingExperiment. +type CreateForecastingExperimentWaiter struct { + poll func(context.Context, *GetForecastingExperimentRequest, ...call.Option) (*ForecastingExperiment, error) + experimentId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateForecastingExperimentWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetForecastingExperimentRequest{ + ExperimentId: &w.experimentId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ForecastingExperiment_State_Succeeded, ForecastingExperiment_State_Failed, ForecastingExperiment_State_Cancelled: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateForecastingExperimentWaiter) Wait(ctx context.Context, opts ...lro.Option) (*ForecastingExperiment, error) { + var result *ForecastingExperiment + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetForecastingExperimentRequest{ + ExperimentId: &w.experimentId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ForecastingExperiment_State_Succeeded: + result = pollResp + return nil + case ForecastingExperiment_State_Failed, ForecastingExperiment_State_Cancelled: + message := "(no message)" + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Public RPC to get forecasting experiment +func (c *internalClient) GetForecastingExperiment(ctx context.Context, req *GetForecastingExperimentRequest, opts ...call.Option) (*ForecastingExperiment, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/automl/get-forecasting-experiment/") + pb.singleSegment(*req.ExperimentId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ForecastingExperiment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp forecastingExperimentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = forecastingExperimentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/forecasting/v1/genhelper.go b/forecasting/v1/genhelper.go new file mode 100755 index 0000000..89b7b71 --- /dev/null +++ b/forecasting/v1/genhelper.go @@ -0,0 +1,209 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package forecasting + +import ( + "context" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/forecasting/v1/model.go b/forecasting/v1/model.go new file mode 100755 index 0000000..c35699f --- /dev/null +++ b/forecasting/v1/model.go @@ -0,0 +1,100 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package forecasting + +type ForecastingExperiment_State string + +const ( + ForecastingExperiment_State_Unspecified ForecastingExperiment_State = "" + // The forecasting experiment is currently running. + ForecastingExperiment_State_Running ForecastingExperiment_State = "RUNNING" + // The forecasting experiment has completed successfully. + ForecastingExperiment_State_Succeeded ForecastingExperiment_State = "SUCCEEDED" + // The forecasting experiment has failed. + ForecastingExperiment_State_Failed ForecastingExperiment_State = "FAILED" + // The forecasting experiment has been cancelled. + ForecastingExperiment_State_Cancelled ForecastingExperiment_State = "CANCELLED" +) + +type CreateForecastingExperimentRequest struct { + // The fully qualified path of a Unity Catalog table, formatted as + // catalog_name.schema_name.table_name, used as training data for the + // forecasting model. + TrainDataPath *string + // The column in the input training table used as the prediction target for + // model training. The values in this column are used as the ground truth for + // model training. + TargetColumn *string + // The column in the input training table that represents each row's timestamp. + TimeColumn *string + // The time interval between consecutive rows in the time series data. Possible + // values include: '1 second', '1 minute', '5 minutes', '10 minutes', '15 + // minutes', '30 minutes', 'Hourly', 'Daily', 'Weekly', 'Monthly', 'Quarterly', + // 'Yearly'. + ForecastGranularity *string + // The number of time steps into the future to make predictions, calculated as a + // multiple of forecast_granularity. This value represents how far ahead the + // model should forecast. + ForecastHorizon *int64 + // The evaluation metric used to optimize the forecasting model. + PrimaryMetric *string + // List of frameworks to include for model tuning. Possible values are + // 'Prophet', 'ARIMA', 'DeepAR'. An empty list includes all supported + // frameworks. + TrainingFrameworks []string + // The path in the workspace to store the created experiment. + ExperimentPath *string + // The maximum duration for the experiment in minutes. The experiment stops + // automatically if it exceeds this limit. + MaxRuntime *int64 + // // The column in the training table used for custom data splits. Values must + // be 'train', 'validate', or 'test'. + SplitColumn *string + // The column in the training table used to customize weights for each time + // series. + CustomWeightsColumn *string + // The fully qualified path of a Unity Catalog model, formatted as + // catalog_name.schema_name.model_name, used to store the best model. + RegisterTo *string + // The region code(s) to automatically add holiday features. Currently supports + // only one region. + HolidayRegions []string + // The column in the training table used to group the dataset for predicting + // individual time series. + TimeseriesIdentifierColumns []string + // The fully qualified path of a Unity Catalog table, formatted as + // catalog_name.schema_name.table_name, used to store predictions. + PredictionDataPath *string + // Specifies the list of feature columns to include in model training. These + // columns must exist in the training data and be of type string, numerical, or + // boolean. If not specified, no additional features will be included. Note: + // Certain columns are automatically handled: - Automatically excluded: + // split_column, target_column, custom_weights_column. - Automatically included: + // time_column. + IncludeFeatures []string + // The fully qualified path of a Unity Catalog table, formatted as + // catalog_name.schema_name.table_name, used to store future feature data for + // predictions. + FutureFeatureDataPath *string +} + +type CreateForecastingExperimentResponse struct { + // The unique ID of the created forecasting experiment + ExperimentId *string +} + +// Represents a forecasting experiment with its unique identifier, URL, and +// state.. +type ForecastingExperiment struct { + // The unique ID for the forecasting experiment. + ExperimentId *string + // The URL to the forecasting experiment page. + ExperimentPageUrl *string + // The current state of the forecasting experiment. + State ForecastingExperiment_State +} + +type GetForecastingExperimentRequest struct { + // The unique ID of a forecasting experiment + ExperimentId *string +} diff --git a/forecasting/v1/wire.go b/forecasting/v1/wire.go new file mode 100755 index 0000000..169b237 --- /dev/null +++ b/forecasting/v1/wire.go @@ -0,0 +1,78 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package forecasting + +type createForecastingExperimentRequestWire struct { + TrainDataPath *string `json:"train_data_path,omitempty"` + TargetColumn *string `json:"target_column,omitempty"` + TimeColumn *string `json:"time_column,omitempty"` + ForecastGranularity *string `json:"forecast_granularity,omitempty"` + ForecastHorizon *int64 `json:"forecast_horizon,omitempty"` + PrimaryMetric *string `json:"primary_metric,omitempty"` + TrainingFrameworks []string `json:"training_frameworks,omitempty"` + ExperimentPath *string `json:"experiment_path,omitempty"` + MaxRuntime *int64 `json:"max_runtime,omitempty"` + SplitColumn *string `json:"split_column,omitempty"` + CustomWeightsColumn *string `json:"custom_weights_column,omitempty"` + RegisterTo *string `json:"register_to,omitempty"` + HolidayRegions []string `json:"holiday_regions,omitempty"` + TimeseriesIdentifierColumns []string `json:"timeseries_identifier_columns,omitempty"` + PredictionDataPath *string `json:"prediction_data_path,omitempty"` + IncludeFeatures []string `json:"include_features,omitempty"` + FutureFeatureDataPath *string `json:"future_feature_data_path,omitempty"` +} + +func createForecastingExperimentRequestToWire(v *CreateForecastingExperimentRequest) (*createForecastingExperimentRequestWire, error) { + if v == nil { + return nil, nil + } + return &createForecastingExperimentRequestWire{ + TrainDataPath: v.TrainDataPath, + TargetColumn: v.TargetColumn, + TimeColumn: v.TimeColumn, + ForecastGranularity: v.ForecastGranularity, + ForecastHorizon: v.ForecastHorizon, + PrimaryMetric: v.PrimaryMetric, + TrainingFrameworks: v.TrainingFrameworks, + ExperimentPath: v.ExperimentPath, + MaxRuntime: v.MaxRuntime, + SplitColumn: v.SplitColumn, + CustomWeightsColumn: v.CustomWeightsColumn, + RegisterTo: v.RegisterTo, + HolidayRegions: v.HolidayRegions, + TimeseriesIdentifierColumns: v.TimeseriesIdentifierColumns, + PredictionDataPath: v.PredictionDataPath, + IncludeFeatures: v.IncludeFeatures, + FutureFeatureDataPath: v.FutureFeatureDataPath, + }, nil +} + +type createForecastingExperimentResponseWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` +} + +func createForecastingExperimentResponseFromWire(w *createForecastingExperimentResponseWire) (*CreateForecastingExperimentResponse, error) { + if w == nil { + return nil, nil + } + return &CreateForecastingExperimentResponse{ + ExperimentId: w.ExperimentId, + }, nil +} + +type forecastingExperimentWire struct { + ExperimentId *string `json:"experiment_id,omitempty"` + ExperimentPageUrl *string `json:"experiment_page_url,omitempty"` + State ForecastingExperiment_State `json:"state,omitempty"` +} + +func forecastingExperimentFromWire(w *forecastingExperimentWire) (*ForecastingExperiment, error) { + if w == nil { + return nil, nil + } + return &ForecastingExperiment{ + ExperimentId: w.ExperimentId, + ExperimentPageUrl: w.ExperimentPageUrl, + State: w.State, + }, nil +} diff --git a/genie/.package.json b/genie/.package.json new file mode 100644 index 0000000..17be283 --- /dev/null +++ b/genie/.package.json @@ -0,0 +1,3 @@ +{ + "package": "genie" +} diff --git a/genie/CHANGELOG.md b/genie/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/genie/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/genie/README.md b/genie/README.md new file mode 100644 index 0000000..fe23e6f --- /dev/null +++ b/genie/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/genie + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/genie@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/genie/v1" + +client, err := genie.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/genie/go.mod b/genie/go.mod new file mode 100644 index 0000000..a99d527 --- /dev/null +++ b/genie/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/genie + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/genie/internal/version.go b/genie/internal/version.go new file mode 100644 index 0000000..327b1b6 --- /dev/null +++ b/genie/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-genie" + +const Version = "0.0.1-dev.1" diff --git a/genie/v1/client.go b/genie/v1/client.go new file mode 100755 index 0000000..3b2a09e --- /dev/null +++ b/genie/v1/client.go @@ -0,0 +1,2284 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package genie + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/genie/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a Genie space from a serialized payload. +func (c *internalClient) CreateSpace(ctx context.Context, req *GenieCreateSpaceRequest, opts ...call.Option) (*GenieSpace, error) { + wireReq, err := genieCreateSpaceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/genie/spaces" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieSpace + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieSpaceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieSpaceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Download a rendered image of a message visualization attachment. The response +// body is the raw PNG image, not a JSON payload. This is only available if the +// attachment is a visualization and the message status is `COMPLETED`. This +// endpoint is not supported for Private Link workspaces. +func (c *internalClient) DownloadMessageAttachmentVisualization(ctx context.Context, req *DownloadMessageAttachmentVisualizationRequest, opts ...call.Option) (*DownloadMessageAttachmentVisualizationResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + headers.Set("Accept", "application/octet-stream") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/") + pb.singleSegment(*req.Name) + pb.literal("/download-visualization") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DownloadMessageAttachmentVisualizationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + httpResp, err := executeStreamingHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + resp = &DownloadMessageAttachmentVisualizationResponse{} + resp.Contents = httpResp.Body + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create new message in a [conversation](:method:genie/startconversation). The +// AI response uses all previously created messages in the conversation to +// respond. +func (c *internalClient) genieCreateConversationMessageBase(ctx context.Context, req *GenieCreateConversationMessageRequest, opts ...call.Option) (*GenieMessage, error) { + wireReq, err := genieCreateConversationMessageRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieMessage + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieMessageWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieMessageFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create new message in a [conversation](:method:genie/startconversation). The +// AI response uses all previously created messages in the conversation to +// respond. +func (c *internalClient) GenieCreateConversationMessage(ctx context.Context, req *GenieCreateConversationMessageRequest, opts ...call.Option) (*GenieCreateConversationMessageWaiter, error) { + if req.ConversationId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "ConversationId") + } + capturedConversationId := *req.ConversationId + if req.SpaceId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "SpaceId") + } + capturedSpaceId := *req.SpaceId + resp, err := c.genieCreateConversationMessageBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.MessageId == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "MessageId") + } + return &GenieCreateConversationMessageWaiter{ + poll: c.GenieGetConversationMessage, + messageId: *resp.MessageId, + conversationId: capturedConversationId, + spaceId: capturedSpaceId, + }, nil +} + +// GenieCreateConversationMessageWaiter tracks the state of the operation started by GenieCreateConversationMessage. +type GenieCreateConversationMessageWaiter struct { + poll func(context.Context, *GenieGetConversationMessageRequest, ...call.Option) (*GenieMessage, error) + messageId string + conversationId string + spaceId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *GenieCreateConversationMessageWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GenieGetConversationMessageRequest{ + MessageId: &w.messageId, + ConversationId: &w.conversationId, + SpaceId: &w.spaceId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case MessageStatus_MessageStatus_Completed, MessageStatus_MessageStatus_Failed: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *GenieCreateConversationMessageWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GenieMessage, error) { + var result *GenieMessage + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GenieGetConversationMessageRequest{ + MessageId: &w.messageId, + ConversationId: &w.conversationId, + SpaceId: &w.spaceId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case MessageStatus_MessageStatus_Completed: + result = pollResp + return nil + case MessageStatus_MessageStatus_Failed: + message := "(no message)" + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Create and run evaluations for multiple benchmark questions in a Genie space. +func (c *internalClient) GenieCreateEvalRun(ctx context.Context, req *GenieCreateEvalRunRequest, opts ...call.Option) (*GenieEvalRunResponse, error) { + wireReq, err := genieCreateEvalRunRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/eval-runs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieEvalRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieEvalRunResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieEvalRunResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a comment on a conversation message. +func (c *internalClient) GenieCreateMessageComment(ctx context.Context, req *GenieCreateMessageCommentRequest, opts ...call.Option) (*GenieMessageComment, error) { + wireReq, err := genieCreateMessageCommentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + pb.literal("/comments") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieMessageComment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieMessageCommentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieMessageCommentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a conversation. +func (c *internalClient) GenieDeleteConversation(ctx context.Context, req *GenieDeleteConversationRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete a conversation message. +func (c *internalClient) GenieDeleteConversationMessage(ctx context.Context, req *GenieDeleteConversationMessageRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Execute the SQL for a message query attachment. Use this API when the query +// attachment has expired and needs to be re-executed. +func (c *internalClient) GenieExecuteMessageAttachmentQuery(ctx context.Context, req *GenieExecuteMessageAttachmentQueryRequest, opts ...call.Option) (*GenieGetMessageQueryResultResponse, error) { + wireReq, err := genieExecuteMessageAttachmentQueryRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + pb.literal("/attachments/") + pb.singleSegment(*req.AttachmentId) + pb.literal("/execute-query") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieGetMessageQueryResultResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieGetMessageQueryResultResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieGetMessageQueryResultResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// DEPRECATED: Use [Execute Message Attachment +// Query](:method:genie/executemessageattachmentquery) instead. +func (c *internalClient) GenieExecuteMessageQuery(ctx context.Context, req *GenieExecuteMessageQueryRequest, opts ...call.Option) (*GenieGetMessageQueryResultResponse, error) { + wireReq, err := genieExecuteMessageQueryRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + pb.literal("/execute-query") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieGetMessageQueryResultResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieGetMessageQueryResultResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieGetMessageQueryResultResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Initiates a new SQL execution and returns a `download_id` and +// `download_id_signature` that you can use to track the progress of the +// download. The query result is stored in an external link and can be retrieved +// using the [Get Download Full Query +// Result](:method:genie/getdownloadfullqueryresult) API. Both `download_id` and +// `download_id_signature` must be provided when calling the Get endpoint. +// +// ---- +// +// ### **Warning: Databricks strongly recommends that you protect the URLs that +// are returned by the `EXTERNAL_LINKS` disposition.** +// +// When you use the `EXTERNAL_LINKS` disposition, a short-lived, URL is +// generated, which can be used to download the results directly from . As a +// short-lived is embedded in this URL, you should protect the URL. +// +// Because URLs are already generated with embedded temporary s, you must not +// set an `Authorization` header in the download requests. +// +// See [Execute Statement](:method:statementexecution/executestatement) for more +// details. +// +// ---- +func (c *internalClient) GenieGenerateDownloadFullQueryResult(ctx context.Context, req *GenieGenerateDownloadFullQueryResultRequest, opts ...call.Option) (*GenieGenerateDownloadFullQueryResultResponse, error) { + wireReq, err := genieGenerateDownloadFullQueryResultRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + pb.literal("/attachments/") + pb.singleSegment(*req.AttachmentId) + pb.literal("/downloads") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieGenerateDownloadFullQueryResultResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieGenerateDownloadFullQueryResultResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieGenerateDownloadFullQueryResultResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get message from conversation. +func (c *internalClient) GenieGetConversationMessage(ctx context.Context, req *GenieGetConversationMessageRequest, opts ...call.Option) (*GenieMessage, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieMessage + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieMessageWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieMessageFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// After [Generating a Full Query Result +// Download](:method:genie/generatedownloadfullqueryresult) and successfully +// receiving a `download_id` and `download_id_signature`, use this API to poll +// the download progress. Both `download_id` and `download_id_signature` are +// required to call this endpoint. When the download is complete, the API +// returns the result in the `EXTERNAL_LINKS` disposition, containing one or +// more external links to the query result files. +// +// ---- +// +// ### **Warning: Databricks strongly recommends that you protect the URLs that +// are returned by the `EXTERNAL_LINKS` disposition.** +// +// When you use the `EXTERNAL_LINKS` disposition, a short-lived, URL is +// generated, which can be used to download the results directly from . As a +// short-lived is embedded in this URL, you should protect the URL. +// +// Because URLs are already generated with embedded temporary s, you must not +// set an `Authorization` header in the download requests. +// +// See [Execute Statement](:method:statementexecution/executestatement) for more +// details. +// +// ---- +func (c *internalClient) GenieGetDownloadFullQueryResult(ctx context.Context, req *GenieGetDownloadFullQueryResultRequest, opts ...call.Option) (*GenieGetDownloadFullQueryResultResponse, error) { + wireReq, err := genieGetDownloadFullQueryResultRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + pb.literal("/attachments/") + pb.singleSegment(*req.AttachmentId) + pb.literal("/downloads/") + pb.singleSegment(*req.DownloadId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "download_id_signature", wireReq.DownloadIdSignature); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieGetDownloadFullQueryResultResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieGetDownloadFullQueryResultResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieGetDownloadFullQueryResultResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get details for evaluation results. +func (c *internalClient) GenieGetEvalResultDetails(ctx context.Context, req *GenieGetEvalResultDetailsRequest, opts ...call.Option) (*GenieEvalResultDetails, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/eval-runs/") + pb.singleSegment(*req.EvalRunId) + pb.literal("/results/") + pb.singleSegment(*req.ResultId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieEvalResultDetails + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieEvalResultDetailsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieEvalResultDetailsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get evaluation run details. +func (c *internalClient) GenieGetEvalRun(ctx context.Context, req *GenieGetEvalRunRequest, opts ...call.Option) (*GenieEvalRunResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/eval-runs/") + pb.singleSegment(*req.EvalRunId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieEvalRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieEvalRunResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieEvalRunResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get the result of SQL query if the message has a query attachment. This is +// only available if a message has a query attachment and the message status is +// `EXECUTING_QUERY` OR `COMPLETED`. +func (c *internalClient) GenieGetMessageAttachmentQueryResult(ctx context.Context, req *GenieGetMessageAttachmentQueryResultRequest, opts ...call.Option) (*GenieGetMessageQueryResultResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + pb.literal("/attachments/") + pb.singleSegment(*req.AttachmentId) + pb.literal("/query-result") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieGetMessageQueryResultResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieGetMessageQueryResultResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieGetMessageQueryResultResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// DEPRECATED: Use [Get Message Attachment Query +// Result](:method:genie/getmessageattachmentqueryresult) instead. +func (c *internalClient) GenieGetMessageQueryResult(ctx context.Context, req *GenieGetMessageQueryResultRequest, opts ...call.Option) (*GenieGetMessageQueryResultResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + pb.literal("/query-result") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieGetMessageQueryResultResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieGetMessageQueryResultResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieGetMessageQueryResultResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// DEPRECATED: Use [Get Message Attachment Query +// Result](:method:genie/getmessageattachmentqueryresult) instead. +func (c *internalClient) GenieGetQueryResultByAttachment(ctx context.Context, req *GenieGetQueryResultByAttachmentRequest, opts ...call.Option) (*GenieGetMessageQueryResultResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + pb.literal("/query-result/") + pb.singleSegment(*req.AttachmentId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieGetMessageQueryResultResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieGetMessageQueryResultResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieGetMessageQueryResultResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get details of a Genie Space. +func (c *internalClient) GenieGetSpace(ctx context.Context, req *GenieGetSpaceRequest, opts ...call.Option) (*GenieSpace, error) { + wireReq, err := genieGetSpaceRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_serialized_space", wireReq.IncludeSerializedSpace); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieSpace + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieSpaceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieSpaceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List all comments across all messages in a conversation. +func (c *internalClient) GenieListConversationComments(ctx context.Context, req *GenieListConversationCommentsRequest, opts ...call.Option) (*GenieListConversationCommentsResponse, error) { + wireReq, err := genieListConversationCommentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/list-comments") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieListConversationCommentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieListConversationCommentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieListConversationCommentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List messages in a conversation +func (c *internalClient) GenieListConversationMessages(ctx context.Context, req *GenieListConversationMessagesRequest, opts ...call.Option) (*GenieListConversationMessagesResponse, error) { + wireReq, err := genieListConversationMessagesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieListConversationMessagesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieListConversationMessagesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieListConversationMessagesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a list of conversations in a Genie Space. +func (c *internalClient) GenieListConversations(ctx context.Context, req *GenieListConversationsRequest, opts ...call.Option) (*GenieListConversationsResponse, error) { + wireReq, err := genieListConversationsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_all", wireReq.IncludeAll); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieListConversationsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieListConversationsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieListConversationsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List evaluation results for a specific evaluation run. +func (c *internalClient) GenieListEvalResults(ctx context.Context, req *GenieListEvalResultsRequest, opts ...call.Option) (*GenieListEvalResultsResponse, error) { + wireReq, err := genieListEvalResultsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/eval-runs/") + pb.singleSegment(*req.EvalRunId) + pb.literal("/results") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieListEvalResultsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieListEvalResultsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieListEvalResultsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists all evaluation runs in a space. +func (c *internalClient) GenieListEvalRuns(ctx context.Context, req *GenieListEvalRunsRequest, opts ...call.Option) (*GenieListEvalRunsResponse, error) { + wireReq, err := genieListEvalRunsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/eval-runs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieListEvalRunsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieListEvalRunsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieListEvalRunsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List comments on a specific conversation message. +func (c *internalClient) GenieListMessageComments(ctx context.Context, req *GenieListMessageCommentsRequest, opts ...call.Option) (*GenieListMessageCommentsResponse, error) { + wireReq, err := genieListMessageCommentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + pb.literal("/comments") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieListMessageCommentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieListMessageCommentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieListMessageCommentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get list of Genie Spaces. +func (c *internalClient) GenieListSpaces(ctx context.Context, req *GenieListSpacesRequest, opts ...call.Option) (*GenieListSpacesResponse, error) { + wireReq, err := genieListSpacesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/genie/spaces" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieListSpacesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieListSpacesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieListSpacesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Send feedback for a message. +func (c *internalClient) GenieSendMessageFeedback(ctx context.Context, req *GenieSendMessageFeedbackRequest, opts ...call.Option) error { + wireReq, err := genieSendMessageFeedbackRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/conversations/") + pb.singleSegment(*req.ConversationId) + pb.literal("/messages/") + pb.singleSegment(*req.MessageId) + pb.literal("/feedback") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Start a new conversation. +func (c *internalClient) genieStartConversationBase(ctx context.Context, req *GenieStartConversationRequest, opts ...call.Option) (*GenieStartConversationResponse, error) { + wireReq, err := genieStartConversationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + pb.literal("/start-conversation") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieStartConversationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieStartConversationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieStartConversationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Start a new conversation. +func (c *internalClient) GenieStartConversation(ctx context.Context, req *GenieStartConversationRequest, opts ...call.Option) (*GenieStartConversationWaiter, error) { + if req.SpaceId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "SpaceId") + } + capturedSpaceId := *req.SpaceId + resp, err := c.genieStartConversationBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.MessageId == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "MessageId") + } + if resp.ConversationId == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "ConversationId") + } + return &GenieStartConversationWaiter{ + poll: c.GenieGetConversationMessage, + messageId: *resp.MessageId, + conversationId: *resp.ConversationId, + spaceId: capturedSpaceId, + }, nil +} + +// GenieStartConversationWaiter tracks the state of the operation started by GenieStartConversation. +type GenieStartConversationWaiter struct { + poll func(context.Context, *GenieGetConversationMessageRequest, ...call.Option) (*GenieMessage, error) + messageId string + conversationId string + spaceId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *GenieStartConversationWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GenieGetConversationMessageRequest{ + MessageId: &w.messageId, + ConversationId: &w.conversationId, + SpaceId: &w.spaceId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case MessageStatus_MessageStatus_Completed, MessageStatus_MessageStatus_Failed: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *GenieStartConversationWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GenieMessage, error) { + var result *GenieMessage + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GenieGetConversationMessageRequest{ + MessageId: &w.messageId, + ConversationId: &w.conversationId, + SpaceId: &w.spaceId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.Status + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case MessageStatus_MessageStatus_Completed: + result = pollResp + return nil + case MessageStatus_MessageStatus_Failed: + message := "(no message)" + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Move a Genie Space to the trash. +func (c *internalClient) GenieTrashSpace(ctx context.Context, req *GenieTrashSpaceRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Updates a Genie space with a serialized payload. +func (c *internalClient) UpdateSpace(ctx context.Context, req *GenieUpdateSpaceRequest, opts ...call.Option) (*GenieSpace, error) { + wireReq, err := genieUpdateSpaceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/genie/spaces/") + pb.singleSegment(*req.SpaceId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenieSpace + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp genieSpaceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = genieSpaceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/genie/v1/genhelper.go b/genie/v1/genhelper.go new file mode 100755 index 0000000..8e95c97 --- /dev/null +++ b/genie/v1/genhelper.go @@ -0,0 +1,269 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package genie + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} + +// executeStreamingHTTPCall executes an HTTP call whose response body is a raw +// byte stream. On success it returns the response with its body still open, so +// the caller can stream and close it. On a non-2xx status it reads and closes +// the body to build the API error; the returned response is nil in that case. +func executeStreamingHTTPCall(opts httpCallOptions) (*http.Response, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, err + } + if resp.StatusCode >= 400 { + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if apiErr := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); apiErr != nil { + return nil, apiErr + } + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, []byte("")}) + return resp, nil +} diff --git a/genie/v1/model.go b/genie/v1/model.go new file mode 100755 index 0000000..fcd3654 --- /dev/null +++ b/genie/v1/model.go @@ -0,0 +1,1762 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package genie + +import ( + "io" + + "github.com/databricks/sdk-go/core/types" +) + +type ColumnTypeName string + +const ( + ColumnTypeName_Unspecified ColumnTypeName = "" + ColumnTypeName_Boolean ColumnTypeName = "BOOLEAN" + ColumnTypeName_Byte ColumnTypeName = "BYTE" + ColumnTypeName_Short ColumnTypeName = "SHORT" + ColumnTypeName_Int ColumnTypeName = "INT" + ColumnTypeName_Long ColumnTypeName = "LONG" + ColumnTypeName_Float ColumnTypeName = "FLOAT" + ColumnTypeName_Double ColumnTypeName = "DOUBLE" + ColumnTypeName_Date ColumnTypeName = "DATE" + ColumnTypeName_Timestamp ColumnTypeName = "TIMESTAMP" + ColumnTypeName_String ColumnTypeName = "STRING" + ColumnTypeName_Binary ColumnTypeName = "BINARY" + ColumnTypeName_Decimal ColumnTypeName = "DECIMAL" + ColumnTypeName_Interval ColumnTypeName = "INTERVAL" + ColumnTypeName_Array ColumnTypeName = "ARRAY" + ColumnTypeName_Struct ColumnTypeName = "STRUCT" + ColumnTypeName_Map ColumnTypeName = "MAP" + ColumnTypeName_Char ColumnTypeName = "CHAR" + ColumnTypeName_Null ColumnTypeName = "NULL" + ColumnTypeName_UserDefinedType ColumnTypeName = "USER_DEFINED_TYPE" + ColumnTypeName_TimestampNtz ColumnTypeName = "TIMESTAMP_NTZ" + ColumnTypeName_Variant ColumnTypeName = "VARIANT" + ColumnTypeName_Geometry ColumnTypeName = "GEOMETRY" + ColumnTypeName_Geography ColumnTypeName = "GEOGRAPHY" + ColumnTypeName_TableType ColumnTypeName = "TABLE_TYPE" +) + +// Error codes returned by Databricks APIs to indicate specific failure +// conditions. +type ErrorCode string + +const ( + ErrorCode_Unspecified ErrorCode = "" + // Internal error. This means that some invariants expected by the underlying + // system have been broken. This error code is reserved for serious errors, + // which generally cannot be resolved by the user. + // + // Prefer this over all kinds of detailed error messages (e.g IO_ERROR), unless + // there's some automation that relies on the custom error code. + // + // Maps to: - google.rpc.Code: INTERNAL = 13; - HTTP code: 500 Internal Server + // Error + ErrorCode_InternalError ErrorCode = "INTERNAL_ERROR" + // The service is currently unavailable. This is most likely a transient + // condition, which can be corrected by retrying with a backoff. Note that it is + // not always safe to retry non-idempotent operations. + // + // Prefer this over SERVICE_UNDER_MAINTENANCE, + // WORKSPACE_TEMPORARILY_UNAVAILABLE. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on how to pick this vs RESOURCE_EXHAUSTED. + // + // Maps to: - google.rpc.Code: UNAVAILABLE = 14; - HTTP code: 503 Service + // Unavailable + ErrorCode_TemporarilyUnavailable ErrorCode = "TEMPORARILY_UNAVAILABLE" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Indicates that an IOException has been internally + // thrown. + ErrorCode_IoError ErrorCode = "IO_ERROR" + // The request is invalid. Prefer more specific error code whenever possible. + // Also see similar recommendation for the google.rpc.Code.FAILED_PRECONDITION. + // + // Prefer this error code over MALFORMED_REQUEST, INVALID_STATE, + // UNPARSEABLE_HTTP_ERROR. + // + // Maps to: - google.rpc.Code: FAILED_PRECONDITION = 9; - HTTP code: 400 Bad + // Request + ErrorCode_BadRequest ErrorCode = "BAD_REQUEST" + // An external service is unavailable temporarily as it is being + // updated/re-deployed. Indicates gateway proxy to safely retry the request. + ErrorCode_ServiceUnderMaintenance ErrorCode = "SERVICE_UNDER_MAINTENANCE" + // A workspace is temporarily unavailable as the workspace is being re-assigned. + ErrorCode_WorkspaceTemporarilyUnavailable ErrorCode = "WORKSPACE_TEMPORARILY_UNAVAILABLE" + // The deadline expired before the operation could complete. For operations that + // change the state of the system, this error may be returned even if the + // operation has completed successfully. For example, a successful response from + // a server could have been delayed long enough for the deadline to expire. When + // possible - implementations should make sure further processing of the request + // is aborted, e.g. by throwing an exception instead of making the RPC request, + // making the database query, etc. + // + // Maps to: - google.rpc.Code: DEADLINE_EXCEEDED = 4; - HTTP code: 504 Gateway + // Timeout + ErrorCode_DeadlineExceeded ErrorCode = "DEADLINE_EXCEEDED" + // The operation was canceled by the caller. An example - client closed the + // connection without waiting for a response. + // + // Maps to: - google.rpc.Code: CANCELLED = 1; - HTTP code: 499 Client Closed + // Request + ErrorCode_Cancelled ErrorCode = "CANCELLED" + // The operation is rejected because of either rate limiting or resource quota, + // such as the client has sent too many requests recently or the client has + // allocated too many resources. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on how to pick this vs TEMPORARILY_UNAVAILABLE. + // + // Maps to: - google.rpc.Code: RESOURCE_EXHAUSTED = 8; - HTTP code: 429 Too Many + // Requests + ErrorCode_ResourceExhausted ErrorCode = "RESOURCE_EXHAUSTED" + // The operation was aborted, typically due to a concurrency issue such as a + // sequencer check failure, transaction abort, or transaction conflict. + // + // Maps to: - google.rpc.Code: ABORTED = 10; - HTTP code: 409 Conflict + ErrorCode_Aborted ErrorCode = "ABORTED" + // Operation was performed on a resource that does not exist, e.g. file or + // directory was not found. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_NotFound ErrorCode = "NOT_FOUND" + // Operation was rejected due a conflict with an existing resource, e.g. + // attempted to create file or directory that already exists. + // + // Prefer this over RESOURCE_CONFLICT. + // + // Maps to: - google.rpc.Code: ALREADY_EXISTS = 6; - HTTP code: 409 Conflict + ErrorCode_AlreadyExists ErrorCode = "ALREADY_EXISTS" + // The request does not have valid authentication (AuthN) credentials for the + // operation. + // + // Prefer this over CUSTOMER_UNAUTHORIZED, unless you need to keep consistent + // behavior with legacy code. For authorization (AuthZ) errors use + // PERMISSION_DENIED. Maps to: - google.rpc.Code: UNAUTHENTICATED = 16; - HTTP + // code: 401 Unauthorized + ErrorCode_Unauthenticated ErrorCode = "UNAUTHENTICATED" + // The service is currently unavailable. Please note that the unavailability may + // or may not be transient. That means if this is a non-transient condition, + // retrying it does not work. If the unavailability is certainly a transient + // condition, pleases use `TEMPORARILY_UNAVAILABLE` which signals its transient + // nature explicitly. An example of this error code’s use case is that when + // DNS resolution fails, the DNS resolver does not know whether it is because + // the domain name is completely wrong (non-transient situation) or the domain + // name is valid but the DNS server does not have an entry for this domain name + // yet (transient situation). Hence, `UNAVAILABLE` is suitable for this case. + // + // Maps to: - google.rpc.Code: UNAVAILABLE = 14; - HTTP code: 503 Service + // Unavailable + ErrorCode_Unavailable ErrorCode = "UNAVAILABLE" + // Supplied value for a parameter was invalid (e.g., giving a number for a + // string parameter). + // + // Maps to: - google.rpc.Code: INVALID_ARGUMENT = 3; - HTTP code: 400 Bad + // Request + ErrorCode_InvalidParameterValue ErrorCode = "INVALID_PARAMETER_VALUE" + // Indicates that the given API endpoint does not exist. Legacy, when possible - + // NOT_IMPLEMENTED should be used instead to indicate that API doesn't exist. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_EndpointNotFound ErrorCode = "ENDPOINT_NOT_FOUND" + // Indicates that the given API request was malformed. + ErrorCode_MalformedRequest ErrorCode = "MALFORMED_REQUEST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. If one or more of the inputs to a given RPC are not in + // a valid state for the action. + ErrorCode_InvalidState ErrorCode = "INVALID_STATE" + // The caller does not have permission to execute the specified operation. + // PERMISSION_DENIED must not be used for rejections caused by exhausting some + // resource, use RESOURCE_EXHAUSTED instead for those errors. PERMISSION_DENIED + // must not be used if the caller can not be identified, use + // CUSTOMER_UNAUTHORIZED instead for those errors. This error code does not + // imply the request is valid or the requested entity exists or satisfies other + // pre-conditions. + // + // Maps to: - google.rpc.Code: PERMISSION_DENIED = 7; - HTTP code: 403 Forbidden + ErrorCode_PermissionDenied ErrorCode = "PERMISSION_DENIED" + // NOTE: Deprecated due to inconsistent mapping in legacy code, see + // https://docs.google.com/document/d/17TZIKX_Y39cJMBr333lc-d5dTvvBLSu3DPUyGU5eMJg/edit?disco=AAAAzVGt6FA. + // Prefer using NOT_FOUND or PERMISSION_DENIED. + // + // If a given user/entity is trying to use a feature which has been disabled. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_FeatureDisabled ErrorCode = "FEATURE_DISABLED" + // The request does not have valid authentication (AuthN) credentials for the + // operation. + // + // For authentication (AuthN) errors prefer using UNAUTHENTICATED, unless you + // need to keep consistent behavior with legacy code. For authorization (AuthZ) + // errors use PERMISSION_DENIED. + // + // Important: name is confusing, this error code is for authentication (AuthN) + // errors, not authorization (AuthZ) errors. It maps to 401 Unauthorized and + // suffers from the same confusing naming. See + // https://datatracker.ietf.org/doc/html/rfc7235#section-3.1 - "[...] status + // code indicates that the request has not been applied because it lacks valid + // authentication credentials for the target resource. [...] If the request + // included authentication credentials, then the 401 response indicates that + // authorization has been refused for those credentials." + // + // Also, see https://stackoverflow.com/a/6937030/16352922, it covers it pretty + // well. + // + // Maps to: - google.rpc.Code: UNAUTHENTICATED = 16; - HTTP code: 401 + // Unauthorized + ErrorCode_CustomerUnauthorized ErrorCode = "CUSTOMER_UNAUTHORIZED" + // The operation is rejected because of request rate limit, for example rate + // limiting applied to users, workspaces, IP addresses, etc. + // + // Prefer a more generic RESOURCE_EXHAUSTED for the new use cases. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on the rate limiting vs throttling. + // + // Maps to: - google.rpc.Code: RESOURCE_EXHAUSTED = 8; - HTTP code: 429 Too Many + // Requests + ErrorCode_RequestLimitExceeded ErrorCode = "REQUEST_LIMIT_EXCEEDED" + // Indicates API request was rejected due a conflict with an existing resource. + ErrorCode_ResourceConflict ErrorCode = "RESOURCE_CONFLICT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Indicates that the HTTP response cannot be correctly + // deserialized. This currently is only used in DUST test clients, and not by + // any real service code. + ErrorCode_UnparseableHttpError ErrorCode = "UNPARSEABLE_HTTP_ERROR" + // The operation is not implemented or is not supported/enabled in this service. + // + // Maps to: - google.rpc.Code: UNIMPLEMENTED = 12; - HTTP code: 501 Not + // Implemented + ErrorCode_NotImplemented ErrorCode = "NOT_IMPLEMENTED" + // Unrecoverable data loss or corruption. + // + // One of the major use cases is to indicate that server failed to validate the + // integrity of the request. This error can occur when the checksum specified in + // the `X-Databricks-Checksum` request header (or trailer) doesn't match the + // actual request content checksum. + // + // Note, in case of the severe corruption that results in a malformed request, + // the server may send a generic `400 Bad Request` response rather than sending + // this error code. + // + // Maps to: - google.rpc.Code: DATA_LOSS = 15; - HTTP code: 500 Internal Server + // Error + ErrorCode_DataLoss ErrorCode = "DATA_LOSS" + // If the user attempts to perform an invalid state transition on a shard. + ErrorCode_InvalidStateTransition ErrorCode = "INVALID_STATE_TRANSITION" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Unable to perform the operation because the shard was + // locked by some other operation. + ErrorCode_CouldNotAcquireLock ErrorCode = "COULD_NOT_ACQUIRE_LOCK" + // NOTE: Deprecated, prefer using ALREADY_EXISTS. Unlike ALREADY_EXISTS - this + // maps to HTTP code 400 Bad Request due to legacy reasons, remapping will be a + // backwards incompatible change. + // + // Operation was performed on a resource that already exists. + ErrorCode_ResourceAlreadyExists ErrorCode = "RESOURCE_ALREADY_EXISTS" + // NOTE: Deprecated, prefer using NOT_FOUND - see the note for the + // RESOURCE_ALREADY_EXISTS, because this pair of codes is related and + // RESOURCE_ALREADY_EXISTS has bad mapping to the HTTP codes we added new error + // codes NOT_FOUND and ALREADY_EXISTS, and recommend to use them instead. + // + // Operation was performed on a resource that does not exist. + ErrorCode_ResourceDoesNotExist ErrorCode = "RESOURCE_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_QuotaExceeded ErrorCode = "QUOTA_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxBlockSizeExceeded ErrorCode = "MAX_BLOCK_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxReadSizeExceeded ErrorCode = "MAX_READ_SIZE_EXCEEDED" + ErrorCode_PartialDelete ErrorCode = "PARTIAL_DELETE" + ErrorCode_MaxListSizeExceeded ErrorCode = "MAX_LIST_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DryRunFailed ErrorCode = "DRY_RUN_FAILED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Cluster request was rejected because it would exceed a + // resource limit. + ErrorCode_ResourceLimitExceeded ErrorCode = "RESOURCE_LIMIT_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DirectoryNotEmpty ErrorCode = "DIRECTORY_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DirectoryProtected ErrorCode = "DIRECTORY_PROTECTED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxNotebookSizeExceeded ErrorCode = "MAX_NOTEBOOK_SIZE_EXCEEDED" + ErrorCode_MaxChildNodeSizeExceeded ErrorCode = "MAX_CHILD_NODE_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SearchQueryTooLong ErrorCode = "SEARCH_QUERY_TOO_LONG" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SearchQueryTooShort ErrorCode = "SEARCH_QUERY_TOO_SHORT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ManagedResourceGroupDoesNotExist ErrorCode = "MANAGED_RESOURCE_GROUP_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_PermissionNotPropagated ErrorCode = "PERMISSION_NOT_PROPAGATED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DeploymentTimeout ErrorCode = "DEPLOYMENT_TIMEOUT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitConflict ErrorCode = "GIT_CONFLICT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitUnknownRef ErrorCode = "GIT_UNKNOWN_REF" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitSensitiveTokenDetected ErrorCode = "GIT_SENSITIVE_TOKEN_DETECTED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitUrlNotOnAllowList ErrorCode = "GIT_URL_NOT_ON_ALLOW_LIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitRemoteError ErrorCode = "GIT_REMOTE_ERROR" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProjectsOperationTimeout ErrorCode = "PROJECTS_OPERATION_TIMEOUT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_IpynbFileInRepo ErrorCode = "IPYNB_FILE_IN_REPO" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_InsecurePartnerResponse ErrorCode = "INSECURE_PARTNER_RESPONSE" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MalformedPartnerResponse ErrorCode = "MALFORMED_PARTNER_RESPONSE" + ErrorCode_MetastoreDoesNotExist ErrorCode = "METASTORE_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DacDoesNotExist ErrorCode = "DAC_DOES_NOT_EXIST" + ErrorCode_CatalogDoesNotExist ErrorCode = "CATALOG_DOES_NOT_EXIST" + ErrorCode_SchemaDoesNotExist ErrorCode = "SCHEMA_DOES_NOT_EXIST" + ErrorCode_TableDoesNotExist ErrorCode = "TABLE_DOES_NOT_EXIST" + ErrorCode_ShareDoesNotExist ErrorCode = "SHARE_DOES_NOT_EXIST" + ErrorCode_RecipientDoesNotExist ErrorCode = "RECIPIENT_DOES_NOT_EXIST" + ErrorCode_StorageCredentialDoesNotExist ErrorCode = "STORAGE_CREDENTIAL_DOES_NOT_EXIST" + ErrorCode_ExternalLocationDoesNotExist ErrorCode = "EXTERNAL_LOCATION_DOES_NOT_EXIST" + ErrorCode_PrincipalDoesNotExist ErrorCode = "PRINCIPAL_DOES_NOT_EXIST" + ErrorCode_ProviderDoesNotExist ErrorCode = "PROVIDER_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MetastoreAlreadyExists ErrorCode = "METASTORE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DacAlreadyExists ErrorCode = "DAC_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_CatalogAlreadyExists ErrorCode = "CATALOG_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SchemaAlreadyExists ErrorCode = "SCHEMA_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_TableAlreadyExists ErrorCode = "TABLE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ShareAlreadyExists ErrorCode = "SHARE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_RecipientAlreadyExists ErrorCode = "RECIPIENT_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_StorageCredentialAlreadyExists ErrorCode = "STORAGE_CREDENTIAL_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ExternalLocationAlreadyExists ErrorCode = "EXTERNAL_LOCATION_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProviderAlreadyExists ErrorCode = "PROVIDER_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_CatalogNotEmpty ErrorCode = "CATALOG_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SchemaNotEmpty ErrorCode = "SCHEMA_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MetastoreNotEmpty ErrorCode = "METASTORE_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProviderShareNotAccessible ErrorCode = "PROVIDER_SHARE_NOT_ACCESSIBLE" +) + +type EvaluationStatusType string + +const ( + EvaluationStatusType_Unspecified EvaluationStatusType = "" + EvaluationStatusType_Running EvaluationStatusType = "RUNNING" + EvaluationStatusType_Done EvaluationStatusType = "DONE" + EvaluationStatusType_NotStarted EvaluationStatusType = "NOT_STARTED" + EvaluationStatusType_EvaluationFailed EvaluationStatusType = "EVALUATION_FAILED" + EvaluationStatusType_EvaluationCancelled EvaluationStatusType = "EVALUATION_CANCELLED" + EvaluationStatusType_EvaluationTimeout EvaluationStatusType = "EVALUATION_TIMEOUT" +) + +type Format string + +const ( + Format_Unspecified Format = "" + Format_JsonArray Format = "JSON_ARRAY" + Format_ArrowStream Format = "ARROW_STREAM" + Format_Csv Format = "CSV" +) + +// The type of a Genie conversation. Distinguishes an agent-mode conversation +// from a classic chat conversation so callers can route message retrieval +// accordingly without a per-conversation lookup. +type GenieConversationType string + +const ( + GenieConversationType_Unspecified GenieConversationType = "" + // A classic Genie chat conversation. + GenieConversationType_GenieConversationTypeChat GenieConversationType = "GENIE_CONVERSATION_TYPE_CHAT" + // An agent-mode conversation. + GenieConversationType_GenieConversationTypeAgent GenieConversationType = "GENIE_CONVERSATION_TYPE_AGENT" +) + +type GenieEvalAssessment string + +const ( + GenieEvalAssessment_Unspecified GenieEvalAssessment = "" + GenieEvalAssessment_Good GenieEvalAssessment = "GOOD" + GenieEvalAssessment_Bad GenieEvalAssessment = "BAD" + GenieEvalAssessment_NeedsReview GenieEvalAssessment = "NEEDS_REVIEW" +) + +type GenieEvalResponseType string + +const ( + GenieEvalResponseType_Unspecified GenieEvalResponseType = "" + GenieEvalResponseType_Text GenieEvalResponseType = "TEXT" + GenieEvalResponseType_Sql GenieEvalResponseType = "SQL" +) + +// Feedback rating for Genie messages +type GenieFeedbackRating string + +const ( + GenieFeedbackRating_Unspecified GenieFeedbackRating = "" + GenieFeedbackRating_Positive GenieFeedbackRating = "POSITIVE" + GenieFeedbackRating_Negative GenieFeedbackRating = "NEGATIVE" + GenieFeedbackRating_None GenieFeedbackRating = "NONE" +) + +// copied from proto3 / Google Well Known Types, source: +// https://github.com/protocolbuffers/protobuf/blob/450d24ca820750c5db5112a6f0b0c2efb9758021/src/google/protobuf/struct.proto +// `NullValue` is a singleton enumeration to represent the null value for the +// `Value` type union. +// +// The JSON representation for `NullValue` is JSON `null`. +type NullValue string + +const ( + NullValue_Unspecified NullValue = "" +) + +type ScoreReason string + +const ( + ScoreReason_Unspecified ScoreReason = "" + ScoreReason_EmptyResult ScoreReason = "EMPTY_RESULT" + ScoreReason_ResultMissingRows ScoreReason = "RESULT_MISSING_ROWS" + ScoreReason_ResultExtraRows ScoreReason = "RESULT_EXTRA_ROWS" + ScoreReason_ResultMissingColumns ScoreReason = "RESULT_MISSING_COLUMNS" + ScoreReason_ResultExtraColumns ScoreReason = "RESULT_EXTRA_COLUMNS" + ScoreReason_SingleCellDifference ScoreReason = "SINGLE_CELL_DIFFERENCE" + ScoreReason_EmptyGoodSql ScoreReason = "EMPTY_GOOD_SQL" + ScoreReason_ColumnTypeDifference ScoreReason = "COLUMN_TYPE_DIFFERENCE" + // Deprecated LLM Judge error categories - kept for backward compatibility + ScoreReason_LlmJudgeMissingJoin ScoreReason = "LLM_JUDGE_MISSING_JOIN" + ScoreReason_LlmJudgeWrongFilter ScoreReason = "LLM_JUDGE_WRONG_FILTER" + ScoreReason_LlmJudgeWrongAggregation ScoreReason = "LLM_JUDGE_WRONG_AGGREGATION" + ScoreReason_LlmJudgeWrongColumns ScoreReason = "LLM_JUDGE_WRONG_COLUMNS" + ScoreReason_LlmJudgeSyntaxError ScoreReason = "LLM_JUDGE_SYNTAX_ERROR" + ScoreReason_LlmJudgeSemanticError ScoreReason = "LLM_JUDGE_SEMANTIC_ERROR" + // New LLM Judge error categories - aligned with LlmJudgeFunctionSpec + ScoreReason_LlmJudgeOther ScoreReason = "LLM_JUDGE_OTHER" + ScoreReason_LlmJudgeMissingOrIncorrectFilter ScoreReason = "LLM_JUDGE_MISSING_OR_INCORRECT_FILTER" + ScoreReason_LlmJudgeIncompleteOrPartialOutput ScoreReason = "LLM_JUDGE_INCOMPLETE_OR_PARTIAL_OUTPUT" + ScoreReason_LlmJudgeMisinterpretationOfUserRequest ScoreReason = "LLM_JUDGE_MISINTERPRETATION_OF_USER_REQUEST" + ScoreReason_LlmJudgeInstructionComplianceOrMissingBusinessLogic ScoreReason = "LLM_JUDGE_INSTRUCTION_COMPLIANCE_OR_MISSING_BUSINESS_LOGIC" + ScoreReason_LlmJudgeIncorrectMetricCalculation ScoreReason = "LLM_JUDGE_INCORRECT_METRIC_CALCULATION" + ScoreReason_LlmJudgeIncorrectTableOrFieldUsage ScoreReason = "LLM_JUDGE_INCORRECT_TABLE_OR_FIELD_USAGE" + ScoreReason_LlmJudgeIncorrectFunctionUsage ScoreReason = "LLM_JUDGE_INCORRECT_FUNCTION_USAGE" + ScoreReason_LlmJudgeMissingOrIncorrectJoin ScoreReason = "LLM_JUDGE_MISSING_OR_INCORRECT_JOIN" + ScoreReason_LlmJudgeMissingOrIncorrectAggregation ScoreReason = "LLM_JUDGE_MISSING_OR_INCORRECT_AGGREGATION" + ScoreReason_LlmJudgeFormattingError ScoreReason = "LLM_JUDGE_FORMATTING_ERROR" +) + +// Purpose/intent of a text attachment +type TextAttachmentPurpose string + +const ( + TextAttachmentPurpose_Unspecified TextAttachmentPurpose = "" + // A clarifying question Genie asks back to the user, not the answer. + TextAttachmentPurpose_FollowUpQuestion TextAttachmentPurpose = "FOLLOW_UP_QUESTION" + // The final answer / summary for the message. Consumers reading the Get Message + // API can use this to identify which text attachment holds the answer. + TextAttachmentPurpose_TextAttachmentPurposeAnswer TextAttachmentPurpose = "TEXT_ATTACHMENT_PURPOSE_ANSWER" +) + +// ThoughtType. The possible values are: * `THOUGHT_TYPE_UNSPECIFIED`: Default +// value that should not be used. * `THOUGHT_TYPE_DESCRIPTION`: A high-level +// description of how the question was interpreted. * +// `THOUGHT_TYPE_UNDERSTANDING`: How ambiguous parts of the question were +// resolved. * `THOUGHT_TYPE_DATA_SOURCING`: Which tables or datasets were +// identified as relevant. * `THOUGHT_TYPE_INSTRUCTIONS`: Which author-defined +// instructions were referenced. * `THOUGHT_TYPE_STEPS`: The logical steps taken +// to compute the answer. The category of a Thought. Additional values may be +// added in the future. +type ThoughtType string + +const ( + ThoughtType_Unspecified ThoughtType = "" + // A high-level description of how the question was interpreted. + ThoughtType_ThoughtTypeDescription ThoughtType = "THOUGHT_TYPE_DESCRIPTION" + // How ambiguous parts of the question were resolved. + ThoughtType_ThoughtTypeUnderstanding ThoughtType = "THOUGHT_TYPE_UNDERSTANDING" + // Which tables or datasets were identified as relevant. + ThoughtType_ThoughtTypeDataSourcing ThoughtType = "THOUGHT_TYPE_DATA_SOURCING" + // Which author-defined instructions were referenced. + ThoughtType_ThoughtTypeInstructions ThoughtType = "THOUGHT_TYPE_INSTRUCTIONS" + // The logical steps taken to compute the answer. + ThoughtType_ThoughtTypeSteps ThoughtType = "THOUGHT_TYPE_STEPS" +) + +type MessageError_Type string + +const ( + MessageError_Type_Unspecified MessageError_Type = "" + MessageError_Type_UnexpectedReplyProcessException MessageError_Type = "UNEXPECTED_REPLY_PROCESS_EXCEPTION" + MessageError_Type_GenericChatCompletionException MessageError_Type = "GENERIC_CHAT_COMPLETION_EXCEPTION" + // TokenCounter estimates were off and OpenAi responds with an error due to the + // token limit. + MessageError_Type_ContextExceededException MessageError_Type = "CONTEXT_EXCEEDED_EXCEPTION" + MessageError_Type_DeploymentNotFoundException MessageError_Type = "DEPLOYMENT_NOT_FOUND_EXCEPTION" + MessageError_Type_FunctionsNotAvailableException MessageError_Type = "FUNCTIONS_NOT_AVAILABLE_EXCEPTION" + MessageError_Type_InvalidCompletionRequestException MessageError_Type = "INVALID_COMPLETION_REQUEST_EXCEPTION" + MessageError_Type_ContentFilterException MessageError_Type = "CONTENT_FILTER_EXCEPTION" + MessageError_Type_FunctionArgumentsInvalidJsonException MessageError_Type = "FUNCTION_ARGUMENTS_INVALID_JSON_EXCEPTION" + MessageError_Type_RetryableProcessingException MessageError_Type = "RETRYABLE_PROCESSING_EXCEPTION" + MessageError_Type_InvalidFunctionCallException MessageError_Type = "INVALID_FUNCTION_CALL_EXCEPTION" + // Request can not fit into model or the configured limits and TokenCounter + // registers token limit exceeded. + MessageError_Type_LocalContextExceededException MessageError_Type = "LOCAL_CONTEXT_EXCEEDED_EXCEPTION" + MessageError_Type_ChatCompletionNetworkException MessageError_Type = "CHAT_COMPLETION_NETWORK_EXCEPTION" + MessageError_Type_InvalidChatCompletionJsonException MessageError_Type = "INVALID_CHAT_COMPLETION_JSON_EXCEPTION" + MessageError_Type_GenericChatCompletionServiceException MessageError_Type = "GENERIC_CHAT_COMPLETION_SERVICE_EXCEPTION" + MessageError_Type_WarehouseAccessMissingException MessageError_Type = "WAREHOUSE_ACCESS_MISSING_EXCEPTION" + MessageError_Type_WarehouseNotFoundException MessageError_Type = "WAREHOUSE_NOT_FOUND_EXCEPTION" + MessageError_Type_NoTablesToQueryException MessageError_Type = "NO_TABLES_TO_QUERY_EXCEPTION" + MessageError_Type_SqlExecutionException MessageError_Type = "SQL_EXECUTION_EXCEPTION" + MessageError_Type_ReplyProcessTimeoutException MessageError_Type = "REPLY_PROCESS_TIMEOUT_EXCEPTION" + MessageError_Type_CouldNotGetUcSchemaException MessageError_Type = "COULD_NOT_GET_UC_SCHEMA_EXCEPTION" + MessageError_Type_InvalidTableIdentifierException MessageError_Type = "INVALID_TABLE_IDENTIFIER_EXCEPTION" + MessageError_Type_TooManyTablesException MessageError_Type = "TOO_MANY_TABLES_EXCEPTION" + MessageError_Type_FunctionArgumentsInvalidException MessageError_Type = "FUNCTION_ARGUMENTS_INVALID_EXCEPTION" + MessageError_Type_GenericSqlExecApiCallException MessageError_Type = "GENERIC_SQL_EXEC_API_CALL_EXCEPTION" + MessageError_Type_ChatCompletionClientException MessageError_Type = "CHAT_COMPLETION_CLIENT_EXCEPTION" + MessageError_Type_ChatCompletionClientTimeoutException MessageError_Type = "CHAT_COMPLETION_CLIENT_TIMEOUT_EXCEPTION" + MessageError_Type_UnknownAiModel MessageError_Type = "UNKNOWN_AI_MODEL" + MessageError_Type_TablesMissingException MessageError_Type = "TABLES_MISSING_EXCEPTION" + MessageError_Type_MessageDeletedWhileExecutingException MessageError_Type = "MESSAGE_DELETED_WHILE_EXECUTING_EXCEPTION" + MessageError_Type_MessageUpdatedWhileExecutingException MessageError_Type = "MESSAGE_UPDATED_WHILE_EXECUTING_EXCEPTION" + MessageError_Type_BlockMultipleExecutionsException MessageError_Type = "BLOCK_MULTIPLE_EXECUTIONS_EXCEPTION" + MessageError_Type_InvalidCertifiedAnswerIdentifierException MessageError_Type = "INVALID_CERTIFIED_ANSWER_IDENTIFIER_EXCEPTION" + MessageError_Type_TooManyCertifiedAnswersException MessageError_Type = "TOO_MANY_CERTIFIED_ANSWERS_EXCEPTION" + MessageError_Type_RateLimitExceededGenericException MessageError_Type = "RATE_LIMIT_EXCEEDED_GENERIC_EXCEPTION" + MessageError_Type_RateLimitExceededSpecifiedWaitException MessageError_Type = "RATE_LIMIT_EXCEEDED_SPECIFIED_WAIT_EXCEPTION" + MessageError_Type_FunctionCallMissingParameterException MessageError_Type = "FUNCTION_CALL_MISSING_PARAMETER_EXCEPTION" + MessageError_Type_InvalidCertifiedAnswerFunctionException MessageError_Type = "INVALID_CERTIFIED_ANSWER_FUNCTION_EXCEPTION" + MessageError_Type_IllegalParameterDefinitionException MessageError_Type = "ILLEGAL_PARAMETER_DEFINITION_EXCEPTION" + MessageError_Type_NoQueryToVisualizeException MessageError_Type = "NO_QUERY_TO_VISUALIZE_EXCEPTION" + MessageError_Type_NoDeploymentsAvailableToWorkspace MessageError_Type = "NO_DEPLOYMENTS_AVAILABLE_TO_WORKSPACE" + MessageError_Type_StopProcessDueToAutoRegenerate MessageError_Type = "STOP_PROCESS_DUE_TO_AUTO_REGENERATE" + MessageError_Type_FunctionArgumentsInvalidTypeException MessageError_Type = "FUNCTION_ARGUMENTS_INVALID_TYPE_EXCEPTION" + MessageError_Type_MessageCancelledWhileExecutingException MessageError_Type = "MESSAGE_CANCELLED_WHILE_EXECUTING_EXCEPTION" + MessageError_Type_CouldNotGetModelDeploymentsException MessageError_Type = "COULD_NOT_GET_MODEL_DEPLOYMENTS_EXCEPTION" + MessageError_Type_GeneratedSqlQueryTooLongException MessageError_Type = "GENERATED_SQL_QUERY_TOO_LONG_EXCEPTION" + MessageError_Type_MissingSqlQueryException MessageError_Type = "MISSING_SQL_QUERY_EXCEPTION" + MessageError_Type_DescribeQueryUnexpectedFailure MessageError_Type = "DESCRIBE_QUERY_UNEXPECTED_FAILURE" + MessageError_Type_DescribeQueryTimeout MessageError_Type = "DESCRIBE_QUERY_TIMEOUT" + MessageError_Type_DescribeQueryInvalidSqlError MessageError_Type = "DESCRIBE_QUERY_INVALID_SQL_ERROR" + MessageError_Type_InvalidSqlUnknownTableException MessageError_Type = "INVALID_SQL_UNKNOWN_TABLE_EXCEPTION" + MessageError_Type_InvalidSqlMultipleStatementsException MessageError_Type = "INVALID_SQL_MULTIPLE_STATEMENTS_EXCEPTION" + MessageError_Type_InvalidSqlMultipleDatasetReferencesException MessageError_Type = "INVALID_SQL_MULTIPLE_DATASET_REFERENCES_EXCEPTION" + MessageError_Type_MessageAttachmentTooLongError MessageError_Type = "MESSAGE_ATTACHMENT_TOO_LONG_ERROR" + MessageError_Type_InternalCatalogPathOverlapException MessageError_Type = "INTERNAL_CATALOG_PATH_OVERLAP_EXCEPTION" + MessageError_Type_InternalCatalogMissingUcPathException MessageError_Type = "INTERNAL_CATALOG_MISSING_UC_PATH_EXCEPTION" + MessageError_Type_ExceededMaxTokenLengthException MessageError_Type = "EXCEEDED_MAX_TOKEN_LENGTH_EXCEPTION" + MessageError_Type_InternalCatalogAssetCreationOngoingException MessageError_Type = "INTERNAL_CATALOG_ASSET_CREATION_ONGOING_EXCEPTION" + MessageError_Type_InternalCatalogAssetCreationFailedException MessageError_Type = "INTERNAL_CATALOG_ASSET_CREATION_FAILED_EXCEPTION" + MessageError_Type_InternalCatalogAssetCreationUnsupportedException MessageError_Type = "INTERNAL_CATALOG_ASSET_CREATION_UNSUPPORTED_EXCEPTION" + MessageError_Type_UnsupportedConversationTypeException MessageError_Type = "UNSUPPORTED_CONVERSATION_TYPE_EXCEPTION" + MessageError_Type_CouldNotGetDashboardSchemaException MessageError_Type = "COULD_NOT_GET_DASHBOARD_SCHEMA_EXCEPTION" +) + +// MessageStatus. The possible values are: * `FETCHING_METADATA`: Fetching +// metadata from the data sources. * `FILTERING_CONTEXT`: Running smart context +// step to determine relevant context. * `ASKING_AI`: Waiting for the LLM to +// respond to the user's question. * `PENDING_WAREHOUSE`: Waiting for warehouse +// before the SQL query can start executing. * `EXECUTING_QUERY`: Executing a +// generated SQL query. Get the SQL query result by calling +// [getMessageAttachmentQueryResult](:method:genie/getMessageAttachmentQueryResult) +// API. * `FAILED`: The response generation or query execution failed. See +// `error` field. * `COMPLETED`: Message processing is completed. Results are in +// the `attachments` field. Get the SQL query result by calling +// [getMessageAttachmentQueryResult](:method:genie/getMessageAttachmentQueryResult) +// API. * `SUBMITTED`: Message has been submitted. * `QUERY_RESULT_EXPIRED`: SQL +// result is not available anymore. The user needs to rerun the query. Rerun the +// SQL query result by calling +// [executeMessageAttachmentQuery](:method:genie/executeMessageAttachmentQuery) +// API. * `CANCELLED`: Message has been cancelled. +type MessageStatus_MessageStatus string + +const ( + MessageStatus_MessageStatus_Unspecified MessageStatus_MessageStatus = "" + MessageStatus_MessageStatus_FetchingMetadata MessageStatus_MessageStatus = "FETCHING_METADATA" + MessageStatus_MessageStatus_FilteringContext MessageStatus_MessageStatus = "FILTERING_CONTEXT" + MessageStatus_MessageStatus_AskingAi MessageStatus_MessageStatus = "ASKING_AI" + MessageStatus_MessageStatus_PendingWarehouse MessageStatus_MessageStatus = "PENDING_WAREHOUSE" + MessageStatus_MessageStatus_ExecutingQuery MessageStatus_MessageStatus = "EXECUTING_QUERY" + MessageStatus_MessageStatus_Failed MessageStatus_MessageStatus = "FAILED" + MessageStatus_MessageStatus_Completed MessageStatus_MessageStatus = "COMPLETED" + MessageStatus_MessageStatus_Submitted MessageStatus_MessageStatus = "SUBMITTED" + MessageStatus_MessageStatus_QueryResultExpired MessageStatus_MessageStatus = "QUERY_RESULT_EXPIRED" + MessageStatus_MessageStatus_Cancelled MessageStatus_MessageStatus = "CANCELLED" +) + +type StatementStatus_State string + +const ( + StatementStatus_State_Unspecified StatementStatus_State = "" + StatementStatus_State_Pending StatementStatus_State = "PENDING" + StatementStatus_State_Running StatementStatus_State = "RUNNING" + StatementStatus_State_Succeeded StatementStatus_State = "SUCCEEDED" + StatementStatus_State_Failed StatementStatus_State = "FAILED" + StatementStatus_State_Canceled StatementStatus_State = "CANCELED" + StatementStatus_State_Closed StatementStatus_State = "CLOSED" +) + +type ChunkInfo struct { + // The position within the sequence of result set chunks. + ChunkIndex *int + // The starting row offset within the result set. + RowOffset *int64 + // The number of rows within the result chunk. + RowCount *int64 + // The number of bytes in the result chunk. This field is not available when + // using `INLINE` disposition. + ByteCount *int64 + // When fetching, provides the `chunk_index` for the _next_ chunk. If absent, + // indicates there are no more chunks. The next chunk can be fetched with a + // :method:statementexecution/getstatementresultchunkn request. + NextChunkIndex *int + // When fetching, provides a link to fetch the _next_ chunk. If absent, + // indicates there are no more chunks. This link is an absolute `path` to be + // joined with your `$DATABRICKS_HOST`, and should be treated as an opaque link. + // This is an alternative to using `next_chunk_index`. + NextChunkInternalLink *string +} + +type ColumnInfo struct { + // Name of Column. + Name *string + // Full data type specification as SQL/catalogString text. + TypeText *string + TypeName ColumnTypeName + // Ordinal position of column (starting at position 0). + Position *int + // Digits of precision; required for DecimalTypes. + TypePrecision *int + // Digits to right of decimal; Required for DecimalTypes. + TypeScale *int + // Format of IntervalType. + TypeIntervalType *string + // Full data type specification, JSON-serialized. + TypeJson *string + // User-provided free-form text description. + Comment *string + // Whether field may be Null (default: true). + Nullable *bool + // Partition index for column. + PartitionIndex *int + Mask *ColumnMask +} + +type ColumnMask struct { + // The full name of the column mask SQL UDF. + FunctionName *string + // The list of additional table columns to be passed as input to the column mask + // function. The first arg of the mask function should be of the type of the + // column being masked and the types of the rest of the args should match the + // types of columns in 'using_column_names'. + UsingColumnNames []string + // The list of additional table columns or literals to be passed as additional + // arguments to a column mask function. This is the replacement of the + // deprecated using_column_names field and carries information about the types + // (alias or constant) of the arguments to the mask function. + UsingArguments []PolicyFunctionArgument +} + +// Serialization format for DatabricksServiceException. Note the definition of +// this message should be in sync with +// DatabricksServiceExceptionWithDetailsProto defined in +// /api-base/proto/exception_with_details.proto except the later one has an +// extra error details field defined.. +type DatabricksServiceExceptionProto struct { + ErrorCode ErrorCode + Message *string + StackTrace *string +} + +type DownloadMessageAttachmentVisualizationRequest struct { + // The resource name of the attachment to render, in the format + // `spaces/{space_id}/conversations/{conversation_id}/messages/{message_id}/attachments/{attachment_id}`. + Name *string +} + +type DownloadMessageAttachmentVisualizationResponse struct { + // The rendered visualization as a PNG image. Returned as the raw HTTP response + // body rather than a JSON field. + Contents io.ReadCloser +} + +type ExternalLink struct { + // A URL pointing to a chunk of result data, hosted by an external service, with + // a short expiration time (<= 15 minutes). As this URL contains a temporary + // credential, it should be considered sensitive and the client should not + // expose this URL in a log. + ExternalLink *string + // Indicates the date-time that the given external link will expire and becomes + // invalid, after which point a new `external_link` must be requested. + Expiration *string + // HTTP headers that must be included with a GET request to the `external_link`. + // Each header is provided as a key-value pair. Headers are typically used to + // pass a decryption key to the external service. The values of these headers + // should be considered sensitive and the client should not expose these values + // in a log. + HttpHeaders map[string]string + // The position within the sequence of result set chunks. + ChunkIndex *int + // The starting row offset within the result set. + RowOffset *int64 + // The number of rows within the result chunk. + RowCount *int64 + // The number of bytes in the result chunk. This field is not available when + // using `INLINE` disposition. + ByteCount *int64 + // When fetching, provides the `chunk_index` for the _next_ chunk. If absent, + // indicates there are no more chunks. The next chunk can be fetched with a + // :method:statementexecution/getstatementresultchunkn request. + NextChunkIndex *int + // When fetching, provides a link to fetch the _next_ chunk. If absent, + // indicates there are no more chunks. This link is an absolute `path` to be + // joined with your `$DATABRICKS_HOST`, and should be treated as an opaque link. + // This is an alternative to using `next_chunk_index`. + NextChunkInternalLink *string +} + +// Genie AI Response. +type GenieAttachment struct { + Attachment isGenieAttachment_Attachment + // Attachment ID + AttachmentId *string +} + +type isGenieAttachment_Attachment interface { + isGenieAttachment_Attachment() +} + +// GenieAttachment_Attachment_Text selects Text for GenieAttachment.Attachment. +// Text Attachment if Genie responds with text This also contains the final +// summary when available. +type GenieAttachment_Attachment_Text struct { + Text TextAttachment +} + +func (*GenieAttachment_Attachment_Text) isGenieAttachment_Attachment() {} + +// GenieAttachment_Attachment_Query selects Query for GenieAttachment.Attachment. +// Query Attachment if Genie responds with a SQL query +type GenieAttachment_Attachment_Query struct { + Query GenieQueryAttachment +} + +func (*GenieAttachment_Attachment_Query) isGenieAttachment_Attachment() {} + +// GenieAttachment_Attachment_SuggestedQuestions selects SuggestedQuestions for GenieAttachment.Attachment. +// Follow-up questions suggested by Genie +type GenieAttachment_Attachment_SuggestedQuestions struct { + SuggestedQuestions GenieSuggestedQuestionsAttachment +} + +func (*GenieAttachment_Attachment_SuggestedQuestions) isGenieAttachment_Attachment() {} + +// GenieAttachment_Attachment_Viz selects Viz for GenieAttachment.Attachment. +// Visualization generated by Genie, if requested via `enable_visualization` +type GenieAttachment_Attachment_Viz struct { + Viz GenieVizAttachment +} + +func (*GenieAttachment_Attachment_Viz) isGenieAttachment_Attachment() {} + +type GenieConversation struct { + // Conversation ID. Legacy identifier, use conversation_id instead + Id *string + // Genie space ID + SpaceId *string + // ID of the user who created the conversation + UserId *int64 + // Timestamp when the message was created + CreatedTimestamp *int64 + // Timestamp when the message was last updated + LastUpdatedTimestamp *int64 + // Conversation title + Title *string + // Conversation ID + ConversationId *string +} + +type GenieConversationSummary struct { + ConversationId *string + Title *string + CreatedTimestamp *int64 + // Whether this is a classic chat or an agent-mode conversation. Allows callers + // to route message retrieval (chat vs. agent endpoint) without an extra lookup. + AgentType GenieConversationType +} + +type GenieCreateConversationMessageRequest struct { + // The ID associated with the Genie space where the conversation is started. + SpaceId *string + // The ID associated with the conversation. + ConversationId *string + // User message content. + Content *string + // Enable visualization generation. + EnableVisualization *bool +} + +type GenieCreateEvalRunRequest struct { + // The ID associated with the Genie space where the evaluations will be + // executed. + SpaceId *string + // List of benchmark question IDs to evaluate. These questions must exist in the + // specified Genie space. If none are specified, then all benchmark questions + // are evaluated. + BenchmarkQuestionIds []string +} + +type GenieCreateMessageCommentRequest struct { + // The ID associated with the Genie space. + SpaceId *string + // The ID associated with the conversation. + ConversationId *string + // The ID associated with the message. + MessageId *string + // Comment text content. + Content *string +} + +type GenieCreateSpaceRequest struct { + // Warehouse to associate with the new space + WarehouseId *string + // Parent folder path where the space will be registered + ParentPath *string + // The contents of the Genie Space in serialized string form. Use the [Get Genie + // Space](:method:genie/getspace) API to retrieve an example response, which + // includes the `serialized_space` field. This field provides the structure of + // the JSON string that represents the space's layout and components. + SerializedSpace *string + // Optional title override + Title *string + // Optional description + Description *string +} + +type GenieDeleteConversationMessageRequest struct { + // The ID associated with the Genie space where the message is located. + SpaceId *string + // The ID associated with the conversation. + ConversationId *string + // The ID associated with the message to delete. + MessageId *string +} + +type GenieDeleteConversationRequest struct { + // The ID associated with the Genie space where the conversation is located. + SpaceId *string + // The ID of the conversation to delete. + ConversationId *string +} + +type GenieEvalResponse struct { + // The response content (either text or SQL query). + Response *string + // SQL Statement Execution response. + SqlExecutionResult *StatementResponse + // Type of response + ResponseType GenieEvalResponseType +} + +// Shows summary information for an evaluation result. For detailed information +// including SQL execution results, actual/expected responses, and assessment +// scores, use GenieGetEvalResultDetails.. +type GenieEvalResult struct { + // Unique identifier for this evaluation result. + ResultId *string + // The ID of the space the evaluation result belongs to. + SpaceId *string + // The ID of the benchmark question that was evaluated. + BenchmarkQuestionId *string + // Current status of this evaluation result. + Status EvaluationStatusType + // Stored snapshot of original benchmark question text. + Question *string + // Stored snapshot of original benchmark answer text. + BenchmarkAnswer *string + // User ID who created evaluation result. + CreatedByUser *int64 +} + +// Shows detailed information for an evaluation result.. +type GenieEvalResultDetails struct { + // The unique identifier for the evaluation result. + ResultId *string + // The ID of the space the evaluation result belongs to. + SpaceId *string + // The ID of the benchmark question that was evaluated. + BenchmarkQuestionId *string + // Current status of the evaluation run. + EvalRunStatus EvaluationStatusType + // Assessment of the evaluation result: good, bad, or needs review + Assessment GenieEvalAssessment + // Whether this evaluation was manually assessed. + ManualAssessment *bool + // Reasons for the assessment score. + // + // Assessment reasons describe why a Genie response was scored as BAD. + // + // Deterministic values (compared against the ground truth result): - + // EMPTY_RESULT: Genie's generated SQL results were empty for this benchmark + // question. - RESULT_MISSING_ROWS: Genie's generated SQL response is missing + // rows from the provided ground truth SQL. - RESULT_EXTRA_ROWS: Genie's + // generated SQL response has more rows than the provided ground truth SQL. - + // RESULT_MISSING_COLUMNS: Genie's generated SQL response is missing columns + // from the provided ground truth SQL. - RESULT_EXTRA_COLUMNS: Genie's generated + // SQL response has more columns than the provided ground truth SQL. - + // SINGLE_CELL_DIFFERENCE: Single value result was produced but differs from + // ground truth result. - EMPTY_GOOD_SQL: The benchmark SQL returned an empty + // result. - COLUMN_TYPE_DIFFERENCE: The values between the results match but + // the column type is different. + // + // LLM judge ratings explain the factors driving BAD results: - + // LLM_JUDGE_MISSING_OR_INCORRECT_FILTER: Genie's generated SQL is missing a + // WHERE clause condition or has incorrect filter logic that excludes/includes + // wrong data. - LLM_JUDGE_INCOMPLETE_OR_PARTIAL_OUTPUT: Genie's generated SQL + // returns only some of the requested data or columns, missing parts of what the + // ground truth SQL returns. - LLM_JUDGE_MISINTERPRETATION_OF_USER_REQUEST: + // Genie's generated SQL fundamentally misunderstands what the user is asking + // for, addressing the wrong question or goal. - + // LLM_JUDGE_INSTRUCTION_COMPLIANCE_OR_MISSING_BUSINESS_LOGIC: Genie's generated + // SQL fails to apply specified instructions or business logic that should be + // followed. - LLM_JUDGE_INCORRECT_METRIC_CALCULATION: Genie's generated SQL + // uses incorrect logic or makes wrong assumptions when calculating metrics. - + // LLM_JUDGE_INCORRECT_TABLE_OR_FIELD_USAGE: Genie's generated SQL references + // wrong tables, columns, or uses fields that don't match the ground truth SQL's + // intent. - LLM_JUDGE_INCORRECT_FUNCTION_USAGE: Genie's generated SQL uses SQL + // functions incorrectly or inappropriately (wrong parameters, wrong function + // for the task, etc.). - LLM_JUDGE_MISSING_OR_INCORRECT_JOIN: Genie's generated + // SQL is missing necessary joins between tables or has incorrect join + // conditions/types that produce wrong results. - + // LLM_JUDGE_MISSING_OR_INCORRECT_AGGREGATION: Genie's generated SQL is missing + // GROUP BY clauses or has incorrect grouping that doesn't match the requested + // aggregation level. - LLM_JUDGE_FORMATTING_ERROR: Genie's generated SQL output + // has incorrect formatting, ordering (ORDER BY), or presentation issues that + // don't match expectations. - LLM_JUDGE_OTHER: LLM judge identified an error + // that doesn't fall into other categories. + // + // Deprecated LLM judge values (kept for backward compatibility, do not use): - + // LLM_JUDGE_MISSING_JOIN (deprecated) - LLM_JUDGE_WRONG_FILTER (deprecated) - + // LLM_JUDGE_WRONG_AGGREGATION (deprecated) - LLM_JUDGE_WRONG_COLUMNS + // (deprecated) - LLM_JUDGE_SYNTAX_ERROR (deprecated) - LLM_JUDGE_SEMANTIC_ERROR + // (deprecated) + AssessmentReasons []ScoreReason + // The actual response generated by Genie. + ActualResponse []GenieEvalResponse + // The expected responses from the benchmark. + ExpectedResponse []GenieEvalResponse +} + +type GenieEvalRunResponse struct { + // The unique identifier for the evaluation run. + EvalRunId *string + // Current status of the evaluation run. + EvalRunStatus EvaluationStatusType + // User ID who initiated the evaluation run. + RunByUser *int64 + // Timestamp when the evaluation run was created (milliseconds since epoch). + CreatedTimestamp *int64 + // Total number of questions in the evaluation run. + NumQuestions *int64 + // Number of questions answered correctly. + NumCorrect *int64 + // Number of questions that need manual review. + NumNeedsReview *int64 + // Number of questions that have been completed. + NumDone *int64 + // Timestamp when the evaluation run was last updated (milliseconds since + // epoch). + LastUpdatedTimestamp *int64 +} + +type GenieExecuteMessageAttachmentQueryRequest struct { + // Message ID + MessageId *string + // Genie space ID + SpaceId *string + // Conversation ID + ConversationId *string + // Attachment ID + AttachmentId *string +} + +type GenieExecuteMessageQueryRequest struct { + // Message ID + MessageId *string + // Genie space ID + SpaceId *string + // Conversation ID + ConversationId *string +} + +// Feedback containing rating and optional comment. +type GenieFeedback struct { + // The feedback rating + Rating GenieFeedbackRating + // Optional feedback comment text + Comment *string +} + +type GenieGenerateDownloadFullQueryResultRequest struct { + // Genie space ID + SpaceId *string + // Conversation ID + ConversationId *string + // Message ID + MessageId *string + // Attachment ID + AttachmentId *string +} + +type GenieGenerateDownloadFullQueryResultResponse struct { + // Download ID. Use this ID to track the download request in subsequent polling + // calls + DownloadId *string + // JWT signature for the download_id to ensure secure access to query results + DownloadIdSignature *string +} + +type GenieGetConversationMessageRequest struct { + // The ID associated with the Genie space where the target conversation is + // located. + SpaceId *string + // The ID associated with the target conversation. + ConversationId *string + // The ID associated with the target message from the identified conversation. + MessageId *string +} + +type GenieGetDownloadFullQueryResultRequest struct { + // Genie space ID + SpaceId *string + // Conversation ID + ConversationId *string + // Message ID + MessageId *string + // Attachment ID + AttachmentId *string + // Download ID. This ID is provided by the [Generate Download + // endpoint](:method:genie/generateDownloadFullQueryResult) + DownloadId *string + // JWT signature for the download_id to ensure secure access to query results + DownloadIdSignature *string +} + +type GenieGetDownloadFullQueryResultResponse struct { + // SQL Statement Execution response. See [Get status, manifest, and result first + // chunk](:method:statementexecution/getstatement) for more details. + StatementResponse *StatementResponse +} + +type GenieGetEvalResultDetailsRequest struct { + // The ID associated with the Genie space where the evaluation run is located. + SpaceId *string + // The unique identifier for the evaluation run. + EvalRunId *string + // The unique identifier for the evaluation result. + ResultId *string +} + +type GenieGetEvalRunRequest struct { + // The ID associated with the Genie space where the evaluation run is located. + SpaceId *string + EvalRunId *string +} + +type GenieGetMessageAttachmentQueryResultRequest struct { + // Message ID + MessageId *string + // Genie space ID + SpaceId *string + // Conversation ID + ConversationId *string + // Attachment ID + AttachmentId *string +} + +type GenieGetMessageQueryResultRequest struct { + // Message ID + MessageId *string + // Genie space ID + SpaceId *string + // Conversation ID + ConversationId *string +} + +type GenieGetMessageQueryResultResponse struct { + // SQL Statement Execution response. See [Get status, manifest, and result first + // chunk](:method:statementexecution/getstatement) for more details. + StatementResponse *StatementResponse +} + +type GenieGetQueryResultByAttachmentRequest struct { + // Message ID + MessageId *string + // Genie space ID + SpaceId *string + // Conversation ID + ConversationId *string + // Attachment ID + AttachmentId *string +} + +type GenieGetSpaceRequest struct { + // The ID associated with the Genie space + SpaceId *string + // Whether to include the serialized space export in the response. Requires at + // least CAN EDIT permission on the space. + IncludeSerializedSpace *bool +} + +type GenieListConversationCommentsRequest struct { + // The ID associated with the Genie space. + SpaceId *string + // The ID associated with the conversation. + ConversationId *string + // Maximum number of comments to return per page. + PageSize *int + // Pagination token for getting the next page of results. + PageToken *string +} + +type GenieListConversationCommentsResponse struct { + // List of comments in the conversation. + Comments []GenieMessageComment + // Token to get the next page of results. + NextPageToken *string +} + +type GenieListConversationMessagesRequest struct { + // The ID associated with the Genie space where the conversation is located + SpaceId *string + // The ID of the conversation to list messages from + ConversationId *string + // Maximum number of messages to return per page + PageSize *int + // Token to get the next page of results + PageToken *string +} + +type GenieListConversationMessagesResponse struct { + // List of messages in the conversation. + Messages []GenieMessage + // The token to use for retrieving the next page of results. + NextPageToken *string +} + +type GenieListConversationsRequest struct { + // The ID of the Genie space to retrieve conversations from. + SpaceId *string + // Maximum number of conversations to return per page + PageSize *int + // Token to get the next page of results + PageToken *string + // Include all conversations in the space across all users. Requires at least + // CAN MANAGE permission on the space. + IncludeAll *bool +} + +type GenieListConversationsResponse struct { + // List of conversations in the Genie space + Conversations []GenieConversationSummary + // Token to get the next page of results + NextPageToken *string +} + +type GenieListEvalResultsRequest struct { + // The ID associated with the Genie space where the evaluation run is located. + SpaceId *string + // The unique identifier for the evaluation run. + EvalRunId *string + // Maximum number of eval results to return per page. + PageSize *int + // Opaque token to retrieve the next page of results. + PageToken *string +} + +type GenieListEvalResultsResponse struct { + // List of evaluation results for the specified run. + EvalResults []GenieEvalResult + // The token to use for retrieving the next page of results. + NextPageToken *string +} + +type GenieListEvalRunsRequest struct { + // The ID associated with the Genie space where the evaluation run is located. + SpaceId *string + // Maximum number of evaluation runs to return per page + PageSize *int + // Token to get the next page of results + PageToken *string +} + +type GenieListEvalRunsResponse struct { + // List of evaluation runs for a space on provided page token and page size + EvalRuns []GenieEvalRunResponse + // The token to use for retrieving the next page of results. + NextPageToken *string +} + +type GenieListMessageCommentsRequest struct { + // The ID associated with the Genie space. + SpaceId *string + // The ID associated with the conversation. + ConversationId *string + // The ID associated with the message. + MessageId *string + // Maximum number of comments to return per page. + PageSize *int + // Pagination token for getting the next page of results. + PageToken *string +} + +type GenieListMessageCommentsResponse struct { + // List of comments on the message. + Comments []GenieMessageComment + // Token to get the next page of results. + NextPageToken *string +} + +type GenieListSpacesRequest struct { + // Maximum number of spaces to return per page + PageSize *int + // Pagination token for getting the next page of results + PageToken *string +} + +type GenieListSpacesResponse struct { + // List of Genie spaces + Spaces []GenieSpace + // Token to get the next page of results + NextPageToken *string +} + +type GenieMessage struct { + // Message ID. Legacy identifier, use message_id instead + Id *string + // Genie space ID + SpaceId *string + // Conversation ID + ConversationId *string + // ID of the user who created the message + UserId *int64 + // Timestamp when the message was created + CreatedTimestamp *int64 + // Timestamp when the message was last updated + LastUpdatedTimestamp *int64 + Status MessageStatus_MessageStatus + // User message content + Content *string + // AI-generated response to the message + Attachments []GenieAttachment + // The result of SQL query if the message includes a query attachment. + // Deprecated. Use `query_result_metadata` in `GenieQueryAttachment` instead. + QueryResult *Result + // Error message if Genie failed to respond to the message + Error *MessageError + // Message ID + MessageId *string + // User feedback for the message if provided + Feedback *GenieFeedback +} + +// A comment on a Genie conversation message.. +type GenieMessageComment struct { + // Genie space ID + SpaceId *string + // Conversation ID + ConversationId *string + // Message ID + MessageId *string + // Comment ID + MessageCommentId *string + // ID of the user who created the comment + UserId *int64 + // Comment text content + Content *string + // Timestamp when the comment was created + CreatedTimestamp *int64 +} + +type GenieQueryAttachment struct { + // Name of the query + Title *string + // AI generated SQL query + Query *string + // Description of the query + Description *string + // Time when the user updated the query last + LastUpdatedTimestamp *int64 + Parameters []QueryAttachmentParameter + Id *string + // Statement Execution API statement id. Use [Get status, manifest, and result + // first chunk](:method:statementexecution/getstatement) to get the full result + // data. + StatementId *string + // Metadata associated with the query result. + QueryResultMetadata *GenieResultMetadata + // Insights into how Genie came to generate the SQL. + Thoughts []Thought +} + +type GenieResultMetadata struct { + // The number of rows in the result set. + RowCount *int64 + // Indicates whether the result set is truncated. + IsTruncated *bool +} + +type GenieSendMessageFeedbackRequest struct { + // The ID associated with the Genie space where the message is located. + SpaceId *string + // The ID associated with the conversation. + ConversationId *string + // The ID associated with the message to provide feedback for. + MessageId *string + // The rating (POSITIVE, NEGATIVE, or NONE). + Rating GenieFeedbackRating + // Optional text feedback that will be stored as a comment. + Comment *string +} + +type GenieSpace struct { + // Genie space ID + SpaceId *string + // Title of the Genie Space + Title *string + // Description of the Genie Space + Description *string + // Warehouse associated with the Genie Space + WarehouseId *string + // Parent folder path of the Genie Space + ParentPath *string + // The contents of the Genie Space in serialized string form. This field is + // excluded in List Genie spaces responses. Use the [Get Genie + // Space](:method:genie/getspace) API to retrieve an example response, which + // includes the `serialized_space` field. This field provides the structure of + // the JSON string that represents the space's layout and components. + SerializedSpace *string + // ETag for this space. Pass this value back in the update request to prevent + // overwriting concurrent changes. + Etag *string + // Time when the Genie space was created. + CreateTime *types.Time + // Time when the Genie space was last modified, matching the value shown in the + // Genie Agent UI. + UpdateTime *types.Time +} + +type GenieStartConversationRequest struct { + // The ID associated with the Genie space where you want to start a + // conversation. + SpaceId *string + // The text of the message that starts the conversation. + Content *string + // Enable visualization generation. + EnableVisualization *bool +} + +type GenieStartConversationResponse struct { + // Message ID + MessageId *string + Message *GenieMessage + // Conversation ID + ConversationId *string + Conversation *GenieConversation +} + +// Follow-up questions suggested by Genie. +type GenieSuggestedQuestionsAttachment struct { + // The suggested follow-up questions + Questions []string +} + +type GenieTrashSpaceRequest struct { + // The ID associated with the Genie space to be sent to the trash. + SpaceId *string +} + +type GenieUpdateSpaceRequest struct { + // Genie space ID + SpaceId *string + // The contents of the Genie Space in serialized string form (full replacement). + // Use the [Get Genie Space](:method:genie/getspace) API to retrieve an example + // response, which includes the `serialized_space` field. This field provides + // the structure of the JSON string that represents the space's layout and + // components. + SerializedSpace *string + // Optional title override + Title *string + // Optional description + Description *string + // Optional warehouse override + WarehouseId *string + // ETag returned by a previous GET or UPDATE. When set, the update will fail if + // the space has been modified since. Omit to apply the update unconditionally. + Etag *string + // Parent workspace folder path to move this Genie space under. + ParentPath *string +} + +// Visualization generated by Genie for a query result. Use the attachment ID +// with the download visualization API to retrieve the rendered image.. +type GenieVizAttachment struct { + // Name of the visualization + Title *string + // The ID of the query attachment the visualization was generated from + QueryAttachmentId *string +} + +// copied from proto3 / Google Well Known Types, source: +// https://github.com/protocolbuffers/protobuf/blob/450d24ca820750c5db5112a6f0b0c2efb9758021/src/google/protobuf/struct.proto +// `ListValue` is a wrapper around a repeated field of values. +// +// The JSON representation for `ListValue` is JSON array.. +type ListValue struct { + // Repeated field of dynamically typed values. + Values []Value +} + +// proto compiler is too old and does not support map. This is wire +// compatible with map. See +// https://developers.google.com/protocol-buffers/docs/proto#backwards_compatibility.. +type MapStringValueEntry struct { + Key *string + Value *Value +} + +type MessageError struct { + Error *string + Type MessageError_Type +} + +type MessageStatus struct { +} + +// A positional argument passed to a row filter or column mask function. +// Distinguishes between column references and literals.. +type PolicyFunctionArgument struct { + Arg isPolicyFunctionArgument_Arg +} + +type isPolicyFunctionArgument_Arg interface { + isPolicyFunctionArgument_Arg() +} + +// PolicyFunctionArgument_Arg_Column selects Column for PolicyFunctionArgument.Arg. +// A column reference. +type PolicyFunctionArgument_Arg_Column struct { + Column string +} + +func (*PolicyFunctionArgument_Arg_Column) isPolicyFunctionArgument_Arg() {} + +// PolicyFunctionArgument_Arg_Constant selects Constant for PolicyFunctionArgument.Arg. +// A constant literal. +type PolicyFunctionArgument_Arg_Constant struct { + Constant string +} + +func (*PolicyFunctionArgument_Arg_Constant) isPolicyFunctionArgument_Arg() {} + +type QueryAttachmentParameter struct { + Keyword *string + Value *string + SqlType *string +} + +type Result struct { + // Statement Execution API statement id. Use [Get status, manifest, and result + // first chunk](:method:statementexecution/getstatement) to get the full result + // data. + StatementId *string + // Row count of the result + RowCount *int64 + // If result is truncated + IsTruncated *bool + // JWT corresponding to the statement contained in this result + StatementIdSignature *string +} + +// Contains the result data of a single chunk when using `INLINE` disposition. +// When using `EXTERNAL_LINKS` disposition, the array `external_links` is used +// instead to provide URLs to the result data in cloud storage. Exactly one of +// these alternatives is used. (While the `external_links` array prepares the +// API to return multiple links in a single response. Currently only a single +// link is returned.). +type ResultData struct { + ExternalLinks []ExternalLink + // The `JSON_ARRAY` format is an array of arrays of values, where each non-null + // value is formatted as a string. Null values are encoded as JSON `null`. + DataArray []ListValue + // The position within the sequence of result set chunks. + ChunkIndex *int + // The starting row offset within the result set. + RowOffset *int64 + // The number of rows within the result chunk. + RowCount *int64 + // The number of bytes in the result chunk. This field is not available when + // using `INLINE` disposition. + ByteCount *int64 + // When fetching, provides the `chunk_index` for the _next_ chunk. If absent, + // indicates there are no more chunks. The next chunk can be fetched with a + // :method:statementexecution/getstatementresultchunkn request. + NextChunkIndex *int + // When fetching, provides a link to fetch the _next_ chunk. If absent, + // indicates there are no more chunks. This link is an absolute `path` to be + // joined with your `$DATABRICKS_HOST`, and should be treated as an opaque link. + // This is an alternative to using `next_chunk_index`. + NextChunkInternalLink *string +} + +// The result manifest provides schema and metadata for the result set.. +type ResultManifest struct { + Format Format + Schema *Schema + // The total number of chunks that the result set has been divided into. + TotalChunkCount *int + // Array of result set chunk metadata. + Chunks []ChunkInfo + // The total number of rows in the result set. + TotalRowCount *int64 + // The total number of bytes in the result set. This field is not available when + // using `INLINE` disposition. + TotalByteCount *int64 + // Indicates whether the result is truncated due to `row_limit` or `byte_limit`. + Truncated *bool +} + +type Schema struct { + ColumnCount *int + Columns []ColumnInfo +} + +type StatementResponse struct { + // The statement ID is returned upon successfully submitting a SQL statement, + // and is a required reference for all subsequent calls. + StatementId *string + Status *StatementStatus + Manifest *ResultManifest + Result *ResultData +} + +// The status response includes execution state and if relevant, error +// information.. +type StatementStatus struct { + // Statement execution state: - `PENDING`: waiting for warehouse - `RUNNING`: + // running - `SUCCEEDED`: execution was successful, result data available for + // fetch - `FAILED`: execution failed; reason for failure described in + // accompanying error message - `CANCELED`: user canceled; can come from + // explicit cancel call, or timeout with `on_wait_timeout=CANCEL` - `CLOSED`: + // execution successful, and statement closed; result no longer available for + // fetch + State StatementStatus_State + Error *DatabricksServiceExceptionProto + // SQLSTATE error code returned when the statement execution fails. Only + // populated when the statement status is `FAILED`. + SqlState *string +} + +// copied from proto3 / Google Well Known Types, source: +// https://github.com/protocolbuffers/protobuf/blob/450d24ca820750c5db5112a6f0b0c2efb9758021/src/google/protobuf/struct.proto +// `Struct` represents a structured data value, consisting of fields which map +// to dynamically typed values. In some languages, `Struct` might be supported +// by a native representation. For example, in scripting languages like JS a +// struct is represented as an object. The details of that representation are +// described together with the proto support for the language. +// +// The JSON representation for `Struct` is JSON object.. +type Struct struct { + // Unordered map of dynamically typed values. + Fields []MapStringValueEntry +} + +// A text response on a conversation message: the answer, the final summary, or +// a clarifying follow-up question, along with optional phase and verification +// metadata.. +type TextAttachment struct { + // AI generated message + Content *string + Id *string + // Purpose of this text attachment. A completed message may contain more than + // one text attachment (for example a clarifying follow-up question alongside + // the final answer); use this field to tell them apart. + // `TEXT_ATTACHMENT_PURPOSE_ANSWER` marks the final answer/summary and + // `FOLLOW_UP_QUESTION` marks a clarifying question. + Purpose TextAttachmentPurpose +} + +// A single thought in the AI's reasoning process for a query.. +type Thought struct { + // The category of this thought. The possible values are: * + // `THOUGHT_TYPE_DESCRIPTION`: A high-level description of how the question was + // interpreted. * `THOUGHT_TYPE_UNDERSTANDING`: How ambiguous parts of the + // question were resolved. * `THOUGHT_TYPE_DATA_SOURCING`: Which tables or + // datasets were identified as relevant. * `THOUGHT_TYPE_INSTRUCTIONS`: Which + // author-defined instructions were referenced. * `THOUGHT_TYPE_STEPS`: The + // logical steps taken to compute the answer. + ThoughtType ThoughtType + // The md formatted content for this thought. + Content *string +} + +// copied from proto3 / Google Well Known Types, source: +// https://github.com/protocolbuffers/protobuf/blob/450d24ca820750c5db5112a6f0b0c2efb9758021/src/google/protobuf/struct.proto +// `Value` represents a dynamically typed value which can be either null, a +// number, a string, a boolean, a recursive struct value, or a list of values. A +// producer of value is expected to set one of these variants. Absence of any +// variant indicates an error. +// +// The JSON representation for `Value` is JSON value.. +type Value struct { + // The kind of value. + Kind isValue_Kind +} + +type isValue_Kind interface { + isValue_Kind() +} + +// Value_Kind_NullValue selects NullValue for Value.Kind. +// Represents a null value. +type Value_Kind_NullValue struct { + NullValue NullValue +} + +func (*Value_Kind_NullValue) isValue_Kind() {} + +// Value_Kind_NumberValue selects NumberValue for Value.Kind. +// Represents a double value. +type Value_Kind_NumberValue struct { + NumberValue float64 +} + +func (*Value_Kind_NumberValue) isValue_Kind() {} + +// Value_Kind_StringValue selects StringValue for Value.Kind. +// Represents a string value. +type Value_Kind_StringValue struct { + StringValue string +} + +func (*Value_Kind_StringValue) isValue_Kind() {} + +// Value_Kind_BoolValue selects BoolValue for Value.Kind. +// Represents a boolean value. +type Value_Kind_BoolValue struct { + BoolValue bool +} + +func (*Value_Kind_BoolValue) isValue_Kind() {} + +// Value_Kind_StructValue selects StructValue for Value.Kind. +// Represents a structured value. +type Value_Kind_StructValue struct { + StructValue Struct +} + +func (*Value_Kind_StructValue) isValue_Kind() {} + +// Value_Kind_ListValue selects ListValue for Value.Kind. +// Represents a repeated `Value`. +type Value_Kind_ListValue struct { + ListValue ListValue +} + +func (*Value_Kind_ListValue) isValue_Kind() {} diff --git a/genie/v1/wire.go b/genie/v1/wire.go new file mode 100755 index 0000000..92bbdb3 --- /dev/null +++ b/genie/v1/wire.go @@ -0,0 +1,1513 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package genie + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +type chunkInfoWire struct { + ChunkIndex *int `json:"chunk_index,omitempty"` + RowOffset *int64 `json:"row_offset,omitempty"` + RowCount *int64 `json:"row_count,omitempty"` + ByteCount *int64 `json:"byte_count,omitempty"` + NextChunkIndex *int `json:"next_chunk_index,omitempty"` + NextChunkInternalLink *string `json:"next_chunk_internal_link,omitempty"` +} + +func chunkInfoFromWire(w *chunkInfoWire) (*ChunkInfo, error) { + if w == nil { + return nil, nil + } + return &ChunkInfo{ + ChunkIndex: w.ChunkIndex, + RowOffset: w.RowOffset, + RowCount: w.RowCount, + ByteCount: w.ByteCount, + NextChunkIndex: w.NextChunkIndex, + NextChunkInternalLink: w.NextChunkInternalLink, + }, nil +} + +type columnInfoWire struct { + Name *string `json:"name,omitempty"` + TypeText *string `json:"type_text,omitempty"` + TypeName ColumnTypeName `json:"type_name,omitempty"` + Position *int `json:"position,omitempty"` + TypePrecision *int `json:"type_precision,omitempty"` + TypeScale *int `json:"type_scale,omitempty"` + TypeIntervalType *string `json:"type_interval_type,omitempty"` + TypeJson *string `json:"type_json,omitempty"` + Comment *string `json:"comment,omitempty"` + Nullable *bool `json:"nullable,omitempty"` + PartitionIndex *int `json:"partition_index,omitempty"` + Mask *columnMaskWire `json:"mask,omitempty"` +} + +func columnInfoFromWire(w *columnInfoWire) (*ColumnInfo, error) { + if w == nil { + return nil, nil + } + maskPublicValue, err := columnMaskFromWire(w.Mask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnInfo.Mask", err) + } + return &ColumnInfo{ + Name: w.Name, + TypeText: w.TypeText, + TypeName: w.TypeName, + Position: w.Position, + TypePrecision: w.TypePrecision, + TypeScale: w.TypeScale, + TypeIntervalType: w.TypeIntervalType, + TypeJson: w.TypeJson, + Comment: w.Comment, + Nullable: w.Nullable, + PartitionIndex: w.PartitionIndex, + Mask: maskPublicValue, + }, nil +} + +type columnMaskWire struct { + FunctionName *string `json:"function_name,omitempty"` + UsingColumnNames []string `json:"using_column_names,omitempty"` + UsingArguments []policyFunctionArgumentWire `json:"using_arguments,omitempty"` +} + +func columnMaskFromWire(w *columnMaskWire) (*ColumnMask, error) { + if w == nil { + return nil, nil + } + usingArgumentsPublicValue, err := convertSlice(w.UsingArguments, policyFunctionArgumentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnMask.UsingArguments", err) + } + return &ColumnMask{ + FunctionName: w.FunctionName, + UsingColumnNames: w.UsingColumnNames, + UsingArguments: usingArgumentsPublicValue, + }, nil +} + +type databricksServiceExceptionProtoWire struct { + ErrorCode ErrorCode `json:"error_code,omitempty"` + Message *string `json:"message,omitempty"` + StackTrace *string `json:"stack_trace,omitempty"` +} + +func databricksServiceExceptionProtoFromWire(w *databricksServiceExceptionProtoWire) (*DatabricksServiceExceptionProto, error) { + if w == nil { + return nil, nil + } + return &DatabricksServiceExceptionProto{ + ErrorCode: w.ErrorCode, + Message: w.Message, + StackTrace: w.StackTrace, + }, nil +} + +type externalLinkWire struct { + ExternalLink *string `json:"external_link,omitempty"` + Expiration *string `json:"expiration,omitempty"` + HttpHeaders map[string]string `json:"http_headers,omitempty"` + ChunkIndex *int `json:"chunk_index,omitempty"` + RowOffset *int64 `json:"row_offset,omitempty"` + RowCount *int64 `json:"row_count,omitempty"` + ByteCount *int64 `json:"byte_count,omitempty"` + NextChunkIndex *int `json:"next_chunk_index,omitempty"` + NextChunkInternalLink *string `json:"next_chunk_internal_link,omitempty"` +} + +func externalLinkFromWire(w *externalLinkWire) (*ExternalLink, error) { + if w == nil { + return nil, nil + } + return &ExternalLink{ + ExternalLink: w.ExternalLink, + Expiration: w.Expiration, + HttpHeaders: w.HttpHeaders, + ChunkIndex: w.ChunkIndex, + RowOffset: w.RowOffset, + RowCount: w.RowCount, + ByteCount: w.ByteCount, + NextChunkIndex: w.NextChunkIndex, + NextChunkInternalLink: w.NextChunkInternalLink, + }, nil +} + +type genieAttachmentWire struct { + Text *textAttachmentWire `json:"text,omitempty"` + Query *genieQueryAttachmentWire `json:"query,omitempty"` + SuggestedQuestions *genieSuggestedQuestionsAttachmentWire `json:"suggested_questions,omitempty"` + Viz *genieVizAttachmentWire `json:"viz,omitempty"` + AttachmentId *string `json:"attachment_id,omitempty"` +} + +func genieAttachmentFromWire(w *genieAttachmentWire) (*GenieAttachment, error) { + if w == nil { + return nil, nil + } + attachmentMembers := 0 + if w.Text != nil { + attachmentMembers++ + } + if w.Query != nil { + attachmentMembers++ + } + if w.SuggestedQuestions != nil { + attachmentMembers++ + } + if w.Viz != nil { + attachmentMembers++ + } + if attachmentMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "GenieAttachment.Attachment") + } + var attachmentSelection isGenieAttachment_Attachment + switch { + case w.Text != nil: + attachmentTextConverted, err := textAttachmentFromWire(w.Text) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieAttachment.Attachment.Text", err) + } + attachmentSelection = &GenieAttachment_Attachment_Text{Text: *attachmentTextConverted} + case w.Query != nil: + attachmentQueryConverted, err := genieQueryAttachmentFromWire(w.Query) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieAttachment.Attachment.Query", err) + } + attachmentSelection = &GenieAttachment_Attachment_Query{Query: *attachmentQueryConverted} + case w.SuggestedQuestions != nil: + attachmentSuggestedQuestionsConverted, err := genieSuggestedQuestionsAttachmentFromWire(w.SuggestedQuestions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieAttachment.Attachment.SuggestedQuestions", err) + } + attachmentSelection = &GenieAttachment_Attachment_SuggestedQuestions{SuggestedQuestions: *attachmentSuggestedQuestionsConverted} + case w.Viz != nil: + attachmentVizConverted, err := genieVizAttachmentFromWire(w.Viz) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieAttachment.Attachment.Viz", err) + } + attachmentSelection = &GenieAttachment_Attachment_Viz{Viz: *attachmentVizConverted} + } + return &GenieAttachment{ + AttachmentId: w.AttachmentId, + Attachment: attachmentSelection, + }, nil +} + +type genieConversationWire struct { + Id *string `json:"id,omitempty"` + SpaceId *string `json:"space_id,omitempty"` + UserId *int64 `json:"user_id,omitempty"` + CreatedTimestamp *int64 `json:"created_timestamp,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + Title *string `json:"title,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` +} + +func genieConversationFromWire(w *genieConversationWire) (*GenieConversation, error) { + if w == nil { + return nil, nil + } + return &GenieConversation{ + Id: w.Id, + SpaceId: w.SpaceId, + UserId: w.UserId, + CreatedTimestamp: w.CreatedTimestamp, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + Title: w.Title, + ConversationId: w.ConversationId, + }, nil +} + +type genieConversationSummaryWire struct { + ConversationId *string `json:"conversation_id,omitempty"` + Title *string `json:"title,omitempty"` + CreatedTimestamp *int64 `json:"created_timestamp,omitempty"` + AgentType GenieConversationType `json:"agent_type,omitempty"` +} + +func genieConversationSummaryFromWire(w *genieConversationSummaryWire) (*GenieConversationSummary, error) { + if w == nil { + return nil, nil + } + return &GenieConversationSummary{ + ConversationId: w.ConversationId, + Title: w.Title, + CreatedTimestamp: w.CreatedTimestamp, + AgentType: w.AgentType, + }, nil +} + +type genieCreateConversationMessageRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + Content *string `json:"content,omitempty"` + EnableVisualization *bool `json:"enable_visualization,omitempty"` +} + +func genieCreateConversationMessageRequestToWire(v *GenieCreateConversationMessageRequest) (*genieCreateConversationMessageRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieCreateConversationMessageRequestWire{ + SpaceId: v.SpaceId, + ConversationId: v.ConversationId, + Content: v.Content, + EnableVisualization: v.EnableVisualization, + }, nil +} + +type genieCreateEvalRunRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + BenchmarkQuestionIds []string `json:"benchmark_question_ids,omitempty"` +} + +func genieCreateEvalRunRequestToWire(v *GenieCreateEvalRunRequest) (*genieCreateEvalRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieCreateEvalRunRequestWire{ + SpaceId: v.SpaceId, + BenchmarkQuestionIds: v.BenchmarkQuestionIds, + }, nil +} + +type genieCreateMessageCommentRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + MessageId *string `json:"message_id,omitempty"` + Content *string `json:"content,omitempty"` +} + +func genieCreateMessageCommentRequestToWire(v *GenieCreateMessageCommentRequest) (*genieCreateMessageCommentRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieCreateMessageCommentRequestWire{ + SpaceId: v.SpaceId, + ConversationId: v.ConversationId, + MessageId: v.MessageId, + Content: v.Content, + }, nil +} + +type genieCreateSpaceRequestWire struct { + WarehouseId *string `json:"warehouse_id,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + SerializedSpace *string `json:"serialized_space,omitempty"` + Title *string `json:"title,omitempty"` + Description *string `json:"description,omitempty"` +} + +func genieCreateSpaceRequestToWire(v *GenieCreateSpaceRequest) (*genieCreateSpaceRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieCreateSpaceRequestWire{ + WarehouseId: v.WarehouseId, + ParentPath: v.ParentPath, + SerializedSpace: v.SerializedSpace, + Title: v.Title, + Description: v.Description, + }, nil +} + +type genieEvalResponseWire struct { + Response *string `json:"response,omitempty"` + SqlExecutionResult *statementResponseWire `json:"sql_execution_result,omitempty"` + ResponseType GenieEvalResponseType `json:"response_type,omitempty"` +} + +func genieEvalResponseFromWire(w *genieEvalResponseWire) (*GenieEvalResponse, error) { + if w == nil { + return nil, nil + } + sqlExecutionResultPublicValue, err := statementResponseFromWire(w.SqlExecutionResult) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieEvalResponse.SqlExecutionResult", err) + } + return &GenieEvalResponse{ + Response: w.Response, + SqlExecutionResult: sqlExecutionResultPublicValue, + ResponseType: w.ResponseType, + }, nil +} + +type genieEvalResultWire struct { + ResultId *string `json:"result_id,omitempty"` + SpaceId *string `json:"space_id,omitempty"` + BenchmarkQuestionId *string `json:"benchmark_question_id,omitempty"` + Status EvaluationStatusType `json:"status,omitempty"` + Question *string `json:"question,omitempty"` + BenchmarkAnswer *string `json:"benchmark_answer,omitempty"` + CreatedByUser *int64 `json:"created_by_user,omitempty"` +} + +func genieEvalResultFromWire(w *genieEvalResultWire) (*GenieEvalResult, error) { + if w == nil { + return nil, nil + } + return &GenieEvalResult{ + ResultId: w.ResultId, + SpaceId: w.SpaceId, + BenchmarkQuestionId: w.BenchmarkQuestionId, + Status: w.Status, + Question: w.Question, + BenchmarkAnswer: w.BenchmarkAnswer, + CreatedByUser: w.CreatedByUser, + }, nil +} + +type genieEvalResultDetailsWire struct { + ResultId *string `json:"result_id,omitempty"` + SpaceId *string `json:"space_id,omitempty"` + BenchmarkQuestionId *string `json:"benchmark_question_id,omitempty"` + EvalRunStatus EvaluationStatusType `json:"eval_run_status,omitempty"` + Assessment GenieEvalAssessment `json:"assessment,omitempty"` + ManualAssessment *bool `json:"manual_assessment,omitempty"` + AssessmentReasons []ScoreReason `json:"assessment_reasons,omitempty"` + ActualResponse []genieEvalResponseWire `json:"actual_response,omitempty"` + ExpectedResponse []genieEvalResponseWire `json:"expected_response,omitempty"` +} + +func genieEvalResultDetailsFromWire(w *genieEvalResultDetailsWire) (*GenieEvalResultDetails, error) { + if w == nil { + return nil, nil + } + actualResponsePublicValue, err := convertSlice(w.ActualResponse, genieEvalResponseFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieEvalResultDetails.ActualResponse", err) + } + expectedResponsePublicValue, err := convertSlice(w.ExpectedResponse, genieEvalResponseFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieEvalResultDetails.ExpectedResponse", err) + } + return &GenieEvalResultDetails{ + ResultId: w.ResultId, + SpaceId: w.SpaceId, + BenchmarkQuestionId: w.BenchmarkQuestionId, + EvalRunStatus: w.EvalRunStatus, + Assessment: w.Assessment, + ManualAssessment: w.ManualAssessment, + AssessmentReasons: w.AssessmentReasons, + ActualResponse: actualResponsePublicValue, + ExpectedResponse: expectedResponsePublicValue, + }, nil +} + +type genieEvalRunResponseWire struct { + EvalRunId *string `json:"eval_run_id,omitempty"` + EvalRunStatus EvaluationStatusType `json:"eval_run_status,omitempty"` + RunByUser *int64 `json:"run_by_user,omitempty"` + CreatedTimestamp *int64 `json:"created_timestamp,omitempty"` + NumQuestions *int64 `json:"num_questions,omitempty"` + NumCorrect *int64 `json:"num_correct,omitempty"` + NumNeedsReview *int64 `json:"num_needs_review,omitempty"` + NumDone *int64 `json:"num_done,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` +} + +func genieEvalRunResponseFromWire(w *genieEvalRunResponseWire) (*GenieEvalRunResponse, error) { + if w == nil { + return nil, nil + } + return &GenieEvalRunResponse{ + EvalRunId: w.EvalRunId, + EvalRunStatus: w.EvalRunStatus, + RunByUser: w.RunByUser, + CreatedTimestamp: w.CreatedTimestamp, + NumQuestions: w.NumQuestions, + NumCorrect: w.NumCorrect, + NumNeedsReview: w.NumNeedsReview, + NumDone: w.NumDone, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + }, nil +} + +type genieExecuteMessageAttachmentQueryRequestWire struct { + MessageId *string `json:"message_id,omitempty"` + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + AttachmentId *string `json:"attachment_id,omitempty"` +} + +func genieExecuteMessageAttachmentQueryRequestToWire(v *GenieExecuteMessageAttachmentQueryRequest) (*genieExecuteMessageAttachmentQueryRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieExecuteMessageAttachmentQueryRequestWire{ + MessageId: v.MessageId, + SpaceId: v.SpaceId, + ConversationId: v.ConversationId, + AttachmentId: v.AttachmentId, + }, nil +} + +type genieExecuteMessageQueryRequestWire struct { + MessageId *string `json:"message_id,omitempty"` + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` +} + +func genieExecuteMessageQueryRequestToWire(v *GenieExecuteMessageQueryRequest) (*genieExecuteMessageQueryRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieExecuteMessageQueryRequestWire{ + MessageId: v.MessageId, + SpaceId: v.SpaceId, + ConversationId: v.ConversationId, + }, nil +} + +type genieFeedbackWire struct { + Rating GenieFeedbackRating `json:"rating,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func genieFeedbackFromWire(w *genieFeedbackWire) (*GenieFeedback, error) { + if w == nil { + return nil, nil + } + return &GenieFeedback{ + Rating: w.Rating, + Comment: w.Comment, + }, nil +} + +type genieGenerateDownloadFullQueryResultRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + MessageId *string `json:"message_id,omitempty"` + AttachmentId *string `json:"attachment_id,omitempty"` +} + +func genieGenerateDownloadFullQueryResultRequestToWire(v *GenieGenerateDownloadFullQueryResultRequest) (*genieGenerateDownloadFullQueryResultRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieGenerateDownloadFullQueryResultRequestWire{ + SpaceId: v.SpaceId, + ConversationId: v.ConversationId, + MessageId: v.MessageId, + AttachmentId: v.AttachmentId, + }, nil +} + +type genieGenerateDownloadFullQueryResultResponseWire struct { + DownloadId *string `json:"download_id,omitempty"` + DownloadIdSignature *string `json:"download_id_signature,omitempty"` +} + +func genieGenerateDownloadFullQueryResultResponseFromWire(w *genieGenerateDownloadFullQueryResultResponseWire) (*GenieGenerateDownloadFullQueryResultResponse, error) { + if w == nil { + return nil, nil + } + return &GenieGenerateDownloadFullQueryResultResponse{ + DownloadId: w.DownloadId, + DownloadIdSignature: w.DownloadIdSignature, + }, nil +} + +type genieGetDownloadFullQueryResultRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + MessageId *string `json:"message_id,omitempty"` + AttachmentId *string `json:"attachment_id,omitempty"` + DownloadId *string `json:"download_id,omitempty"` + DownloadIdSignature *string `json:"download_id_signature,omitempty"` +} + +func genieGetDownloadFullQueryResultRequestToWire(v *GenieGetDownloadFullQueryResultRequest) (*genieGetDownloadFullQueryResultRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieGetDownloadFullQueryResultRequestWire{ + SpaceId: v.SpaceId, + ConversationId: v.ConversationId, + MessageId: v.MessageId, + AttachmentId: v.AttachmentId, + DownloadId: v.DownloadId, + DownloadIdSignature: v.DownloadIdSignature, + }, nil +} + +type genieGetDownloadFullQueryResultResponseWire struct { + StatementResponse *statementResponseWire `json:"statement_response,omitempty"` +} + +func genieGetDownloadFullQueryResultResponseFromWire(w *genieGetDownloadFullQueryResultResponseWire) (*GenieGetDownloadFullQueryResultResponse, error) { + if w == nil { + return nil, nil + } + statementResponsePublicValue, err := statementResponseFromWire(w.StatementResponse) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieGetDownloadFullQueryResultResponse.StatementResponse", err) + } + return &GenieGetDownloadFullQueryResultResponse{ + StatementResponse: statementResponsePublicValue, + }, nil +} + +type genieGetMessageQueryResultResponseWire struct { + StatementResponse *statementResponseWire `json:"statement_response,omitempty"` +} + +func genieGetMessageQueryResultResponseFromWire(w *genieGetMessageQueryResultResponseWire) (*GenieGetMessageQueryResultResponse, error) { + if w == nil { + return nil, nil + } + statementResponsePublicValue, err := statementResponseFromWire(w.StatementResponse) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieGetMessageQueryResultResponse.StatementResponse", err) + } + return &GenieGetMessageQueryResultResponse{ + StatementResponse: statementResponsePublicValue, + }, nil +} + +type genieGetSpaceRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + IncludeSerializedSpace *bool `json:"include_serialized_space,omitempty"` +} + +func genieGetSpaceRequestToWire(v *GenieGetSpaceRequest) (*genieGetSpaceRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieGetSpaceRequestWire{ + SpaceId: v.SpaceId, + IncludeSerializedSpace: v.IncludeSerializedSpace, + }, nil +} + +type genieListConversationCommentsRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func genieListConversationCommentsRequestToWire(v *GenieListConversationCommentsRequest) (*genieListConversationCommentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieListConversationCommentsRequestWire{ + SpaceId: v.SpaceId, + ConversationId: v.ConversationId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type genieListConversationCommentsResponseWire struct { + Comments []genieMessageCommentWire `json:"comments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func genieListConversationCommentsResponseFromWire(w *genieListConversationCommentsResponseWire) (*GenieListConversationCommentsResponse, error) { + if w == nil { + return nil, nil + } + commentsPublicValue, err := convertSlice(w.Comments, genieMessageCommentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieListConversationCommentsResponse.Comments", err) + } + return &GenieListConversationCommentsResponse{ + Comments: commentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type genieListConversationMessagesRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func genieListConversationMessagesRequestToWire(v *GenieListConversationMessagesRequest) (*genieListConversationMessagesRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieListConversationMessagesRequestWire{ + SpaceId: v.SpaceId, + ConversationId: v.ConversationId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type genieListConversationMessagesResponseWire struct { + Messages []genieMessageWire `json:"messages,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func genieListConversationMessagesResponseFromWire(w *genieListConversationMessagesResponseWire) (*GenieListConversationMessagesResponse, error) { + if w == nil { + return nil, nil + } + messagesPublicValue, err := convertSlice(w.Messages, genieMessageFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieListConversationMessagesResponse.Messages", err) + } + return &GenieListConversationMessagesResponse{ + Messages: messagesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type genieListConversationsRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` + IncludeAll *bool `json:"include_all,omitempty"` +} + +func genieListConversationsRequestToWire(v *GenieListConversationsRequest) (*genieListConversationsRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieListConversationsRequestWire{ + SpaceId: v.SpaceId, + PageSize: v.PageSize, + PageToken: v.PageToken, + IncludeAll: v.IncludeAll, + }, nil +} + +type genieListConversationsResponseWire struct { + Conversations []genieConversationSummaryWire `json:"conversations,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func genieListConversationsResponseFromWire(w *genieListConversationsResponseWire) (*GenieListConversationsResponse, error) { + if w == nil { + return nil, nil + } + conversationsPublicValue, err := convertSlice(w.Conversations, genieConversationSummaryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieListConversationsResponse.Conversations", err) + } + return &GenieListConversationsResponse{ + Conversations: conversationsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type genieListEvalResultsRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + EvalRunId *string `json:"eval_run_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func genieListEvalResultsRequestToWire(v *GenieListEvalResultsRequest) (*genieListEvalResultsRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieListEvalResultsRequestWire{ + SpaceId: v.SpaceId, + EvalRunId: v.EvalRunId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type genieListEvalResultsResponseWire struct { + EvalResults []genieEvalResultWire `json:"eval_results,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func genieListEvalResultsResponseFromWire(w *genieListEvalResultsResponseWire) (*GenieListEvalResultsResponse, error) { + if w == nil { + return nil, nil + } + evalResultsPublicValue, err := convertSlice(w.EvalResults, genieEvalResultFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieListEvalResultsResponse.EvalResults", err) + } + return &GenieListEvalResultsResponse{ + EvalResults: evalResultsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type genieListEvalRunsRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func genieListEvalRunsRequestToWire(v *GenieListEvalRunsRequest) (*genieListEvalRunsRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieListEvalRunsRequestWire{ + SpaceId: v.SpaceId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type genieListEvalRunsResponseWire struct { + EvalRuns []genieEvalRunResponseWire `json:"eval_runs,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func genieListEvalRunsResponseFromWire(w *genieListEvalRunsResponseWire) (*GenieListEvalRunsResponse, error) { + if w == nil { + return nil, nil + } + evalRunsPublicValue, err := convertSlice(w.EvalRuns, genieEvalRunResponseFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieListEvalRunsResponse.EvalRuns", err) + } + return &GenieListEvalRunsResponse{ + EvalRuns: evalRunsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type genieListMessageCommentsRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + MessageId *string `json:"message_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func genieListMessageCommentsRequestToWire(v *GenieListMessageCommentsRequest) (*genieListMessageCommentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieListMessageCommentsRequestWire{ + SpaceId: v.SpaceId, + ConversationId: v.ConversationId, + MessageId: v.MessageId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type genieListMessageCommentsResponseWire struct { + Comments []genieMessageCommentWire `json:"comments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func genieListMessageCommentsResponseFromWire(w *genieListMessageCommentsResponseWire) (*GenieListMessageCommentsResponse, error) { + if w == nil { + return nil, nil + } + commentsPublicValue, err := convertSlice(w.Comments, genieMessageCommentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieListMessageCommentsResponse.Comments", err) + } + return &GenieListMessageCommentsResponse{ + Comments: commentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type genieListSpacesRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func genieListSpacesRequestToWire(v *GenieListSpacesRequest) (*genieListSpacesRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieListSpacesRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type genieListSpacesResponseWire struct { + Spaces []genieSpaceWire `json:"spaces,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func genieListSpacesResponseFromWire(w *genieListSpacesResponseWire) (*GenieListSpacesResponse, error) { + if w == nil { + return nil, nil + } + spacesPublicValue, err := convertSlice(w.Spaces, genieSpaceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieListSpacesResponse.Spaces", err) + } + return &GenieListSpacesResponse{ + Spaces: spacesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type genieMessageWire struct { + Id *string `json:"id,omitempty"` + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + UserId *int64 `json:"user_id,omitempty"` + CreatedTimestamp *int64 `json:"created_timestamp,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + Status MessageStatus_MessageStatus `json:"status,omitempty"` + Content *string `json:"content,omitempty"` + Attachments []genieAttachmentWire `json:"attachments,omitempty"` + QueryResult *resultWire `json:"query_result,omitempty"` + Error *messageErrorWire `json:"error,omitempty"` + MessageId *string `json:"message_id,omitempty"` + Feedback *genieFeedbackWire `json:"feedback,omitempty"` +} + +func genieMessageFromWire(w *genieMessageWire) (*GenieMessage, error) { + if w == nil { + return nil, nil + } + attachmentsPublicValue, err := convertSlice(w.Attachments, genieAttachmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieMessage.Attachments", err) + } + queryResultPublicValue, err := resultFromWire(w.QueryResult) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieMessage.QueryResult", err) + } + errorPublicValue, err := messageErrorFromWire(w.Error) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieMessage.Error", err) + } + feedbackPublicValue, err := genieFeedbackFromWire(w.Feedback) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieMessage.Feedback", err) + } + return &GenieMessage{ + Id: w.Id, + SpaceId: w.SpaceId, + ConversationId: w.ConversationId, + UserId: w.UserId, + CreatedTimestamp: w.CreatedTimestamp, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + Status: w.Status, + Content: w.Content, + Attachments: attachmentsPublicValue, + QueryResult: queryResultPublicValue, + Error: errorPublicValue, + MessageId: w.MessageId, + Feedback: feedbackPublicValue, + }, nil +} + +type genieMessageCommentWire struct { + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + MessageId *string `json:"message_id,omitempty"` + MessageCommentId *string `json:"message_comment_id,omitempty"` + UserId *int64 `json:"user_id,omitempty"` + Content *string `json:"content,omitempty"` + CreatedTimestamp *int64 `json:"created_timestamp,omitempty"` +} + +func genieMessageCommentFromWire(w *genieMessageCommentWire) (*GenieMessageComment, error) { + if w == nil { + return nil, nil + } + return &GenieMessageComment{ + SpaceId: w.SpaceId, + ConversationId: w.ConversationId, + MessageId: w.MessageId, + MessageCommentId: w.MessageCommentId, + UserId: w.UserId, + Content: w.Content, + CreatedTimestamp: w.CreatedTimestamp, + }, nil +} + +type genieQueryAttachmentWire struct { + Title *string `json:"title,omitempty"` + Query *string `json:"query,omitempty"` + Description *string `json:"description,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + Parameters []queryAttachmentParameterWire `json:"parameters,omitempty"` + Id *string `json:"id,omitempty"` + StatementId *string `json:"statement_id,omitempty"` + QueryResultMetadata *genieResultMetadataWire `json:"query_result_metadata,omitempty"` + Thoughts []thoughtWire `json:"thoughts,omitempty"` +} + +func genieQueryAttachmentFromWire(w *genieQueryAttachmentWire) (*GenieQueryAttachment, error) { + if w == nil { + return nil, nil + } + parametersPublicValue, err := convertSlice(w.Parameters, queryAttachmentParameterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieQueryAttachment.Parameters", err) + } + queryResultMetadataPublicValue, err := genieResultMetadataFromWire(w.QueryResultMetadata) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieQueryAttachment.QueryResultMetadata", err) + } + thoughtsPublicValue, err := convertSlice(w.Thoughts, thoughtFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieQueryAttachment.Thoughts", err) + } + return &GenieQueryAttachment{ + Title: w.Title, + Query: w.Query, + Description: w.Description, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + Parameters: parametersPublicValue, + Id: w.Id, + StatementId: w.StatementId, + QueryResultMetadata: queryResultMetadataPublicValue, + Thoughts: thoughtsPublicValue, + }, nil +} + +type genieResultMetadataWire struct { + RowCount *int64 `json:"row_count,omitempty"` + IsTruncated *bool `json:"is_truncated,omitempty"` +} + +func genieResultMetadataFromWire(w *genieResultMetadataWire) (*GenieResultMetadata, error) { + if w == nil { + return nil, nil + } + return &GenieResultMetadata{ + RowCount: w.RowCount, + IsTruncated: w.IsTruncated, + }, nil +} + +type genieSendMessageFeedbackRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + MessageId *string `json:"message_id,omitempty"` + Rating GenieFeedbackRating `json:"rating,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func genieSendMessageFeedbackRequestToWire(v *GenieSendMessageFeedbackRequest) (*genieSendMessageFeedbackRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieSendMessageFeedbackRequestWire{ + SpaceId: v.SpaceId, + ConversationId: v.ConversationId, + MessageId: v.MessageId, + Rating: v.Rating, + Comment: v.Comment, + }, nil +} + +type genieSpaceWire struct { + SpaceId *string `json:"space_id,omitempty"` + Title *string `json:"title,omitempty"` + Description *string `json:"description,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + SerializedSpace *string `json:"serialized_space,omitempty"` + Etag *string `json:"etag,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` +} + +func genieSpaceFromWire(w *genieSpaceWire) (*GenieSpace, error) { + if w == nil { + return nil, nil + } + return &GenieSpace{ + SpaceId: w.SpaceId, + Title: w.Title, + Description: w.Description, + WarehouseId: w.WarehouseId, + ParentPath: w.ParentPath, + SerializedSpace: w.SerializedSpace, + Etag: w.Etag, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + }, nil +} + +type genieStartConversationRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + Content *string `json:"content,omitempty"` + EnableVisualization *bool `json:"enable_visualization,omitempty"` +} + +func genieStartConversationRequestToWire(v *GenieStartConversationRequest) (*genieStartConversationRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieStartConversationRequestWire{ + SpaceId: v.SpaceId, + Content: v.Content, + EnableVisualization: v.EnableVisualization, + }, nil +} + +type genieStartConversationResponseWire struct { + MessageId *string `json:"message_id,omitempty"` + Message *genieMessageWire `json:"message,omitempty"` + ConversationId *string `json:"conversation_id,omitempty"` + Conversation *genieConversationWire `json:"conversation,omitempty"` +} + +func genieStartConversationResponseFromWire(w *genieStartConversationResponseWire) (*GenieStartConversationResponse, error) { + if w == nil { + return nil, nil + } + messagePublicValue, err := genieMessageFromWire(w.Message) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieStartConversationResponse.Message", err) + } + conversationPublicValue, err := genieConversationFromWire(w.Conversation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenieStartConversationResponse.Conversation", err) + } + return &GenieStartConversationResponse{ + MessageId: w.MessageId, + Message: messagePublicValue, + ConversationId: w.ConversationId, + Conversation: conversationPublicValue, + }, nil +} + +type genieSuggestedQuestionsAttachmentWire struct { + Questions []string `json:"questions,omitempty"` +} + +func genieSuggestedQuestionsAttachmentFromWire(w *genieSuggestedQuestionsAttachmentWire) (*GenieSuggestedQuestionsAttachment, error) { + if w == nil { + return nil, nil + } + return &GenieSuggestedQuestionsAttachment{ + Questions: w.Questions, + }, nil +} + +type genieUpdateSpaceRequestWire struct { + SpaceId *string `json:"space_id,omitempty"` + SerializedSpace *string `json:"serialized_space,omitempty"` + Title *string `json:"title,omitempty"` + Description *string `json:"description,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + Etag *string `json:"etag,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` +} + +func genieUpdateSpaceRequestToWire(v *GenieUpdateSpaceRequest) (*genieUpdateSpaceRequestWire, error) { + if v == nil { + return nil, nil + } + return &genieUpdateSpaceRequestWire{ + SpaceId: v.SpaceId, + SerializedSpace: v.SerializedSpace, + Title: v.Title, + Description: v.Description, + WarehouseId: v.WarehouseId, + Etag: v.Etag, + ParentPath: v.ParentPath, + }, nil +} + +type genieVizAttachmentWire struct { + Title *string `json:"title,omitempty"` + QueryAttachmentId *string `json:"query_attachment_id,omitempty"` +} + +func genieVizAttachmentFromWire(w *genieVizAttachmentWire) (*GenieVizAttachment, error) { + if w == nil { + return nil, nil + } + return &GenieVizAttachment{ + Title: w.Title, + QueryAttachmentId: w.QueryAttachmentId, + }, nil +} + +type listValueWire struct { + Values []valueWire `json:"values,omitempty"` +} + +func listValueFromWire(w *listValueWire) (*ListValue, error) { + if w == nil { + return nil, nil + } + valuesPublicValue, err := convertSlice(w.Values, valueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListValue.Values", err) + } + return &ListValue{ + Values: valuesPublicValue, + }, nil +} + +type mapStringValueEntryWire struct { + Key *string `json:"key,omitempty"` + Value *valueWire `json:"value,omitempty"` +} + +func mapStringValueEntryFromWire(w *mapStringValueEntryWire) (*MapStringValueEntry, error) { + if w == nil { + return nil, nil + } + valuePublicValue, err := valueFromWire(w.Value) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MapStringValueEntry.Value", err) + } + return &MapStringValueEntry{ + Key: w.Key, + Value: valuePublicValue, + }, nil +} + +type messageErrorWire struct { + Error *string `json:"error,omitempty"` + Type MessageError_Type `json:"type,omitempty"` +} + +func messageErrorFromWire(w *messageErrorWire) (*MessageError, error) { + if w == nil { + return nil, nil + } + return &MessageError{ + Error: w.Error, + Type: w.Type, + }, nil +} + +type policyFunctionArgumentWire struct { + Column *string `json:"column,omitempty"` + Constant *string `json:"constant,omitempty"` +} + +func policyFunctionArgumentFromWire(w *policyFunctionArgumentWire) (*PolicyFunctionArgument, error) { + if w == nil { + return nil, nil + } + argMembers := 0 + if w.Column != nil { + argMembers++ + } + if w.Constant != nil { + argMembers++ + } + if argMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PolicyFunctionArgument.Arg") + } + var argSelection isPolicyFunctionArgument_Arg + switch { + case w.Column != nil: + argSelection = &PolicyFunctionArgument_Arg_Column{Column: *w.Column} + case w.Constant != nil: + argSelection = &PolicyFunctionArgument_Arg_Constant{Constant: *w.Constant} + } + return &PolicyFunctionArgument{ + Arg: argSelection, + }, nil +} + +type queryAttachmentParameterWire struct { + Keyword *string `json:"keyword,omitempty"` + Value *string `json:"value,omitempty"` + SqlType *string `json:"sql_type,omitempty"` +} + +func queryAttachmentParameterFromWire(w *queryAttachmentParameterWire) (*QueryAttachmentParameter, error) { + if w == nil { + return nil, nil + } + return &QueryAttachmentParameter{ + Keyword: w.Keyword, + Value: w.Value, + SqlType: w.SqlType, + }, nil +} + +type resultWire struct { + StatementId *string `json:"statement_id,omitempty"` + RowCount *int64 `json:"row_count,omitempty"` + IsTruncated *bool `json:"is_truncated,omitempty"` + StatementIdSignature *string `json:"statement_id_signature,omitempty"` +} + +func resultFromWire(w *resultWire) (*Result, error) { + if w == nil { + return nil, nil + } + return &Result{ + StatementId: w.StatementId, + RowCount: w.RowCount, + IsTruncated: w.IsTruncated, + StatementIdSignature: w.StatementIdSignature, + }, nil +} + +type resultDataWire struct { + ExternalLinks []externalLinkWire `json:"external_links,omitempty"` + DataArray []listValueWire `json:"data_array,omitempty"` + ChunkIndex *int `json:"chunk_index,omitempty"` + RowOffset *int64 `json:"row_offset,omitempty"` + RowCount *int64 `json:"row_count,omitempty"` + ByteCount *int64 `json:"byte_count,omitempty"` + NextChunkIndex *int `json:"next_chunk_index,omitempty"` + NextChunkInternalLink *string `json:"next_chunk_internal_link,omitempty"` +} + +func resultDataFromWire(w *resultDataWire) (*ResultData, error) { + if w == nil { + return nil, nil + } + externalLinksPublicValue, err := convertSlice(w.ExternalLinks, externalLinkFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResultData.ExternalLinks", err) + } + dataArrayPublicValue, err := convertSlice(w.DataArray, listValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResultData.DataArray", err) + } + return &ResultData{ + ExternalLinks: externalLinksPublicValue, + DataArray: dataArrayPublicValue, + ChunkIndex: w.ChunkIndex, + RowOffset: w.RowOffset, + RowCount: w.RowCount, + ByteCount: w.ByteCount, + NextChunkIndex: w.NextChunkIndex, + NextChunkInternalLink: w.NextChunkInternalLink, + }, nil +} + +type resultManifestWire struct { + Format Format `json:"format,omitempty"` + Schema *schemaWire `json:"schema,omitempty"` + TotalChunkCount *int `json:"total_chunk_count,omitempty"` + Chunks []chunkInfoWire `json:"chunks,omitempty"` + TotalRowCount *int64 `json:"total_row_count,omitempty"` + TotalByteCount *int64 `json:"total_byte_count,omitempty"` + Truncated *bool `json:"truncated,omitempty"` +} + +func resultManifestFromWire(w *resultManifestWire) (*ResultManifest, error) { + if w == nil { + return nil, nil + } + schemaPublicValue, err := schemaFromWire(w.Schema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResultManifest.Schema", err) + } + chunksPublicValue, err := convertSlice(w.Chunks, chunkInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResultManifest.Chunks", err) + } + return &ResultManifest{ + Format: w.Format, + Schema: schemaPublicValue, + TotalChunkCount: w.TotalChunkCount, + Chunks: chunksPublicValue, + TotalRowCount: w.TotalRowCount, + TotalByteCount: w.TotalByteCount, + Truncated: w.Truncated, + }, nil +} + +type schemaWire struct { + ColumnCount *int `json:"column_count,omitempty"` + Columns []columnInfoWire `json:"columns,omitempty"` +} + +func schemaFromWire(w *schemaWire) (*Schema, error) { + if w == nil { + return nil, nil + } + columnsPublicValue, err := convertSlice(w.Columns, columnInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Schema.Columns", err) + } + return &Schema{ + ColumnCount: w.ColumnCount, + Columns: columnsPublicValue, + }, nil +} + +type statementResponseWire struct { + StatementId *string `json:"statement_id,omitempty"` + Status *statementStatusWire `json:"status,omitempty"` + Manifest *resultManifestWire `json:"manifest,omitempty"` + Result *resultDataWire `json:"result,omitempty"` +} + +func statementResponseFromWire(w *statementResponseWire) (*StatementResponse, error) { + if w == nil { + return nil, nil + } + statusPublicValue, err := statementStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StatementResponse.Status", err) + } + manifestPublicValue, err := resultManifestFromWire(w.Manifest) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StatementResponse.Manifest", err) + } + resultPublicValue, err := resultDataFromWire(w.Result) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StatementResponse.Result", err) + } + return &StatementResponse{ + StatementId: w.StatementId, + Status: statusPublicValue, + Manifest: manifestPublicValue, + Result: resultPublicValue, + }, nil +} + +type statementStatusWire struct { + State StatementStatus_State `json:"state,omitempty"` + Error *databricksServiceExceptionProtoWire `json:"error,omitempty"` + SqlState *string `json:"sql_state,omitempty"` +} + +func statementStatusFromWire(w *statementStatusWire) (*StatementStatus, error) { + if w == nil { + return nil, nil + } + errorPublicValue, err := databricksServiceExceptionProtoFromWire(w.Error) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StatementStatus.Error", err) + } + return &StatementStatus{ + State: w.State, + Error: errorPublicValue, + SqlState: w.SqlState, + }, nil +} + +type structWire struct { + Fields []mapStringValueEntryWire `json:"fields,omitempty"` +} + +func structFromWire(w *structWire) (*Struct, error) { + if w == nil { + return nil, nil + } + fieldsPublicValue, err := convertSlice(w.Fields, mapStringValueEntryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Struct.Fields", err) + } + return &Struct{ + Fields: fieldsPublicValue, + }, nil +} + +type textAttachmentWire struct { + Content *string `json:"content,omitempty"` + Id *string `json:"id,omitempty"` + Purpose TextAttachmentPurpose `json:"purpose,omitempty"` +} + +func textAttachmentFromWire(w *textAttachmentWire) (*TextAttachment, error) { + if w == nil { + return nil, nil + } + return &TextAttachment{ + Content: w.Content, + Id: w.Id, + Purpose: w.Purpose, + }, nil +} + +type thoughtWire struct { + ThoughtType ThoughtType `json:"thought_type,omitempty"` + Content *string `json:"content,omitempty"` +} + +func thoughtFromWire(w *thoughtWire) (*Thought, error) { + if w == nil { + return nil, nil + } + return &Thought{ + ThoughtType: w.ThoughtType, + Content: w.Content, + }, nil +} + +type valueWire struct { + NullValue NullValue `json:"null_value,omitempty"` + NumberValue *float64 `json:"number_value,omitempty"` + StringValue *string `json:"string_value,omitempty"` + BoolValue *bool `json:"bool_value,omitempty"` + StructValue *structWire `json:"struct_value,omitempty"` + ListValue *listValueWire `json:"list_value,omitempty"` +} + +func valueFromWire(w *valueWire) (*Value, error) { + if w == nil { + return nil, nil + } + kindMembers := 0 + if w.NullValue != "" { + kindMembers++ + } + if w.NumberValue != nil { + kindMembers++ + } + if w.StringValue != nil { + kindMembers++ + } + if w.BoolValue != nil { + kindMembers++ + } + if w.StructValue != nil { + kindMembers++ + } + if w.ListValue != nil { + kindMembers++ + } + if kindMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Value.Kind") + } + var kindSelection isValue_Kind + switch { + case w.NullValue != "": + kindSelection = &Value_Kind_NullValue{NullValue: w.NullValue} + case w.NumberValue != nil: + kindSelection = &Value_Kind_NumberValue{NumberValue: *w.NumberValue} + case w.StringValue != nil: + kindSelection = &Value_Kind_StringValue{StringValue: *w.StringValue} + case w.BoolValue != nil: + kindSelection = &Value_Kind_BoolValue{BoolValue: *w.BoolValue} + case w.StructValue != nil: + kindStructValueConverted, err := structFromWire(w.StructValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Value.Kind.StructValue", err) + } + kindSelection = &Value_Kind_StructValue{StructValue: *kindStructValueConverted} + case w.ListValue != nil: + kindListValueConverted, err := listValueFromWire(w.ListValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Value.Kind.ListValue", err) + } + kindSelection = &Value_Kind_ListValue{ListValue: *kindListValueConverted} + } + return &Value{ + Kind: kindSelection, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/gitcredentials/.package.json b/gitcredentials/.package.json new file mode 100644 index 0000000..1227315 --- /dev/null +++ b/gitcredentials/.package.json @@ -0,0 +1,3 @@ +{ + "package": "gitcredentials" +} diff --git a/gitcredentials/CHANGELOG.md b/gitcredentials/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/gitcredentials/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/gitcredentials/README.md b/gitcredentials/README.md new file mode 100644 index 0000000..16d7002 --- /dev/null +++ b/gitcredentials/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/gitcredentials + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/gitcredentials@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/gitcredentials/v1" + +client, err := gitcredentials.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/gitcredentials/go.mod b/gitcredentials/go.mod new file mode 100644 index 0000000..81582da --- /dev/null +++ b/gitcredentials/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/gitcredentials + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/gitcredentials/internal/version.go b/gitcredentials/internal/version.go new file mode 100644 index 0000000..76c6eb9 --- /dev/null +++ b/gitcredentials/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-gitcredentials" + +const Version = "0.0.1-dev.1" diff --git a/gitcredentials/v1/client.go b/gitcredentials/v1/client.go new file mode 100755 index 0000000..210a77b --- /dev/null +++ b/gitcredentials/v1/client.go @@ -0,0 +1,396 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package gitcredentials + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/gitcredentials/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a Git credential entry for the user. Use the PATCH endpoint to update +// existing credentials, or the DELETE endpoint to delete existing credentials. +func (c *internalClient) CreateCredentials(ctx context.Context, req *CreateCredentialsRequest, opts ...call.Option) (*CreateCredentialsResponse, error) { + wireReq, err := createCredentialsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/git-credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateCredentialsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createCredentialsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createCredentialsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the specified Git credential. +func (c *internalClient) DeleteCredentials(ctx context.Context, req *DeleteCredentialsRequest, opts ...call.Option) (*DeleteCredentialsResponse, error) { + wireReq, err := deleteCredentialsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/git-credentials/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "principal_id", wireReq.PrincipalId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteCredentialsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteCredentialsResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the Git credential with the specified credential ID. +func (c *internalClient) GetCredentials(ctx context.Context, req *GetCredentialsRequest, opts ...call.Option) (*GetCredentialsResponse, error) { + wireReq, err := getCredentialsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/git-credentials/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "principal_id", wireReq.PrincipalId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetCredentialsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getCredentialsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getCredentialsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists the calling user's Git credentials. +func (c *internalClient) ListCredentials(ctx context.Context, req *ListCredentialsRequest, opts ...call.Option) (*ListCredentialsResponse, error) { + wireReq, err := listCredentialsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/git-credentials" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "principal_id", wireReq.PrincipalId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCredentialsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCredentialsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCredentialsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the specified Git credential. +func (c *internalClient) UpdateCredentials(ctx context.Context, req *UpdateCredentialsRequest, opts ...call.Option) (*UpdateCredentialsResponse, error) { + wireReq, err := updateCredentialsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/git-credentials/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateCredentialsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateCredentialsResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/gitcredentials/v1/genhelper.go b/gitcredentials/v1/genhelper.go new file mode 100755 index 0000000..0372533 --- /dev/null +++ b/gitcredentials/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package gitcredentials + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/gitcredentials/v1/model.go b/gitcredentials/v1/model.go new file mode 100755 index 0000000..fe977fa --- /dev/null +++ b/gitcredentials/v1/model.go @@ -0,0 +1,179 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package gitcredentials + +type CreateCredentialsRequest struct { + // Git provider. This field is case-insensitive. The available Git providers are + // `gitHub`, `bitbucketCloud`, `gitLab`, `azureDevOpsServices` (Azure DevOps + // Services, including Microsoft Entra ID authentication), `gitHubEnterprise`, + // `bitbucketServer` (Bitbucket Data Center), `gitLabEnterpriseEdition` (GitLab + // Self-Managed), and `awsCodeCommit`. + GitProvider *string + // The username provided with your Git provider account and associated with the + // credential. For most Git providers it is only used to set the Git committer & + // author names for commits, however it may be required for authentication + // depending on your Git provider / token requirements. Required for AWS + // CodeCommit. + GitUsername *string + // The personal access token used to authenticate to the corresponding Git + // provider. For certain providers, support may exist for other types of scoped + // access tokens. [Learn more]. + // + // [Learn more]: https://docs.databricks.com/repos/get-access-tokens-from-git-provider.html + PersonalAccessToken *string + // The ID of the service principal whose credentials will be modified. Only + // service principal managers can perform this action. + PrincipalId *int64 + // the name of the git credential, used for identification and ease of lookup + Name *string + // if the credential is the default for the given provider + IsDefaultForProvider *bool + // The authenticating email associated with your Git provider user account. Used + // for authentication with the remote repository and also sets the author & + // committer identity for commits. Required for most Git providers except AWS + // CodeCommit. Learn more at + // https://docs.databricks.com/aws/en/repos/get-access-tokens-from-git-provider + GitEmail *string +} + +type CreateCredentialsResponse struct { + // ID of the credential object in the workspace. + CredentialId *int64 + // The Git provider associated with the credential. + GitProvider *string + // The username provided with your Git provider account and associated with the + // credential. For most Git providers it is only used to set the Git committer & + // author names for commits, however it may be required for authentication + // depending on your Git provider / token requirements. Required for AWS + // CodeCommit. + GitUsername *string + // the name of the git credential, used for identification and ease of lookup + Name *string + // if the credential is the default for the given provider + IsDefaultForProvider *bool + // The authenticating email associated with your Git provider user account. Used + // for authentication with the remote repository and also sets the author & + // committer identity for commits. Required for most Git providers except AWS + // CodeCommit. Learn more at + // https://docs.databricks.com/aws/en/repos/get-access-tokens-from-git-provider + GitEmail *string +} + +type Credential struct { + // ID of the credential object in the workspace. + CredentialId *int64 + // The Git provider associated with the credential. One of `gitHub`, + // `bitbucketCloud`, `gitLab`, `azureDevOpsServices` (Azure DevOps Services, + // including Microsoft Entra ID authentication), `gitHubEnterprise`, + // `bitbucketServer` (Bitbucket Data Center), `gitLabEnterpriseEdition` (GitLab + // Self-Managed), or `awsCodeCommit`. + GitProvider *string + // The username provided with your Git provider account and associated with the + // credential. For most Git providers it is only used to set the Git committer & + // author names for commits, however it may be required for authentication + // depending on your Git provider / token requirements. Required for AWS + // CodeCommit. + GitUsername *string + // the name of the git credential, used for identification and ease of lookup + Name *string + // if the credential is the default for the given provider + IsDefaultForProvider *bool + // The authenticating email associated with your Git provider user account. Used + // for authentication with the remote repository and also sets the author & + // committer identity for commits. Required for most Git providers except AWS + // CodeCommit. Learn more at + // https://docs.databricks.com/aws/en/repos/get-access-tokens-from-git-provider + GitEmail *string +} + +type DeleteCredentialsRequest struct { + // The ID for the corresponding credential to access. + Id *int64 + // The ID of the service principal whose credentials will be modified. Only + // service principal managers can perform this action. + PrincipalId *int64 +} + +type DeleteCredentialsResponse struct { +} + +type GetCredentialsRequest struct { + // The ID for the corresponding credential to access. + Id *int64 + // The ID of the service principal whose credentials will be modified. Only + // service principal managers can perform this action. + PrincipalId *int64 +} + +type GetCredentialsResponse struct { + // ID of the credential object in the workspace. + CredentialId *int64 + // The Git provider associated with the credential. + GitProvider *string + // The username provided with your Git provider account and associated with the + // credential. For most Git providers it is only used to set the Git committer & + // author names for commits, however it may be required for authentication + // depending on your Git provider / token requirements. Required for AWS + // CodeCommit. + GitUsername *string + // the name of the git credential, used for identification and ease of lookup + Name *string + // if the credential is the default for the given provider + IsDefaultForProvider *bool + // The authenticating email associated with your Git provider user account. Used + // for authentication with the remote repository and also sets the author & + // committer identity for commits. Required for most Git providers except AWS + // CodeCommit. Learn more at + // https://docs.databricks.com/aws/en/repos/get-access-tokens-from-git-provider + GitEmail *string +} + +type ListCredentialsRequest struct { + // The ID of the service principal whose credentials will be listed. Only + // service principal managers can perform this action. + PrincipalId *int64 +} + +type ListCredentialsResponse struct { + // List of credentials. + Credentials []Credential +} + +type UpdateCredentialsRequest struct { + // The ID for the corresponding credential to access. + Id *int64 + // The personal access token used to authenticate to the corresponding Git + // provider. For certain providers, support may exist for other types of scoped + // access tokens. [Learn more]. + // + // [Learn more]: https://docs.databricks.com/repos/get-access-tokens-from-git-provider.html + PersonalAccessToken *string + // Git provider. This field is case-insensitive. The available Git providers are + // `gitHub`, `bitbucketCloud`, `gitLab`, `azureDevOpsServices` (Azure DevOps + // Services, including Microsoft Entra ID authentication), `gitHubEnterprise`, + // `bitbucketServer` (Bitbucket Data Center), `gitLabEnterpriseEdition` (GitLab + // Self-Managed), and `awsCodeCommit`. + GitProvider *string + // The username provided with your Git provider account and associated with the + // credential. For most Git providers it is only used to set the Git committer & + // author names for commits, however it may be required for authentication + // depending on your Git provider / token requirements. Required for AWS + // CodeCommit. + GitUsername *string + // The ID of the service principal whose credentials will be modified. Only + // service principal managers can perform this action. + PrincipalId *int64 + // the name of the git credential, used for identification and ease of lookup + Name *string + // if the credential is the default for the given provider + IsDefaultForProvider *bool + // The authenticating email associated with your Git provider user account. Used + // for authentication with the remote repository and also sets the author & + // committer identity for commits. Required for most Git providers except AWS + // CodeCommit. Learn more at + // https://docs.databricks.com/aws/en/repos/get-access-tokens-from-git-provider + GitEmail *string +} + +type UpdateCredentialsResponse struct { +} diff --git a/gitcredentials/v1/wire.go b/gitcredentials/v1/wire.go new file mode 100755 index 0000000..c8c865b --- /dev/null +++ b/gitcredentials/v1/wire.go @@ -0,0 +1,203 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package gitcredentials + +import ( + "fmt" +) + +type createCredentialsRequestWire struct { + GitProvider *string `json:"git_provider,omitempty"` + GitUsername *string `json:"git_username,omitempty"` + PersonalAccessToken *string `json:"personal_access_token,omitempty"` + PrincipalId *int64 `json:"principal_id,omitempty"` + Name *string `json:"name,omitempty"` + IsDefaultForProvider *bool `json:"is_default_for_provider,omitempty"` + GitEmail *string `json:"git_email,omitempty"` +} + +func createCredentialsRequestToWire(v *CreateCredentialsRequest) (*createCredentialsRequestWire, error) { + if v == nil { + return nil, nil + } + return &createCredentialsRequestWire{ + GitProvider: v.GitProvider, + GitUsername: v.GitUsername, + PersonalAccessToken: v.PersonalAccessToken, + PrincipalId: v.PrincipalId, + Name: v.Name, + IsDefaultForProvider: v.IsDefaultForProvider, + GitEmail: v.GitEmail, + }, nil +} + +type createCredentialsResponseWire struct { + CredentialId *int64 `json:"credential_id,omitempty"` + GitProvider *string `json:"git_provider,omitempty"` + GitUsername *string `json:"git_username,omitempty"` + Name *string `json:"name,omitempty"` + IsDefaultForProvider *bool `json:"is_default_for_provider,omitempty"` + GitEmail *string `json:"git_email,omitempty"` +} + +func createCredentialsResponseFromWire(w *createCredentialsResponseWire) (*CreateCredentialsResponse, error) { + if w == nil { + return nil, nil + } + return &CreateCredentialsResponse{ + CredentialId: w.CredentialId, + GitProvider: w.GitProvider, + GitUsername: w.GitUsername, + Name: w.Name, + IsDefaultForProvider: w.IsDefaultForProvider, + GitEmail: w.GitEmail, + }, nil +} + +type credentialWire struct { + CredentialId *int64 `json:"credential_id,omitempty"` + GitProvider *string `json:"git_provider,omitempty"` + GitUsername *string `json:"git_username,omitempty"` + Name *string `json:"name,omitempty"` + IsDefaultForProvider *bool `json:"is_default_for_provider,omitempty"` + GitEmail *string `json:"git_email,omitempty"` +} + +func credentialFromWire(w *credentialWire) (*Credential, error) { + if w == nil { + return nil, nil + } + return &Credential{ + CredentialId: w.CredentialId, + GitProvider: w.GitProvider, + GitUsername: w.GitUsername, + Name: w.Name, + IsDefaultForProvider: w.IsDefaultForProvider, + GitEmail: w.GitEmail, + }, nil +} + +type deleteCredentialsRequestWire struct { + Id *int64 `json:"id,omitempty"` + PrincipalId *int64 `json:"principal_id,omitempty"` +} + +func deleteCredentialsRequestToWire(v *DeleteCredentialsRequest) (*deleteCredentialsRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteCredentialsRequestWire{ + Id: v.Id, + PrincipalId: v.PrincipalId, + }, nil +} + +type getCredentialsRequestWire struct { + Id *int64 `json:"id,omitempty"` + PrincipalId *int64 `json:"principal_id,omitempty"` +} + +func getCredentialsRequestToWire(v *GetCredentialsRequest) (*getCredentialsRequestWire, error) { + if v == nil { + return nil, nil + } + return &getCredentialsRequestWire{ + Id: v.Id, + PrincipalId: v.PrincipalId, + }, nil +} + +type getCredentialsResponseWire struct { + CredentialId *int64 `json:"credential_id,omitempty"` + GitProvider *string `json:"git_provider,omitempty"` + GitUsername *string `json:"git_username,omitempty"` + Name *string `json:"name,omitempty"` + IsDefaultForProvider *bool `json:"is_default_for_provider,omitempty"` + GitEmail *string `json:"git_email,omitempty"` +} + +func getCredentialsResponseFromWire(w *getCredentialsResponseWire) (*GetCredentialsResponse, error) { + if w == nil { + return nil, nil + } + return &GetCredentialsResponse{ + CredentialId: w.CredentialId, + GitProvider: w.GitProvider, + GitUsername: w.GitUsername, + Name: w.Name, + IsDefaultForProvider: w.IsDefaultForProvider, + GitEmail: w.GitEmail, + }, nil +} + +type listCredentialsRequestWire struct { + PrincipalId *int64 `json:"principal_id,omitempty"` +} + +func listCredentialsRequestToWire(v *ListCredentialsRequest) (*listCredentialsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCredentialsRequestWire{ + PrincipalId: v.PrincipalId, + }, nil +} + +type listCredentialsResponseWire struct { + Credentials []credentialWire `json:"credentials,omitempty"` +} + +func listCredentialsResponseFromWire(w *listCredentialsResponseWire) (*ListCredentialsResponse, error) { + if w == nil { + return nil, nil + } + credentialsPublicValue, err := convertSlice(w.Credentials, credentialFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCredentialsResponse.Credentials", err) + } + return &ListCredentialsResponse{ + Credentials: credentialsPublicValue, + }, nil +} + +type updateCredentialsRequestWire struct { + Id *int64 `json:"id,omitempty"` + PersonalAccessToken *string `json:"personal_access_token,omitempty"` + GitProvider *string `json:"git_provider,omitempty"` + GitUsername *string `json:"git_username,omitempty"` + PrincipalId *int64 `json:"principal_id,omitempty"` + Name *string `json:"name,omitempty"` + IsDefaultForProvider *bool `json:"is_default_for_provider,omitempty"` + GitEmail *string `json:"git_email,omitempty"` +} + +func updateCredentialsRequestToWire(v *UpdateCredentialsRequest) (*updateCredentialsRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateCredentialsRequestWire{ + Id: v.Id, + PersonalAccessToken: v.PersonalAccessToken, + GitProvider: v.GitProvider, + GitUsername: v.GitUsername, + PrincipalId: v.PrincipalId, + Name: v.Name, + IsDefaultForProvider: v.IsDefaultForProvider, + GitEmail: v.GitEmail, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/globalinitscripts/.package.json b/globalinitscripts/.package.json new file mode 100644 index 0000000..c4ed212 --- /dev/null +++ b/globalinitscripts/.package.json @@ -0,0 +1,3 @@ +{ + "package": "globalinitscripts" +} diff --git a/globalinitscripts/CHANGELOG.md b/globalinitscripts/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/globalinitscripts/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/globalinitscripts/README.md b/globalinitscripts/README.md new file mode 100644 index 0000000..18a8fed --- /dev/null +++ b/globalinitscripts/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/globalinitscripts + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/globalinitscripts@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/globalinitscripts/v2" + +client, err := globalinitscripts.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/globalinitscripts/go.mod b/globalinitscripts/go.mod new file mode 100644 index 0000000..87c24be --- /dev/null +++ b/globalinitscripts/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/globalinitscripts + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/globalinitscripts/internal/version.go b/globalinitscripts/internal/version.go new file mode 100644 index 0000000..1062753 --- /dev/null +++ b/globalinitscripts/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-globalinitscripts" + +const Version = "0.0.1-dev.1" diff --git a/globalinitscripts/v2/client.go b/globalinitscripts/v2/client.go new file mode 100755 index 0000000..62f0352 --- /dev/null +++ b/globalinitscripts/v2/client.go @@ -0,0 +1,378 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package globalinitscripts + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/globalinitscripts/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new global init script in this workspace. +func (c *internalClient) CreateGlobalInitScript(ctx context.Context, req *CreateGlobalInitScriptRequest, opts ...call.Option) (*CreateGlobalInitScriptResponse, error) { + wireReq, err := createGlobalInitScriptRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/global-init-scripts" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateGlobalInitScriptResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createGlobalInitScriptResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createGlobalInitScriptResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a global init script. +func (c *internalClient) DeleteGlobalInitScript(ctx context.Context, req *DeleteGlobalInitScriptRequest, opts ...call.Option) (*DeleteGlobalInitScriptResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/global-init-scripts/") + pb.singleSegment(*req.ScriptId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteGlobalInitScriptResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteGlobalInitScriptResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets all the details of a script, including its Base64-encoded contents. +func (c *internalClient) GetGlobalInitScript(ctx context.Context, req *GetGlobalInitScriptRequest, opts ...call.Option) (*GlobalInitScriptDetails, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/global-init-scripts/") + pb.singleSegment(*req.ScriptId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GlobalInitScriptDetails + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp globalInitScriptDetailsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = globalInitScriptDetailsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a list of all global init scripts for this workspace. This returns all +// properties for each script but **not** the script contents. To retrieve the +// contents of a script, use the [get a global init +// script](:method:globalinitscripts/get) operation. +func (c *internalClient) ListGlobalInitScripts(ctx context.Context, req *ListGlobalInitScriptsRequest, opts ...call.Option) (*ListGlobalInitScriptsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/global-init-scripts" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListGlobalInitScriptsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listGlobalInitScriptsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listGlobalInitScriptsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a global init script, specifying only the fields to change. All +// fields are optional. Unspecified fields retain their current value. +func (c *internalClient) UpdateGlobalInitScript(ctx context.Context, req *UpdateGlobalInitScriptRequest, opts ...call.Option) (*UpdateGlobalInitScriptResponse, error) { + wireReq, err := updateGlobalInitScriptRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/global-init-scripts/") + pb.singleSegment(*req.ScriptId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateGlobalInitScriptResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateGlobalInitScriptResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/globalinitscripts/v2/genhelper.go b/globalinitscripts/v2/genhelper.go new file mode 100755 index 0000000..2427b06 --- /dev/null +++ b/globalinitscripts/v2/genhelper.go @@ -0,0 +1,188 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package globalinitscripts + +import ( + "context" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/globalinitscripts/v2/model.go b/globalinitscripts/v2/model.go new file mode 100755 index 0000000..0a6ec01 --- /dev/null +++ b/globalinitscripts/v2/model.go @@ -0,0 +1,98 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package globalinitscripts + +type CreateGlobalInitScriptRequest struct { + // The name of the script + Name *string + // The Base64-encoded content of the script. + Script []byte + // The position of a global init script, where 0 represents the first script to + // run, 1 is the second script to run, in ascending order. + // + // If you omit the numeric position for a new global init script, it defaults to + // last position. It will run after all current scripts. Setting any value + // greater than the position of the last script is equivalent to the last + // position. Example: Take three existing scripts with positions 0, 1, and 2. + // Any position of (3) or greater puts the script in the last position. If an + // explicit position value conflicts with an existing script value, your request + // succeeds, but the original script at that position and all later scripts have + // their positions incremented by 1. + Position *int + // Specifies whether the script is enabled. The script runs only if enabled. + Enabled *bool +} + +type CreateGlobalInitScriptResponse struct { + // The global init script ID. + ScriptId *string +} + +type DeleteGlobalInitScriptRequest struct { + // The ID of the global init script. + ScriptId *string +} + +type DeleteGlobalInitScriptResponse struct { +} + +type GetGlobalInitScriptRequest struct { + // The ID of the global init script. + ScriptId *string +} + +type GlobalInitScriptDetails struct { + // The global init script ID. + ScriptId *string + // The name of the script + Name *string + // The position of a script, where 0 represents the first script to run, 1 is + // the second script to run, in ascending order. + Position *int + // Specifies whether the script is enabled. The script runs only if enabled. + Enabled *bool + // The username of the user who created the script. + CreatedBy *string + // Time when the script was created, represented as a Unix timestamp in + // milliseconds. + CreatedAt *int64 + // The username of the user who last updated the script + UpdatedBy *string + // Time when the script was updated, represented as a Unix timestamp in + // milliseconds. + UpdatedAt *int64 +} + +type ListGlobalInitScriptsRequest struct { +} + +type ListGlobalInitScriptsResponse struct { + Scripts []GlobalInitScriptDetails +} + +type UpdateGlobalInitScriptRequest struct { + // The ID of the global init script. + ScriptId *string + // The name of the script + Name *string + // The Base64-encoded content of the script. + Script []byte + // The position of a script, where 0 represents the first script to run, 1 is + // the second script to run, in ascending order. To move the script to run + // first, set its position to 0. + // + // To move the script to the end, set its position to any value greater or equal + // to the position of the last script. Example, three existing scripts with + // positions 0, 1, and 2. Any position value of 2 or greater puts the script in + // the last position (2). + // + // If an explicit position value conflicts with an existing script, your request + // succeeds, but the original script at that position and all later scripts have + // their positions incremented by 1. + Position *int + // Specifies whether the script is enabled. The script runs only if enabled. + Enabled *bool +} + +type UpdateGlobalInitScriptResponse struct { +} diff --git a/globalinitscripts/v2/wire.go b/globalinitscripts/v2/wire.go new file mode 100755 index 0000000..e9879d3 --- /dev/null +++ b/globalinitscripts/v2/wire.go @@ -0,0 +1,119 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package globalinitscripts + +import ( + "fmt" +) + +type createGlobalInitScriptRequestWire struct { + Name *string `json:"name,omitempty"` + Script []byte `json:"script,omitempty"` + Position *int `json:"position,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func createGlobalInitScriptRequestToWire(v *CreateGlobalInitScriptRequest) (*createGlobalInitScriptRequestWire, error) { + if v == nil { + return nil, nil + } + return &createGlobalInitScriptRequestWire{ + Name: v.Name, + Script: v.Script, + Position: v.Position, + Enabled: v.Enabled, + }, nil +} + +type createGlobalInitScriptResponseWire struct { + ScriptId *string `json:"script_id,omitempty"` +} + +func createGlobalInitScriptResponseFromWire(w *createGlobalInitScriptResponseWire) (*CreateGlobalInitScriptResponse, error) { + if w == nil { + return nil, nil + } + return &CreateGlobalInitScriptResponse{ + ScriptId: w.ScriptId, + }, nil +} + +type globalInitScriptDetailsWire struct { + ScriptId *string `json:"script_id,omitempty"` + Name *string `json:"name,omitempty"` + Position *int `json:"position,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` +} + +func globalInitScriptDetailsFromWire(w *globalInitScriptDetailsWire) (*GlobalInitScriptDetails, error) { + if w == nil { + return nil, nil + } + return &GlobalInitScriptDetails{ + ScriptId: w.ScriptId, + Name: w.Name, + Position: w.Position, + Enabled: w.Enabled, + CreatedBy: w.CreatedBy, + CreatedAt: w.CreatedAt, + UpdatedBy: w.UpdatedBy, + UpdatedAt: w.UpdatedAt, + }, nil +} + +type listGlobalInitScriptsResponseWire struct { + Scripts []globalInitScriptDetailsWire `json:"scripts,omitempty"` +} + +func listGlobalInitScriptsResponseFromWire(w *listGlobalInitScriptsResponseWire) (*ListGlobalInitScriptsResponse, error) { + if w == nil { + return nil, nil + } + scriptsPublicValue, err := convertSlice(w.Scripts, globalInitScriptDetailsFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListGlobalInitScriptsResponse.Scripts", err) + } + return &ListGlobalInitScriptsResponse{ + Scripts: scriptsPublicValue, + }, nil +} + +type updateGlobalInitScriptRequestWire struct { + ScriptId *string `json:"script_id,omitempty"` + Name *string `json:"name,omitempty"` + Script []byte `json:"script,omitempty"` + Position *int `json:"position,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func updateGlobalInitScriptRequestToWire(v *UpdateGlobalInitScriptRequest) (*updateGlobalInitScriptRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateGlobalInitScriptRequestWire{ + ScriptId: v.ScriptId, + Name: v.Name, + Script: v.Script, + Position: v.Position, + Enabled: v.Enabled, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/go.work b/go.work index 9f8515c..abec0ba 100644 --- a/go.work +++ b/go.work @@ -1,8 +1,90 @@ go 1.26.0 use ( + ./accessmanagement + ./aigateway + ./alerts + ./apps ./auth + ./authentication + ./budgetpolicy + ./budgets + ./cleanrooms + ./clusterlibraries + ./clusterpolicies + ./clusters + ./commandexecution ./core + ./customllms + ./database + ./dataclassification + ./dataquality + ./disasterrecovery + ./environments + ./experiments + ./features + ./featurestore ./files + ./forecasting + ./genie + ./gitcredentials + ./globalinitscripts + ./instancepools + ./instanceprofiles + ./jobs + ./keyconfigurations + ./knowledgeassistants + ./lakeview + ./logdelivery + ./marketplaces + ./modelregistry + ./modelserving + ./modelservingquery + ./networking + ./notificationdestinations + ./oauth ./options + ./pipelines + ./policyfamilies + ./postgres + ./queries + ./queryhistory + ./repos + ./scim + ./secrets + ./settings + ./sharing + ./statementexecution + ./storageconfigurations + ./supervisoragents + ./tagassignments + ./tagpolicies + ./tokenmanagement + ./tokens + ./uc/abacpolicies + ./uc/artifactallowlists + ./uc/catalogs + ./uc/connections + ./uc/credentials + ./uc/entitytagassignments + ./uc/externallineage + ./uc/externallocations + ./uc/externalmetadata + ./uc/functions + ./uc/grants + ./uc/metastores + ./uc/onlinetables + ./uc/registeredmodels + ./uc/resourcequotas + ./uc/rfa + ./uc/schemas + ./uc/secrets + ./uc/systemschemas + ./uc/tables + ./uc/volumes + ./uc/workspacebindings + ./usagedashboards + ./vectorsearch + ./warehouses + ./workspaces ) diff --git a/go.work.sum b/go.work.sum index cbd322a..ad22bfd 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,11 +1,22 @@ +cloud.google.com/go v0.114.0 h1:OIPFAdfrFDFO2ve2U7r/H5SwSbBzEdrBdE7xkgwc+kY= +cloud.google.com/go v0.114.0/go.mod h1:ZV9La5YYxctro1HTPug5lXH/GefROyW8PPD4T8n9J8E= cloud.google.com/go/auth v0.4.2/go.mod h1:Kqvlz1cf1sNA0D+sYJnkPQOP+JMHkuHeIgVmCRtZOLc= cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= +cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= +cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50/go.mod h1:5e1+Vvlzido69INQaVO6d87Qn543Xr6nooe9Kz7oBFM= +github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= @@ -18,8 +29,13 @@ go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= google.golang.org/api v0.182.0/go.mod h1:cGhjy4caqA5yXRzEhkHI8Y9mfyC2VLTlER2l08xaqtM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20240521202816-d264139d666e/go.mod h1:0J6mmn3XAEjfNbPvpH63c0RXCjGNFcCzlEfWSN4In+k= google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= diff --git a/instancepools/.package.json b/instancepools/.package.json new file mode 100644 index 0000000..5fa8552 --- /dev/null +++ b/instancepools/.package.json @@ -0,0 +1,3 @@ +{ + "package": "instancepools" +} diff --git a/instancepools/CHANGELOG.md b/instancepools/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/instancepools/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/instancepools/README.md b/instancepools/README.md new file mode 100644 index 0000000..7cee4be --- /dev/null +++ b/instancepools/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/instancepools + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/instancepools@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/instancepools/v2" + +client, err := instancepools.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/instancepools/go.mod b/instancepools/go.mod new file mode 100644 index 0000000..565688d --- /dev/null +++ b/instancepools/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/instancepools + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/instancepools/internal/version.go b/instancepools/internal/version.go new file mode 100644 index 0000000..e03a04d --- /dev/null +++ b/instancepools/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-instancepools" + +const Version = "0.0.1-dev.1" diff --git a/instancepools/v2/client.go b/instancepools/v2/client.go new file mode 100755 index 0000000..b27e70d --- /dev/null +++ b/instancepools/v2/client.go @@ -0,0 +1,382 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package instancepools + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/instancepools/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new instance pool using idle and ready-to-use cloud instances. +func (c *internalClient) CreateInstancePool(ctx context.Context, req *CreateInstancePoolRequest, opts ...call.Option) (*CreateInstancePoolResponse, error) { + wireReq, err := createInstancePoolRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/instance-pools/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateInstancePoolResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createInstancePoolResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createInstancePoolResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the instance pool permanently. The idle instances in the pool are +// terminated asynchronously. +func (c *internalClient) DeleteInstancePool(ctx context.Context, req *DeleteInstancePoolRequest, opts ...call.Option) (*DeleteInstancePoolResponse, error) { + wireReq, err := deleteInstancePoolRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/instance-pools/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteInstancePoolResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteInstancePoolResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Modifies the configuration of an existing instance pool. +func (c *internalClient) EditInstancePool(ctx context.Context, req *EditInstancePoolRequest, opts ...call.Option) (*EditInstancePoolResponse, error) { + wireReq, err := editInstancePoolRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/instance-pools/edit" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EditInstancePoolResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &EditInstancePoolResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieve the information for an instance pool based on its identifier. +func (c *internalClient) GetInstancePool(ctx context.Context, req *GetInstancePoolRequest, opts ...call.Option) (*GetInstancePoolResponse, error) { + wireReq, err := getInstancePoolRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/instance-pools/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "instance_pool_id", wireReq.InstancePoolId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetInstancePoolResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getInstancePoolResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getInstancePoolResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a list of instance pools with their statistics. +func (c *internalClient) ListInstancePools(ctx context.Context, req *ListInstancePoolsRequest, opts ...call.Option) (*ListInstancePoolsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/instance-pools/list" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListInstancePoolsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listInstancePoolsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listInstancePoolsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/instancepools/v2/genhelper.go b/instancepools/v2/genhelper.go new file mode 100755 index 0000000..99c8629 --- /dev/null +++ b/instancepools/v2/genhelper.go @@ -0,0 +1,178 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package instancepools + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} diff --git a/instancepools/v2/model.go b/instancepools/v2/model.go new file mode 100755 index 0000000..9816ad6 --- /dev/null +++ b/instancepools/v2/model.go @@ -0,0 +1,637 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package instancepools + +// Availability type used for all subsequent nodes past the `first_on_demand` +// ones. +// +// Note: If `first_on_demand` is zero, this availability type will be used for +// the entire cluster. +type AwsAvailability string + +const ( + AwsAvailability_Unspecified AwsAvailability = "" + // Use spot instances. + AwsAvailability_Spot AwsAvailability = "SPOT" + // Use on-demand instances. + AwsAvailability_OnDemand AwsAvailability = "ON_DEMAND" + // Preferably use spot instances, but fall back to on-demand instances if spot + // instances cannot be acquired (e.g., if AWS spot prices are too high). + AwsAvailability_SpotWithFallback AwsAvailability = "SPOT_WITH_FALLBACK" +) + +// Availability type used for all subsequent nodes past the `first_on_demand` +// ones. Note: If `first_on_demand` is zero, this availability type will be used +// for the entire cluster. +type AzureAvailability string + +const ( + AzureAvailability_Unspecified AzureAvailability = "" + // Use spot instances. + AzureAvailability_SpotAzure AzureAvailability = "SPOT_AZURE" + // Use on-demand instances. + AzureAvailability_OnDemandAzure AzureAvailability = "ON_DEMAND_AZURE" + // Preferably use spot instances, but fall back to on-demand instances if spot + // instances cannot be acquired (e.g., if Azure is out of Quota). + AzureAvailability_SpotWithFallbackAzure AzureAvailability = "SPOT_WITH_FALLBACK_AZURE" +) + +// All Azure Disk types that supports. See +// https://docs.microsoft.com/en-us/azure/storage/storage-about-disks-and-vhds-linux#types-of-disks +type AzureDiskVolumeType string + +const ( + AzureDiskVolumeType_Unspecified AzureDiskVolumeType = "" + // Premium storage tier, backed by SSDs. + AzureDiskVolumeType_PremiumLrs AzureDiskVolumeType = "PREMIUM_LRS" + // Standard storage tier, backed by HDDs. + AzureDiskVolumeType_StandardLrs AzureDiskVolumeType = "STANDARD_LRS" +) + +// All EBS volume types that supports. See +// https://aws.amazon.com/ebs/details/ for details. +type EbsVolumeType string + +const ( + EbsVolumeType_Unspecified EbsVolumeType = "" + // Provision extra storage using AWS gp2 EBS volumes. + EbsVolumeType_GeneralPurposeSsd EbsVolumeType = "GENERAL_PURPOSE_SSD" + // Provision extra storage using AWS st1 volumes. + EbsVolumeType_ThroughputOptimizedHdd EbsVolumeType = "THROUGHPUT_OPTIMIZED_HDD" +) + +// This field determines whether the instance pool will contain preemptible VMs, +// on-demand VMs, or preemptible VMs with a fallback to on-demand VMs if the +// former is unavailable. +type GcpAvailability string + +const ( + GcpAvailability_Unspecified GcpAvailability = "" + GcpAvailability_PreemptibleGcp GcpAvailability = "PREEMPTIBLE_GCP" + GcpAvailability_OnDemandGcp GcpAvailability = "ON_DEMAND_GCP" + GcpAvailability_PreemptibleWithFallbackGcp GcpAvailability = "PREEMPTIBLE_WITH_FALLBACK_GCP" +) + +// The state of a Cluster. The current allowable state transitions are as +// follows: +// +// - “ACTIVE“ -> “STOPPED“ - “ACTIVE“ -> “DELETED“ - “STOPPED“ -> +// “ACTIVE“ - “STOPPED“ -> “DELETED“ +type InstancePoolState string + +const ( + InstancePoolState_Unspecified InstancePoolState = "" + // Indicates an instance pool is active for use. + InstancePoolState_Active InstancePoolState = "ACTIVE" + // Indicates an instance pool has been stopped so no more clusters should be + // able to get instances from the pool. + InstancePoolState_Stopped InstancePoolState = "STOPPED" + // Indicates the instance pool has been deleted and should no longer exist. + InstancePoolState_Deleted InstancePoolState = "DELETED" +) + +type CreateInstancePoolRequest struct { + // Pool name requested by the user. Pool name must be unique. Length must be + // between 1 and 100 characters. + InstancePoolName *string + // Minimum number of idle instances to keep in the instance pool + MinIdleInstances *int + // Maximum number of outstanding instances to keep in the pool, including both + // instances used by clusters and idle instances. Clusters that require further + // instance provisioning will fail during upsize requests. + MaxCapacity *int + // Attributes related to instance pools running on Amazon Web Services. If not + // specified at pool creation, a set of default values will be used. + AwsAttributes *InstancePoolAwsAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // Additional tags for pool resources. will tag all pool resources + // (e.g., AWS instances and EBS volumes) with these tags in addition to + // `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + CustomTags map[string]string + // Automatically terminates the extra instances in the pool cache after they are + // inactive for this time in minutes if min_idle_instances requirement is + // already met. If not set, the extra pool instances will be automatically + // terminated after a default timeout. If specified, the threshold must be + // between 0 and 10000 minutes. Users can also set this value to 0 to instantly + // remove idle instances from the cache if min cache size could still hold. + IdleInstanceAutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this instances in this pool will + // dynamically acquire additional disk space when its Spark workers are running + // low on disk space. In AWS, this feature requires specific AWS permissions to + // function correctly - refer to the User Guide for more details. + EnableElasticDisk *bool + // Defines the specification of the disks that will be attached to all spark + // containers. + DiskSpec *DiskSpec + // Custom Docker Image BYOC + PreloadedDockerImages []DockerImage + // A list containing at most one preloaded Spark image version for the pool. + // Pool-backed clusters started with the preloaded Spark version will start + // faster. A list of available Spark versions can be retrieved by using the + // [clusters/sparkVersions] API call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + PreloadedSparkVersions []string + // Attributes related to instance pools running on Azure. If not specified at + // pool creation, a set of default values will be used. + AzureAttributes *InstancePoolAzureAttributes + // Attributes related to instance pools running on Google Cloud Platform. If not + // specified at pool creation, a set of default values will be used. + GcpAttributes *InstancePoolGcpAttributes + // Flexible node type configuration for the pool. + NodeTypeFlexibility *NodeTypeFlexibility + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED types. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED types. + TotalInitialRemoteDiskSize *int +} + +type CreateInstancePoolResponse struct { + // The ID of the created instance pool. + InstancePoolId *string +} + +type DeleteInstancePoolRequest struct { + // The instance pool to be terminated. + InstancePoolId *string +} + +type DeleteInstancePoolResponse struct { +} + +// Describes the disks that are launched for each instance in the spark cluster. +// For example, if the cluster has 3 instances, each instance is configured to +// launch 2 disks, 100 GiB each, then will launch a total of 6 +// disks, 100 GiB each, for this cluster.. +type DiskSpec struct { + // The type of disks that will be launched with this cluster. + DiskType *DiskType + // The number of disks launched for each instance: - This feature is only + // enabled for supported node types. - Users can choose up to the limit of the + // disks supported by the node type. - For node types with no OS disk, at least + // one disk must be specified; otherwise, cluster creation will fail. + // + // If disks are attached, will configure Spark to use only the + // disks for scratch storage, because heterogenously sized scratch devices can + // lead to inefficient disk utilization. If no disks are attached, + // will configure Spark to use instance store disks. + // + // Note: If disks are specified, then the Spark configuration `spark.local.dir` + // will be overridden. + // + // Disks will be mounted at: - For AWS: `/ebs0`, `/ebs1`, and etc. - For Azure: + // `/remote_volume0`, `/remote_volume1`, and etc. + DiskCount *int + // The size of each disk (in GiB) launched for each instance. Values must fall + // into the supported range for a particular instance type. + // + // For AWS: - General Purpose SSD: 100 - 4096 GiB - Throughput Optimized HDD: + // 500 - 4096 GiB + // + // For Azure: - Premium LRS (SSD): 1 - 1023 GiB - Standard LRS (HDD): 1- 1023 + // GiB + DiskSize *int + DiskIops *int + DiskThroughput *int +} + +// Describes the disk type.. +type DiskType struct { + RemoteVolumeType isDiskType_RemoteVolumeType +} + +type isDiskType_RemoteVolumeType interface { + isDiskType_RemoteVolumeType() +} + +// DiskType_RemoteVolumeType_EbsVolumeType selects EbsVolumeType for DiskType.RemoteVolumeType. +type DiskType_RemoteVolumeType_EbsVolumeType struct { + EbsVolumeType EbsVolumeType +} + +func (*DiskType_RemoteVolumeType_EbsVolumeType) isDiskType_RemoteVolumeType() {} + +// DiskType_RemoteVolumeType_AzureDiskVolumeType selects AzureDiskVolumeType for DiskType.RemoteVolumeType. +type DiskType_RemoteVolumeType_AzureDiskVolumeType struct { + AzureDiskVolumeType AzureDiskVolumeType +} + +func (*DiskType_RemoteVolumeType_AzureDiskVolumeType) isDiskType_RemoteVolumeType() {} + +type DockerBasicAuth struct { + // Name of the user + Username *string + // Password of the user + Password *string +} + +type DockerImage struct { + // URL of the docker image. + Url *string + CredsOneof isDockerImage_CredsOneof +} + +type isDockerImage_CredsOneof interface { + isDockerImage_CredsOneof() +} + +// DockerImage_CredsOneof_BasicAuth selects BasicAuth for DockerImage.CredsOneof. +// Basic auth with username and password +type DockerImage_CredsOneof_BasicAuth struct { + BasicAuth DockerBasicAuth +} + +func (*DockerImage_CredsOneof_BasicAuth) isDockerImage_CredsOneof() {} + +type EditInstancePoolRequest struct { + // Instance pool ID + InstancePoolId *string + // Pool name requested by the user. Pool name must be unique. Length must be + // between 1 and 100 characters. + InstancePoolName *string + // Minimum number of idle instances to keep in the instance pool + MinIdleInstances *int + // Maximum number of outstanding instances to keep in the pool, including both + // instances used by clusters and idle instances. Clusters that require further + // instance provisioning will fail during upsize requests. + MaxCapacity *int + // Attributes related to instance pools running on Amazon Web Services. If not + // specified at pool creation, a set of default values will be used. + AwsAttributes *InstancePoolAwsAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // Additional tags for pool resources. will tag all pool resources + // (e.g., AWS instances and EBS volumes) with these tags in addition to + // `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + CustomTags map[string]string + // Automatically terminates the extra instances in the pool cache after they are + // inactive for this time in minutes if min_idle_instances requirement is + // already met. If not set, the extra pool instances will be automatically + // terminated after a default timeout. If specified, the threshold must be + // between 0 and 10000 minutes. Users can also set this value to 0 to instantly + // remove idle instances from the cache if min cache size could still hold. + IdleInstanceAutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this instances in this pool will + // dynamically acquire additional disk space when its Spark workers are running + // low on disk space. In AWS, this feature requires specific AWS permissions to + // function correctly - refer to the User Guide for more details. + EnableElasticDisk *bool + // Defines the specification of the disks that will be attached to all spark + // containers. + DiskSpec *DiskSpec + // Custom Docker Image BYOC + PreloadedDockerImages []DockerImage + // A list containing at most one preloaded Spark image version for the pool. + // Pool-backed clusters started with the preloaded Spark version will start + // faster. A list of available Spark versions can be retrieved by using the + // [clusters/sparkVersions] API call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + PreloadedSparkVersions []string + // Attributes related to instance pools running on Azure. If not specified at + // pool creation, a set of default values will be used. + AzureAttributes *InstancePoolAzureAttributes + // Attributes related to instance pools running on Google Cloud Platform. If not + // specified at pool creation, a set of default values will be used. + GcpAttributes *InstancePoolGcpAttributes + // Flexible node type configuration for the pool. + NodeTypeFlexibility *NodeTypeFlexibility + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED types. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED types. + TotalInitialRemoteDiskSize *int +} + +type EditInstancePoolResponse struct { +} + +type GetInstancePoolRequest struct { + // The canonical unique identifier for the instance pool. + InstancePoolId *string +} + +type GetInstancePoolResponse struct { + // Usage statistics about the instance pool. + Stats *InstancePoolStats + // Status of failed pending instances in the pool. + Status *InstancePoolStatus + // Canonical unique identifier for the pool. + InstancePoolId *string + // Tags that are added by regardless of any ``custom_tags``, + // including: + // + // - Vendor: + // + // - InstancePoolCreator: + // + // - InstancePoolName: + // + // - InstancePoolId: + DefaultTags map[string]string + // Current state of the instance pool. + State InstancePoolState + // Pool name requested by the user. Pool name must be unique. Length must be + // between 1 and 100 characters. + InstancePoolName *string + // Minimum number of idle instances to keep in the instance pool + MinIdleInstances *int + // Maximum number of outstanding instances to keep in the pool, including both + // instances used by clusters and idle instances. Clusters that require further + // instance provisioning will fail during upsize requests. + MaxCapacity *int + // Attributes related to instance pools running on Amazon Web Services. If not + // specified at pool creation, a set of default values will be used. + AwsAttributes *InstancePoolAwsAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // Additional tags for pool resources. will tag all pool resources + // (e.g., AWS instances and EBS volumes) with these tags in addition to + // `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + CustomTags map[string]string + // Automatically terminates the extra instances in the pool cache after they are + // inactive for this time in minutes if min_idle_instances requirement is + // already met. If not set, the extra pool instances will be automatically + // terminated after a default timeout. If specified, the threshold must be + // between 0 and 10000 minutes. Users can also set this value to 0 to instantly + // remove idle instances from the cache if min cache size could still hold. + IdleInstanceAutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this instances in this pool will + // dynamically acquire additional disk space when its Spark workers are running + // low on disk space. In AWS, this feature requires specific AWS permissions to + // function correctly - refer to the User Guide for more details. + EnableElasticDisk *bool + // Defines the specification of the disks that will be attached to all spark + // containers. + DiskSpec *DiskSpec + // Custom Docker Image BYOC + PreloadedDockerImages []DockerImage + // A list containing at most one preloaded Spark image version for the pool. + // Pool-backed clusters started with the preloaded Spark version will start + // faster. A list of available Spark versions can be retrieved by using the + // [clusters/sparkVersions] API call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + PreloadedSparkVersions []string + // Attributes related to instance pools running on Azure. If not specified at + // pool creation, a set of default values will be used. + AzureAttributes *InstancePoolAzureAttributes + // Attributes related to instance pools running on Google Cloud Platform. If not + // specified at pool creation, a set of default values will be used. + GcpAttributes *InstancePoolGcpAttributes + // Flexible node type configuration for the pool. + NodeTypeFlexibility *NodeTypeFlexibility + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED types. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED types. + TotalInitialRemoteDiskSize *int +} + +type InstancePoolAndStats struct { + // Usage statistics about the instance pool. + Stats *InstancePoolStats + // Status of failed pending instances in the pool. + Status *InstancePoolStatus + // Canonical unique identifier for the pool. + InstancePoolId *string + // Tags that are added by regardless of any ``custom_tags``, + // including: + // + // - Vendor: + // + // - InstancePoolCreator: + // + // - InstancePoolName: + // + // - InstancePoolId: + DefaultTags map[string]string + // Current state of the instance pool. + State InstancePoolState + // Pool name requested by the user. Pool name must be unique. Length must be + // between 1 and 100 characters. + InstancePoolName *string + // Minimum number of idle instances to keep in the instance pool + MinIdleInstances *int + // Maximum number of outstanding instances to keep in the pool, including both + // instances used by clusters and idle instances. Clusters that require further + // instance provisioning will fail during upsize requests. + MaxCapacity *int + // Attributes related to instance pools running on Amazon Web Services. If not + // specified at pool creation, a set of default values will be used. + AwsAttributes *InstancePoolAwsAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // Additional tags for pool resources. will tag all pool resources + // (e.g., AWS instances and EBS volumes) with these tags in addition to + // `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + CustomTags map[string]string + // Automatically terminates the extra instances in the pool cache after they are + // inactive for this time in minutes if min_idle_instances requirement is + // already met. If not set, the extra pool instances will be automatically + // terminated after a default timeout. If specified, the threshold must be + // between 0 and 10000 minutes. Users can also set this value to 0 to instantly + // remove idle instances from the cache if min cache size could still hold. + IdleInstanceAutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this instances in this pool will + // dynamically acquire additional disk space when its Spark workers are running + // low on disk space. In AWS, this feature requires specific AWS permissions to + // function correctly - refer to the User Guide for more details. + EnableElasticDisk *bool + // Defines the specification of the disks that will be attached to all spark + // containers. + DiskSpec *DiskSpec + // Custom Docker Image BYOC + PreloadedDockerImages []DockerImage + // A list containing at most one preloaded Spark image version for the pool. + // Pool-backed clusters started with the preloaded Spark version will start + // faster. A list of available Spark versions can be retrieved by using the + // [clusters/sparkVersions] API call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + PreloadedSparkVersions []string + // Attributes related to instance pools running on Azure. If not specified at + // pool creation, a set of default values will be used. + AzureAttributes *InstancePoolAzureAttributes + // Attributes related to instance pools running on Google Cloud Platform. If not + // specified at pool creation, a set of default values will be used. + GcpAttributes *InstancePoolGcpAttributes + // Flexible node type configuration for the pool. + NodeTypeFlexibility *NodeTypeFlexibility + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED types. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED types. + TotalInitialRemoteDiskSize *int +} + +// Attributes set during instance pool creation which are related to Amazon Web +// Services.. +type InstancePoolAwsAttributes struct { + // Availability type used for the spot nodes. + Availability AwsAvailability + // Identifier for the availability zone/datacenter in which the cluster resides. + // This string will be of a form like "us-west-2a". The provided availability + // zone must be in the same region as the deployment. For example, + // "us-west-2a" is not a valid zone id if the deployment resides in + // the "us-east-1" region. This is an optional field at cluster creation, and if + // not specified, a default zone will be used. The list of available zones as + // well as the default value can be found by using the `List Zones` method. + ZoneId *string + // Calculates the bid price for AWS spot instances, as a percentage of the + // corresponding instance type's on-demand price. For example, if this field is + // set to 50, and the cluster needs a new `r3.xlarge` spot instance, then the + // bid price is half of the price of on-demand `r3.xlarge` instances. Similarly, + // if this field is set to 200, the bid price is twice the price of on-demand + // `r3.xlarge` instances. If not specified, the default value is 100. When spot + // instances are requested for this cluster, only spot instances whose bid price + // percentage matches this field will be considered. Note that, for safety, we + // enforce this field to be no more than 10000. + SpotBidPricePercent *int + // All AWS instances belonging to the instance pool will have this instance + // profile. If omitted, instances will initially be launched with the + // workspace's default instance profile. If defined, clusters that use the pool + // will inherit the instance profile, and must not specify their own instance + // profile on cluster creation or update. If the pool does not specify an + // instance profile, clusters using the pool may specify any instance profile. + // The instance profile must have previously been added to the + // environment by an account administrator. + // + // This feature may only be available to certain customer plans. + InstanceProfileArn *string +} + +// Attributes set during instance pool creation which are related to Azure.. +type InstancePoolAzureAttributes struct { + // Availability type used for the spot nodes. + Availability AzureAvailability + // With variable pricing, you have option to set a max price, in US dollars + // (USD) For example, the value 2 would be a max price of $2.00 USD per hour. If + // you set the max price to be -1, the VM won't be evicted based on price. The + // price for the VM will be the current price for spot or the price for a + // standard VM, which ever is less, as long as there is capacity and quota + // available. + SpotBidMaxPrice *float64 + // The Azure capacity reservation group resource ID to use for launching VMs in + // this pool. When specified, VMs will be launched using the provided capacity + // reservation. + // + // NOTE: Omitting this field will clear any existing configured capacity + // reservation group on the pool. + // + // Capacity reservations can only be specified when the workspace uses injected + // vnet (i.e. customer defined vnet not managed by databricks). Ensure the + // databricks-login-prod Enterprise Application is granted the following four + // permissions: 1. Microsoft.Compute/capacityReservationGroups/read 2. + // Microsoft.Compute/capacityReservationGroups/deploy/action 3. + // Microsoft.Compute/capacityReservationGroups/capacityReservations/read 4. + // Microsoft.Compute/capacityReservationGroups/capacityReservations/deploy/action + // + // Format: + // `/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/capacityReservationGroups/{capacityReservationGroupName}` + CapacityReservationGroup *string +} + +// Attributes set during instance pool creation which are related to GCP.. +type InstancePoolGcpAttributes struct { + GcpAvailability GcpAvailability + // If provided, each node in the instance pool will have this number of local + // SSDs attached. Each local SSD is 375GB in size. Refer to [GCP documentation] + // for the supported number of local SSDs for each instance type. + // + // [GCP documentation]: https://cloud.google.com/compute/docs/disks/local-ssd#choose_number_local_ssds + LocalSsdCount *int + // Identifier for the availability zone/datacenter in which the cluster resides. + // This string will be of a form like "us-west1-a". The provided availability + // zone must be in the same region as the workspace. For example, + // "us-west1-a" is not a valid zone id if the workspace resides in + // the "us-east1" region. This is an optional field at instance pool creation, + // and if not specified, a default zone will be used. + // + // This field can be one of the following: - "HA" => High availability, spread + // nodes across availability zones for a deployment region - A GCP + // availability zone => Pick One of the available zones for (machine type + + // region) from https://cloud.google.com/compute/docs/regions-zones (e.g. + // "us-west1-a"). + // + // If empty, picks an availability zone to schedule the cluster on. + ZoneId *string +} + +type InstancePoolStats struct { + // Number of active instances in the pool that are part of a cluster. + UsedCount *int + // Number of active instances in the pool that are NOT part of a cluster. + IdleCount *int + // Number of pending instances in the pool that are part of a cluster. + PendingUsedCount *int + // Number of pending instances in the pool that are NOT part of a cluster. + PendingIdleCount *int +} + +type InstancePoolStatus struct { + // List of error messages for the failed pending instances. The + // pending_instance_errors follows FIFO with maximum length of the min_idle of + // the pool. The pending_instance_errors is emptied once the number of exiting + // available instances reaches the min_idle of the pool. + PendingInstanceErrors []PendingInstanceError +} + +type ListInstancePoolsRequest struct { +} + +type ListInstancePoolsResponse struct { + InstancePools []InstancePoolAndStats +} + +// Configuration for flexible node types, allowing fallback to alternate node +// types during cluster launch and upscale.. +type NodeTypeFlexibility struct { + // A list of node type IDs to use as fallbacks when the primary node type is + // unavailable. + AlternateNodeTypeIds []string +} + +// Error message of a failed pending instances. +type PendingInstanceError struct { + InstanceId *string + Message *string +} diff --git a/instancepools/v2/wire.go b/instancepools/v2/wire.go new file mode 100755 index 0000000..c26f466 --- /dev/null +++ b/instancepools/v2/wire.go @@ -0,0 +1,722 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package instancepools + +import ( + "fmt" +) + +type createInstancePoolRequestWire struct { + InstancePoolName *string `json:"instance_pool_name,omitempty"` + MinIdleInstances *int `json:"min_idle_instances,omitempty"` + MaxCapacity *int `json:"max_capacity,omitempty"` + AwsAttributes *instancePoolAwsAttributesWire `json:"aws_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + IdleInstanceAutoterminationMinutes *int `json:"idle_instance_autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + DiskSpec *diskSpecWire `json:"disk_spec,omitempty"` + PreloadedDockerImages []dockerImageWire `json:"preloaded_docker_images,omitempty"` + PreloadedSparkVersions []string `json:"preloaded_spark_versions,omitempty"` + AzureAttributes *instancePoolAzureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *instancePoolGcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeFlexibility *nodeTypeFlexibilityWire `json:"node_type_flexibility,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` +} + +func createInstancePoolRequestToWire(v *CreateInstancePoolRequest) (*createInstancePoolRequestWire, error) { + if v == nil { + return nil, nil + } + awsAttributesWireValue, err := instancePoolAwsAttributesToWire(v.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInstancePoolRequest.AwsAttributes", err) + } + diskSpecWireValue, err := diskSpecToWire(v.DiskSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInstancePoolRequest.DiskSpec", err) + } + preloadedDockerImagesWireValue, err := convertSlice(v.PreloadedDockerImages, dockerImageToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInstancePoolRequest.PreloadedDockerImages", err) + } + azureAttributesWireValue, err := instancePoolAzureAttributesToWire(v.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInstancePoolRequest.AzureAttributes", err) + } + gcpAttributesWireValue, err := instancePoolGcpAttributesToWire(v.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInstancePoolRequest.GcpAttributes", err) + } + nodeTypeFlexibilityWireValue, err := nodeTypeFlexibilityToWire(v.NodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInstancePoolRequest.NodeTypeFlexibility", err) + } + return &createInstancePoolRequestWire{ + InstancePoolName: v.InstancePoolName, + MinIdleInstances: v.MinIdleInstances, + MaxCapacity: v.MaxCapacity, + AwsAttributes: awsAttributesWireValue, + NodeTypeId: v.NodeTypeId, + CustomTags: v.CustomTags, + IdleInstanceAutoterminationMinutes: v.IdleInstanceAutoterminationMinutes, + EnableElasticDisk: v.EnableElasticDisk, + DiskSpec: diskSpecWireValue, + PreloadedDockerImages: preloadedDockerImagesWireValue, + PreloadedSparkVersions: v.PreloadedSparkVersions, + AzureAttributes: azureAttributesWireValue, + GcpAttributes: gcpAttributesWireValue, + NodeTypeFlexibility: nodeTypeFlexibilityWireValue, + RemoteDiskThroughput: v.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: v.TotalInitialRemoteDiskSize, + }, nil +} + +type createInstancePoolResponseWire struct { + InstancePoolId *string `json:"instance_pool_id,omitempty"` +} + +func createInstancePoolResponseFromWire(w *createInstancePoolResponseWire) (*CreateInstancePoolResponse, error) { + if w == nil { + return nil, nil + } + return &CreateInstancePoolResponse{ + InstancePoolId: w.InstancePoolId, + }, nil +} + +type deleteInstancePoolRequestWire struct { + InstancePoolId *string `json:"instance_pool_id,omitempty"` +} + +func deleteInstancePoolRequestToWire(v *DeleteInstancePoolRequest) (*deleteInstancePoolRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteInstancePoolRequestWire{ + InstancePoolId: v.InstancePoolId, + }, nil +} + +type diskSpecWire struct { + DiskType *diskTypeWire `json:"disk_type,omitempty"` + DiskCount *int `json:"disk_count,omitempty"` + DiskSize *int `json:"disk_size,omitempty"` + DiskIops *int `json:"disk_iops,omitempty"` + DiskThroughput *int `json:"disk_throughput,omitempty"` +} + +func diskSpecToWire(v *DiskSpec) (*diskSpecWire, error) { + if v == nil { + return nil, nil + } + diskTypeWireValue, err := diskTypeToWire(v.DiskType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DiskSpec.DiskType", err) + } + return &diskSpecWire{ + DiskType: diskTypeWireValue, + DiskCount: v.DiskCount, + DiskSize: v.DiskSize, + DiskIops: v.DiskIops, + DiskThroughput: v.DiskThroughput, + }, nil +} + +func diskSpecFromWire(w *diskSpecWire) (*DiskSpec, error) { + if w == nil { + return nil, nil + } + diskTypePublicValue, err := diskTypeFromWire(w.DiskType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DiskSpec.DiskType", err) + } + return &DiskSpec{ + DiskType: diskTypePublicValue, + DiskCount: w.DiskCount, + DiskSize: w.DiskSize, + DiskIops: w.DiskIops, + DiskThroughput: w.DiskThroughput, + }, nil +} + +type diskTypeWire struct { + EbsVolumeType EbsVolumeType `json:"ebs_volume_type,omitempty"` + AzureDiskVolumeType AzureDiskVolumeType `json:"azure_disk_volume_type,omitempty"` +} + +func diskTypeToWire(v *DiskType) (*diskTypeWire, error) { + if v == nil { + return nil, nil + } + var remoteVolumeTypeEbsVolumeTypeWire EbsVolumeType + var remoteVolumeTypeAzureDiskVolumeTypeWire AzureDiskVolumeType + switch value := v.RemoteVolumeType.(type) { + case nil: + case *DiskType_RemoteVolumeType_EbsVolumeType: + if value != nil { + remoteVolumeTypeEbsVolumeTypeWire = value.EbsVolumeType + } + case *DiskType_RemoteVolumeType_AzureDiskVolumeType: + if value != nil { + remoteVolumeTypeAzureDiskVolumeTypeWire = value.AzureDiskVolumeType + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "DiskType.RemoteVolumeType", value) + } + return &diskTypeWire{ + EbsVolumeType: remoteVolumeTypeEbsVolumeTypeWire, + AzureDiskVolumeType: remoteVolumeTypeAzureDiskVolumeTypeWire, + }, nil +} + +func diskTypeFromWire(w *diskTypeWire) (*DiskType, error) { + if w == nil { + return nil, nil + } + remoteVolumeTypeMembers := 0 + if w.EbsVolumeType != "" { + remoteVolumeTypeMembers++ + } + if w.AzureDiskVolumeType != "" { + remoteVolumeTypeMembers++ + } + if remoteVolumeTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "DiskType.RemoteVolumeType") + } + var remoteVolumeTypeSelection isDiskType_RemoteVolumeType + switch { + case w.EbsVolumeType != "": + remoteVolumeTypeSelection = &DiskType_RemoteVolumeType_EbsVolumeType{EbsVolumeType: w.EbsVolumeType} + case w.AzureDiskVolumeType != "": + remoteVolumeTypeSelection = &DiskType_RemoteVolumeType_AzureDiskVolumeType{AzureDiskVolumeType: w.AzureDiskVolumeType} + } + return &DiskType{ + RemoteVolumeType: remoteVolumeTypeSelection, + }, nil +} + +type dockerBasicAuthWire struct { + Username *string `json:"username,omitempty"` + Password *string `json:"password,omitempty"` +} + +func dockerBasicAuthToWire(v *DockerBasicAuth) (*dockerBasicAuthWire, error) { + if v == nil { + return nil, nil + } + return &dockerBasicAuthWire{ + Username: v.Username, + Password: v.Password, + }, nil +} + +func dockerBasicAuthFromWire(w *dockerBasicAuthWire) (*DockerBasicAuth, error) { + if w == nil { + return nil, nil + } + return &DockerBasicAuth{ + Username: w.Username, + Password: w.Password, + }, nil +} + +type dockerImageWire struct { + Url *string `json:"url,omitempty"` + BasicAuth *dockerBasicAuthWire `json:"basic_auth,omitempty"` +} + +func dockerImageToWire(v *DockerImage) (*dockerImageWire, error) { + if v == nil { + return nil, nil + } + var credsOneofBasicAuthWire *dockerBasicAuthWire + switch value := v.CredsOneof.(type) { + case nil: + case *DockerImage_CredsOneof_BasicAuth: + if value != nil { + credsOneofBasicAuthConverted, err := dockerBasicAuthToWire(&value.BasicAuth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DockerImage.CredsOneof.BasicAuth", err) + } + credsOneofBasicAuthWire = credsOneofBasicAuthConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "DockerImage.CredsOneof", value) + } + return &dockerImageWire{ + Url: v.Url, + BasicAuth: credsOneofBasicAuthWire, + }, nil +} + +func dockerImageFromWire(w *dockerImageWire) (*DockerImage, error) { + if w == nil { + return nil, nil + } + credsOneofMembers := 0 + if w.BasicAuth != nil { + credsOneofMembers++ + } + if credsOneofMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "DockerImage.CredsOneof") + } + var credsOneofSelection isDockerImage_CredsOneof + switch { + case w.BasicAuth != nil: + credsOneofBasicAuthConverted, err := dockerBasicAuthFromWire(w.BasicAuth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DockerImage.CredsOneof.BasicAuth", err) + } + credsOneofSelection = &DockerImage_CredsOneof_BasicAuth{BasicAuth: *credsOneofBasicAuthConverted} + } + return &DockerImage{ + Url: w.Url, + CredsOneof: credsOneofSelection, + }, nil +} + +type editInstancePoolRequestWire struct { + InstancePoolId *string `json:"instance_pool_id,omitempty"` + InstancePoolName *string `json:"instance_pool_name,omitempty"` + MinIdleInstances *int `json:"min_idle_instances,omitempty"` + MaxCapacity *int `json:"max_capacity,omitempty"` + AwsAttributes *instancePoolAwsAttributesWire `json:"aws_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + IdleInstanceAutoterminationMinutes *int `json:"idle_instance_autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + DiskSpec *diskSpecWire `json:"disk_spec,omitempty"` + PreloadedDockerImages []dockerImageWire `json:"preloaded_docker_images,omitempty"` + PreloadedSparkVersions []string `json:"preloaded_spark_versions,omitempty"` + AzureAttributes *instancePoolAzureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *instancePoolGcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeFlexibility *nodeTypeFlexibilityWire `json:"node_type_flexibility,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` +} + +func editInstancePoolRequestToWire(v *EditInstancePoolRequest) (*editInstancePoolRequestWire, error) { + if v == nil { + return nil, nil + } + awsAttributesWireValue, err := instancePoolAwsAttributesToWire(v.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditInstancePoolRequest.AwsAttributes", err) + } + diskSpecWireValue, err := diskSpecToWire(v.DiskSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditInstancePoolRequest.DiskSpec", err) + } + preloadedDockerImagesWireValue, err := convertSlice(v.PreloadedDockerImages, dockerImageToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditInstancePoolRequest.PreloadedDockerImages", err) + } + azureAttributesWireValue, err := instancePoolAzureAttributesToWire(v.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditInstancePoolRequest.AzureAttributes", err) + } + gcpAttributesWireValue, err := instancePoolGcpAttributesToWire(v.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditInstancePoolRequest.GcpAttributes", err) + } + nodeTypeFlexibilityWireValue, err := nodeTypeFlexibilityToWire(v.NodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditInstancePoolRequest.NodeTypeFlexibility", err) + } + return &editInstancePoolRequestWire{ + InstancePoolId: v.InstancePoolId, + InstancePoolName: v.InstancePoolName, + MinIdleInstances: v.MinIdleInstances, + MaxCapacity: v.MaxCapacity, + AwsAttributes: awsAttributesWireValue, + NodeTypeId: v.NodeTypeId, + CustomTags: v.CustomTags, + IdleInstanceAutoterminationMinutes: v.IdleInstanceAutoterminationMinutes, + EnableElasticDisk: v.EnableElasticDisk, + DiskSpec: diskSpecWireValue, + PreloadedDockerImages: preloadedDockerImagesWireValue, + PreloadedSparkVersions: v.PreloadedSparkVersions, + AzureAttributes: azureAttributesWireValue, + GcpAttributes: gcpAttributesWireValue, + NodeTypeFlexibility: nodeTypeFlexibilityWireValue, + RemoteDiskThroughput: v.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: v.TotalInitialRemoteDiskSize, + }, nil +} + +type getInstancePoolRequestWire struct { + InstancePoolId *string `json:"instance_pool_id,omitempty"` +} + +func getInstancePoolRequestToWire(v *GetInstancePoolRequest) (*getInstancePoolRequestWire, error) { + if v == nil { + return nil, nil + } + return &getInstancePoolRequestWire{ + InstancePoolId: v.InstancePoolId, + }, nil +} + +type getInstancePoolResponseWire struct { + Stats *instancePoolStatsWire `json:"stats,omitempty"` + Status *instancePoolStatusWire `json:"status,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + DefaultTags map[string]string `json:"default_tags,omitempty"` + State InstancePoolState `json:"state,omitempty"` + InstancePoolName *string `json:"instance_pool_name,omitempty"` + MinIdleInstances *int `json:"min_idle_instances,omitempty"` + MaxCapacity *int `json:"max_capacity,omitempty"` + AwsAttributes *instancePoolAwsAttributesWire `json:"aws_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + IdleInstanceAutoterminationMinutes *int `json:"idle_instance_autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + DiskSpec *diskSpecWire `json:"disk_spec,omitempty"` + PreloadedDockerImages []dockerImageWire `json:"preloaded_docker_images,omitempty"` + PreloadedSparkVersions []string `json:"preloaded_spark_versions,omitempty"` + AzureAttributes *instancePoolAzureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *instancePoolGcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeFlexibility *nodeTypeFlexibilityWire `json:"node_type_flexibility,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` +} + +func getInstancePoolResponseFromWire(w *getInstancePoolResponseWire) (*GetInstancePoolResponse, error) { + if w == nil { + return nil, nil + } + statsPublicValue, err := instancePoolStatsFromWire(w.Stats) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetInstancePoolResponse.Stats", err) + } + statusPublicValue, err := instancePoolStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetInstancePoolResponse.Status", err) + } + awsAttributesPublicValue, err := instancePoolAwsAttributesFromWire(w.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetInstancePoolResponse.AwsAttributes", err) + } + diskSpecPublicValue, err := diskSpecFromWire(w.DiskSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetInstancePoolResponse.DiskSpec", err) + } + preloadedDockerImagesPublicValue, err := convertSlice(w.PreloadedDockerImages, dockerImageFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetInstancePoolResponse.PreloadedDockerImages", err) + } + azureAttributesPublicValue, err := instancePoolAzureAttributesFromWire(w.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetInstancePoolResponse.AzureAttributes", err) + } + gcpAttributesPublicValue, err := instancePoolGcpAttributesFromWire(w.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetInstancePoolResponse.GcpAttributes", err) + } + nodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.NodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetInstancePoolResponse.NodeTypeFlexibility", err) + } + return &GetInstancePoolResponse{ + Stats: statsPublicValue, + Status: statusPublicValue, + InstancePoolId: w.InstancePoolId, + DefaultTags: w.DefaultTags, + State: w.State, + InstancePoolName: w.InstancePoolName, + MinIdleInstances: w.MinIdleInstances, + MaxCapacity: w.MaxCapacity, + AwsAttributes: awsAttributesPublicValue, + NodeTypeId: w.NodeTypeId, + CustomTags: w.CustomTags, + IdleInstanceAutoterminationMinutes: w.IdleInstanceAutoterminationMinutes, + EnableElasticDisk: w.EnableElasticDisk, + DiskSpec: diskSpecPublicValue, + PreloadedDockerImages: preloadedDockerImagesPublicValue, + PreloadedSparkVersions: w.PreloadedSparkVersions, + AzureAttributes: azureAttributesPublicValue, + GcpAttributes: gcpAttributesPublicValue, + NodeTypeFlexibility: nodeTypeFlexibilityPublicValue, + RemoteDiskThroughput: w.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: w.TotalInitialRemoteDiskSize, + }, nil +} + +type instancePoolAndStatsWire struct { + Stats *instancePoolStatsWire `json:"stats,omitempty"` + Status *instancePoolStatusWire `json:"status,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + DefaultTags map[string]string `json:"default_tags,omitempty"` + State InstancePoolState `json:"state,omitempty"` + InstancePoolName *string `json:"instance_pool_name,omitempty"` + MinIdleInstances *int `json:"min_idle_instances,omitempty"` + MaxCapacity *int `json:"max_capacity,omitempty"` + AwsAttributes *instancePoolAwsAttributesWire `json:"aws_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + IdleInstanceAutoterminationMinutes *int `json:"idle_instance_autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + DiskSpec *diskSpecWire `json:"disk_spec,omitempty"` + PreloadedDockerImages []dockerImageWire `json:"preloaded_docker_images,omitempty"` + PreloadedSparkVersions []string `json:"preloaded_spark_versions,omitempty"` + AzureAttributes *instancePoolAzureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *instancePoolGcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeFlexibility *nodeTypeFlexibilityWire `json:"node_type_flexibility,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` +} + +func instancePoolAndStatsFromWire(w *instancePoolAndStatsWire) (*InstancePoolAndStats, error) { + if w == nil { + return nil, nil + } + statsPublicValue, err := instancePoolStatsFromWire(w.Stats) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstancePoolAndStats.Stats", err) + } + statusPublicValue, err := instancePoolStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstancePoolAndStats.Status", err) + } + awsAttributesPublicValue, err := instancePoolAwsAttributesFromWire(w.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstancePoolAndStats.AwsAttributes", err) + } + diskSpecPublicValue, err := diskSpecFromWire(w.DiskSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstancePoolAndStats.DiskSpec", err) + } + preloadedDockerImagesPublicValue, err := convertSlice(w.PreloadedDockerImages, dockerImageFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstancePoolAndStats.PreloadedDockerImages", err) + } + azureAttributesPublicValue, err := instancePoolAzureAttributesFromWire(w.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstancePoolAndStats.AzureAttributes", err) + } + gcpAttributesPublicValue, err := instancePoolGcpAttributesFromWire(w.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstancePoolAndStats.GcpAttributes", err) + } + nodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.NodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstancePoolAndStats.NodeTypeFlexibility", err) + } + return &InstancePoolAndStats{ + Stats: statsPublicValue, + Status: statusPublicValue, + InstancePoolId: w.InstancePoolId, + DefaultTags: w.DefaultTags, + State: w.State, + InstancePoolName: w.InstancePoolName, + MinIdleInstances: w.MinIdleInstances, + MaxCapacity: w.MaxCapacity, + AwsAttributes: awsAttributesPublicValue, + NodeTypeId: w.NodeTypeId, + CustomTags: w.CustomTags, + IdleInstanceAutoterminationMinutes: w.IdleInstanceAutoterminationMinutes, + EnableElasticDisk: w.EnableElasticDisk, + DiskSpec: diskSpecPublicValue, + PreloadedDockerImages: preloadedDockerImagesPublicValue, + PreloadedSparkVersions: w.PreloadedSparkVersions, + AzureAttributes: azureAttributesPublicValue, + GcpAttributes: gcpAttributesPublicValue, + NodeTypeFlexibility: nodeTypeFlexibilityPublicValue, + RemoteDiskThroughput: w.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: w.TotalInitialRemoteDiskSize, + }, nil +} + +type instancePoolAwsAttributesWire struct { + Availability AwsAvailability `json:"availability,omitempty"` + ZoneId *string `json:"zone_id,omitempty"` + SpotBidPricePercent *int `json:"spot_bid_price_percent,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` +} + +func instancePoolAwsAttributesToWire(v *InstancePoolAwsAttributes) (*instancePoolAwsAttributesWire, error) { + if v == nil { + return nil, nil + } + return &instancePoolAwsAttributesWire{ + Availability: v.Availability, + ZoneId: v.ZoneId, + SpotBidPricePercent: v.SpotBidPricePercent, + InstanceProfileArn: v.InstanceProfileArn, + }, nil +} + +func instancePoolAwsAttributesFromWire(w *instancePoolAwsAttributesWire) (*InstancePoolAwsAttributes, error) { + if w == nil { + return nil, nil + } + return &InstancePoolAwsAttributes{ + Availability: w.Availability, + ZoneId: w.ZoneId, + SpotBidPricePercent: w.SpotBidPricePercent, + InstanceProfileArn: w.InstanceProfileArn, + }, nil +} + +type instancePoolAzureAttributesWire struct { + Availability AzureAvailability `json:"availability,omitempty"` + SpotBidMaxPrice *float64 `json:"spot_bid_max_price,omitempty"` + CapacityReservationGroup *string `json:"capacity_reservation_group,omitempty"` +} + +func instancePoolAzureAttributesToWire(v *InstancePoolAzureAttributes) (*instancePoolAzureAttributesWire, error) { + if v == nil { + return nil, nil + } + return &instancePoolAzureAttributesWire{ + Availability: v.Availability, + SpotBidMaxPrice: v.SpotBidMaxPrice, + CapacityReservationGroup: v.CapacityReservationGroup, + }, nil +} + +func instancePoolAzureAttributesFromWire(w *instancePoolAzureAttributesWire) (*InstancePoolAzureAttributes, error) { + if w == nil { + return nil, nil + } + return &InstancePoolAzureAttributes{ + Availability: w.Availability, + SpotBidMaxPrice: w.SpotBidMaxPrice, + CapacityReservationGroup: w.CapacityReservationGroup, + }, nil +} + +type instancePoolGcpAttributesWire struct { + GcpAvailability GcpAvailability `json:"gcp_availability,omitempty"` + LocalSsdCount *int `json:"local_ssd_count,omitempty"` + ZoneId *string `json:"zone_id,omitempty"` +} + +func instancePoolGcpAttributesToWire(v *InstancePoolGcpAttributes) (*instancePoolGcpAttributesWire, error) { + if v == nil { + return nil, nil + } + return &instancePoolGcpAttributesWire{ + GcpAvailability: v.GcpAvailability, + LocalSsdCount: v.LocalSsdCount, + ZoneId: v.ZoneId, + }, nil +} + +func instancePoolGcpAttributesFromWire(w *instancePoolGcpAttributesWire) (*InstancePoolGcpAttributes, error) { + if w == nil { + return nil, nil + } + return &InstancePoolGcpAttributes{ + GcpAvailability: w.GcpAvailability, + LocalSsdCount: w.LocalSsdCount, + ZoneId: w.ZoneId, + }, nil +} + +type instancePoolStatsWire struct { + UsedCount *int `json:"used_count,omitempty"` + IdleCount *int `json:"idle_count,omitempty"` + PendingUsedCount *int `json:"pending_used_count,omitempty"` + PendingIdleCount *int `json:"pending_idle_count,omitempty"` +} + +func instancePoolStatsFromWire(w *instancePoolStatsWire) (*InstancePoolStats, error) { + if w == nil { + return nil, nil + } + return &InstancePoolStats{ + UsedCount: w.UsedCount, + IdleCount: w.IdleCount, + PendingUsedCount: w.PendingUsedCount, + PendingIdleCount: w.PendingIdleCount, + }, nil +} + +type instancePoolStatusWire struct { + PendingInstanceErrors []pendingInstanceErrorWire `json:"pending_instance_errors,omitempty"` +} + +func instancePoolStatusFromWire(w *instancePoolStatusWire) (*InstancePoolStatus, error) { + if w == nil { + return nil, nil + } + pendingInstanceErrorsPublicValue, err := convertSlice(w.PendingInstanceErrors, pendingInstanceErrorFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstancePoolStatus.PendingInstanceErrors", err) + } + return &InstancePoolStatus{ + PendingInstanceErrors: pendingInstanceErrorsPublicValue, + }, nil +} + +type listInstancePoolsResponseWire struct { + InstancePools []instancePoolAndStatsWire `json:"instance_pools,omitempty"` +} + +func listInstancePoolsResponseFromWire(w *listInstancePoolsResponseWire) (*ListInstancePoolsResponse, error) { + if w == nil { + return nil, nil + } + instancePoolsPublicValue, err := convertSlice(w.InstancePools, instancePoolAndStatsFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListInstancePoolsResponse.InstancePools", err) + } + return &ListInstancePoolsResponse{ + InstancePools: instancePoolsPublicValue, + }, nil +} + +type nodeTypeFlexibilityWire struct { + AlternateNodeTypeIds []string `json:"alternate_node_type_ids,omitempty"` +} + +func nodeTypeFlexibilityToWire(v *NodeTypeFlexibility) (*nodeTypeFlexibilityWire, error) { + if v == nil { + return nil, nil + } + return &nodeTypeFlexibilityWire{ + AlternateNodeTypeIds: v.AlternateNodeTypeIds, + }, nil +} + +func nodeTypeFlexibilityFromWire(w *nodeTypeFlexibilityWire) (*NodeTypeFlexibility, error) { + if w == nil { + return nil, nil + } + return &NodeTypeFlexibility{ + AlternateNodeTypeIds: w.AlternateNodeTypeIds, + }, nil +} + +type pendingInstanceErrorWire struct { + InstanceId *string `json:"instance_id,omitempty"` + Message *string `json:"message,omitempty"` +} + +func pendingInstanceErrorFromWire(w *pendingInstanceErrorWire) (*PendingInstanceError, error) { + if w == nil { + return nil, nil + } + return &PendingInstanceError{ + InstanceId: w.InstanceId, + Message: w.Message, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/instanceprofiles/.package.json b/instanceprofiles/.package.json new file mode 100644 index 0000000..36ec21b --- /dev/null +++ b/instanceprofiles/.package.json @@ -0,0 +1,3 @@ +{ + "package": "instanceprofiles" +} diff --git a/instanceprofiles/CHANGELOG.md b/instanceprofiles/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/instanceprofiles/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/instanceprofiles/README.md b/instanceprofiles/README.md new file mode 100644 index 0000000..4d44dbd --- /dev/null +++ b/instanceprofiles/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/instanceprofiles + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/instanceprofiles@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/instanceprofiles/v2" + +client, err := instanceprofiles.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/instanceprofiles/go.mod b/instanceprofiles/go.mod new file mode 100644 index 0000000..7608779 --- /dev/null +++ b/instanceprofiles/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/instanceprofiles + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/instanceprofiles/internal/version.go b/instanceprofiles/internal/version.go new file mode 100644 index 0000000..e0da4ca --- /dev/null +++ b/instanceprofiles/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-instanceprofiles" + +const Version = "0.0.1-dev.1" diff --git a/instanceprofiles/v2/client.go b/instanceprofiles/v2/client.go new file mode 100755 index 0000000..08e4b3b --- /dev/null +++ b/instanceprofiles/v2/client.go @@ -0,0 +1,330 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package instanceprofiles + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/instanceprofiles/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Registers an instance profile in . In the UI, you can then give +// users the permission to use this instance profile when launching clusters. +// +// This API is only available to admin users. +func (c *internalClient) AddInstanceProfile(ctx context.Context, req *AddInstanceProfileRequest, opts ...call.Option) (*AddInstanceProfileResponse, error) { + wireReq, err := addInstanceProfileRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/instance-profiles/add" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AddInstanceProfileResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &AddInstanceProfileResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// The only supported field to change is the optional IAM role ARN associated +// with the instance profile. It is required to specify the IAM role ARN if both +// of the following are true: +// +// * Your role name and instance profile name do not match. The name is the part +// after the last slash in each ARN. * You want to use the instance profile with +// [Databricks SQL Serverless](/sql/admin/serverless.html). +// +// To understand where these fields are in the AWS console, see [Enable +// serverless SQL warehouses](/sql/admin/serverless.html). +// +// This API is only available to admin users. +func (c *internalClient) EditInstanceProfile(ctx context.Context, req *EditInstanceProfileRequest, opts ...call.Option) (*EditInstanceProfileResponse, error) { + wireReq, err := editInstanceProfileRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/instance-profiles/edit" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EditInstanceProfileResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &EditInstanceProfileResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List the instance profiles that the calling user can use to launch a cluster. +// +// This API is available to all users. +func (c *internalClient) ListInstanceProfiles(ctx context.Context, req *ListInstanceProfilesRequest, opts ...call.Option) (*ListInstanceProfilesResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/instance-profiles/list" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListInstanceProfilesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listInstanceProfilesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listInstanceProfilesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Remove the instance profile with the provided ARN. Existing clusters with +// this instance profile will continue to function. +// +// This API is only accessible to admin users. +func (c *internalClient) RemoveInstanceProfile(ctx context.Context, req *RemoveInstanceProfileRequest, opts ...call.Option) (*RemoveInstanceProfileResponse, error) { + wireReq, err := removeInstanceProfileRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/instance-profiles/remove" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RemoveInstanceProfileResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &RemoveInstanceProfileResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/instanceprofiles/v2/genhelper.go b/instanceprofiles/v2/genhelper.go new file mode 100755 index 0000000..929850a --- /dev/null +++ b/instanceprofiles/v2/genhelper.go @@ -0,0 +1,142 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package instanceprofiles + +import ( + "context" + "io" + "log/slog" + "net/http" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} diff --git a/instanceprofiles/v2/model.go b/instanceprofiles/v2/model.go new file mode 100755 index 0000000..30eda8e --- /dev/null +++ b/instanceprofiles/v2/model.go @@ -0,0 +1,90 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package instanceprofiles + +type AddInstanceProfileRequest struct { + // By default, validates that it has sufficient permissions to + // launch instances with the instance profile. This validation uses AWS dry-run + // mode for the RunInstances API. If validation fails with an error message that + // does not indicate an IAM related permission issue, (e.g. “Your requested + // instance type is not supported in your requested availability zone”), you + // can pass this flag to skip the validation and forcibly add the instance + // profile. + SkipValidation *bool + // The AWS ARN of the instance profile to register with . This field + // is required. + InstanceProfileArn *string + // Boolean flag indicating whether the instance profile should only be used in + // credential passthrough scenarios. If true, it means the instance profile + // contains an meta IAM role which could assume a wide range of roles. Therefore + // it should always be used with authorization. This field is optional, the + // default value is `false`. + IsMetaInstanceProfile *bool + // The AWS IAM role ARN of the role associated with the instance profile. This + // field is required if your role name and instance profile name do not match + // and you want to use the instance profile with [Databricks SQL + // Serverless](/sql/admin/serverless.html). + // + // Otherwise, this field is optional. + IamRoleArn *string +} + +type AddInstanceProfileResponse struct { +} + +type EditInstanceProfileRequest struct { + // The AWS ARN of the instance profile to register with . This field + // is required. + InstanceProfileArn *string + // Boolean flag indicating whether the instance profile should only be used in + // credential passthrough scenarios. If true, it means the instance profile + // contains an meta IAM role which could assume a wide range of roles. Therefore + // it should always be used with authorization. This field is optional, the + // default value is `false`. + IsMetaInstanceProfile *bool + // The AWS IAM role ARN of the role associated with the instance profile. This + // field is required if your role name and instance profile name do not match + // and you want to use the instance profile with [Databricks SQL + // Serverless](/sql/admin/serverless.html). + // + // Otherwise, this field is optional. + IamRoleArn *string +} + +type EditInstanceProfileResponse struct { +} + +type InstanceProfile struct { + // The AWS ARN of the instance profile to register with . This field + // is required. + InstanceProfileArn *string + // Boolean flag indicating whether the instance profile should only be used in + // credential passthrough scenarios. If true, it means the instance profile + // contains an meta IAM role which could assume a wide range of roles. Therefore + // it should always be used with authorization. This field is optional, the + // default value is `false`. + IsMetaInstanceProfile *bool + // The AWS IAM role ARN of the role associated with the instance profile. This + // field is required if your role name and instance profile name do not match + // and you want to use the instance profile with [Databricks SQL + // Serverless](/sql/admin/serverless.html). + // + // Otherwise, this field is optional. + IamRoleArn *string +} + +type ListInstanceProfilesRequest struct { +} + +type ListInstanceProfilesResponse struct { + // A list of instance profiles that the user can access. + InstanceProfiles []InstanceProfile +} + +type RemoveInstanceProfileRequest struct { + // The ARN of the instance profile to remove. This field is required. + InstanceProfileArn *string +} + +type RemoveInstanceProfileResponse struct { +} diff --git a/instanceprofiles/v2/wire.go b/instanceprofiles/v2/wire.go new file mode 100755 index 0000000..78d2682 --- /dev/null +++ b/instanceprofiles/v2/wire.go @@ -0,0 +1,105 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package instanceprofiles + +import ( + "fmt" +) + +type addInstanceProfileRequestWire struct { + SkipValidation *bool `json:"skip_validation,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + IsMetaInstanceProfile *bool `json:"is_meta_instance_profile,omitempty"` + IamRoleArn *string `json:"iam_role_arn,omitempty"` +} + +func addInstanceProfileRequestToWire(v *AddInstanceProfileRequest) (*addInstanceProfileRequestWire, error) { + if v == nil { + return nil, nil + } + return &addInstanceProfileRequestWire{ + SkipValidation: v.SkipValidation, + InstanceProfileArn: v.InstanceProfileArn, + IsMetaInstanceProfile: v.IsMetaInstanceProfile, + IamRoleArn: v.IamRoleArn, + }, nil +} + +type editInstanceProfileRequestWire struct { + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + IsMetaInstanceProfile *bool `json:"is_meta_instance_profile,omitempty"` + IamRoleArn *string `json:"iam_role_arn,omitempty"` +} + +func editInstanceProfileRequestToWire(v *EditInstanceProfileRequest) (*editInstanceProfileRequestWire, error) { + if v == nil { + return nil, nil + } + return &editInstanceProfileRequestWire{ + InstanceProfileArn: v.InstanceProfileArn, + IsMetaInstanceProfile: v.IsMetaInstanceProfile, + IamRoleArn: v.IamRoleArn, + }, nil +} + +type instanceProfileWire struct { + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + IsMetaInstanceProfile *bool `json:"is_meta_instance_profile,omitempty"` + IamRoleArn *string `json:"iam_role_arn,omitempty"` +} + +func instanceProfileFromWire(w *instanceProfileWire) (*InstanceProfile, error) { + if w == nil { + return nil, nil + } + return &InstanceProfile{ + InstanceProfileArn: w.InstanceProfileArn, + IsMetaInstanceProfile: w.IsMetaInstanceProfile, + IamRoleArn: w.IamRoleArn, + }, nil +} + +type listInstanceProfilesResponseWire struct { + InstanceProfiles []instanceProfileWire `json:"instance_profiles,omitempty"` +} + +func listInstanceProfilesResponseFromWire(w *listInstanceProfilesResponseWire) (*ListInstanceProfilesResponse, error) { + if w == nil { + return nil, nil + } + instanceProfilesPublicValue, err := convertSlice(w.InstanceProfiles, instanceProfileFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListInstanceProfilesResponse.InstanceProfiles", err) + } + return &ListInstanceProfilesResponse{ + InstanceProfiles: instanceProfilesPublicValue, + }, nil +} + +type removeInstanceProfileRequestWire struct { + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` +} + +func removeInstanceProfileRequestToWire(v *RemoveInstanceProfileRequest) (*removeInstanceProfileRequestWire, error) { + if v == nil { + return nil, nil + } + return &removeInstanceProfileRequestWire{ + InstanceProfileArn: v.InstanceProfileArn, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/jobs/.package.json b/jobs/.package.json new file mode 100644 index 0000000..6b56c1b --- /dev/null +++ b/jobs/.package.json @@ -0,0 +1,3 @@ +{ + "package": "jobs" +} diff --git a/jobs/CHANGELOG.md b/jobs/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/jobs/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/jobs/README.md b/jobs/README.md new file mode 100644 index 0000000..814404d --- /dev/null +++ b/jobs/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/jobs + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/jobs@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/jobs/v2" + +client, err := jobs.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/jobs/go.mod b/jobs/go.mod new file mode 100644 index 0000000..489ff60 --- /dev/null +++ b/jobs/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/jobs + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/jobs/internal/version.go b/jobs/internal/version.go new file mode 100644 index 0000000..7e91ae8 --- /dev/null +++ b/jobs/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-jobs" + +const Version = "0.0.1-dev.1" diff --git a/jobs/v2/client.go b/jobs/v2/client.go new file mode 100755 index 0000000..3b9bebb --- /dev/null +++ b/jobs/v2/client.go @@ -0,0 +1,1896 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package jobs + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/jobs/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Updates a job so the job clusters that are created when running the job +// (specified in `new_cluster`) are compliant with the current versions of their +// respective cluster policies. All-purpose clusters used in the job will not be +// updated. +func (c *internalClient) EnforcePolicyComplianceForJob(ctx context.Context, req *EnforcePolicyComplianceForJob, opts ...call.Option) (*EnforcePolicyComplianceResponse, error) { + wireReq, err := enforcePolicyComplianceForJobToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/jobs/enforce-compliance" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EnforcePolicyComplianceResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp enforcePolicyComplianceResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = enforcePolicyComplianceResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns the policy compliance status of a job. Jobs could be out of +// compliance if a cluster policy they use was updated after the job was last +// edited and some of its job clusters no longer comply with their updated +// policies. +func (c *internalClient) GetPolicyComplianceForJob(ctx context.Context, req *GetPolicyComplianceForJobRequest, opts ...call.Option) (*GetPolicyComplianceForJobResponse, error) { + wireReq, err := getPolicyComplianceForJobRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/jobs/get-compliance" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "job_id", wireReq.JobId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPolicyComplianceForJobResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPolicyComplianceForJobResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPolicyComplianceForJobResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns the policy compliance status of all jobs that use a given policy. +// Jobs could be out of compliance if a cluster policy they use was updated +// after the job was last edited and its job clusters no longer comply with the +// updated policy. +func (c *internalClient) ListJobComplianceForPolicy(ctx context.Context, req *ListJobComplianceForPolicy, opts ...call.Option) (*ListJobComplianceResponse, error) { + wireReq, err := listJobComplianceForPolicyToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policies/jobs/list-compliance" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "policy_id", wireReq.PolicyId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListJobComplianceResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listJobComplianceResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listJobComplianceResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListJobComplianceForPolicyIter returns an iterator that iterates +// over the results of ListJobComplianceForPolicy. +// +// For example: +// +// for item, err := range c.ListJobComplianceForPolicyIter(ctx, &ListJobComplianceForPolicy{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListJobComplianceForPolicy call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListJobComplianceForPolicy directly. +func (c *internalClient) ListJobComplianceForPolicyIter(ctx context.Context, req *ListJobComplianceForPolicy, opts ...call.Option) iter.Seq2[*ListJobComplianceForPolicy_JobCompliance, error] { + return func(yield func(*ListJobComplianceForPolicy_JobCompliance, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListJobComplianceForPolicy{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListJobComplianceForPolicy(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Jobs { + if !yield(&resp.Jobs[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Cancels all active runs of a job. The runs are canceled asynchronously, so it +// doesn't prevent new runs from being started. +func (c *internalClient) CancelAllRuns(ctx context.Context, req *CancelAllRunsRequest, opts ...call.Option) (*CancelAllRunsResponse, error) { + wireReq, err := cancelAllRunsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/runs/cancel-all" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CancelAllRunsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &CancelAllRunsResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Cancels a job run or a task run. The run is canceled asynchronously, so it +// may still be running when this request completes. +func (c *internalClient) cancelRunBase(ctx context.Context, req *CancelRunRequest, opts ...call.Option) (*CancelRunResponse, error) { + wireReq, err := cancelRunRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/runs/cancel" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CancelRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &CancelRunResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Cancels a job run or a task run. The run is canceled asynchronously, so it +// may still be running when this request completes. +func (c *internalClient) CancelRun(ctx context.Context, req *CancelRunRequest, opts ...call.Option) (*CancelRunWaiter, error) { + if req.RunId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "RunId") + } + capturedRunId := *req.RunId + _, err := c.cancelRunBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &CancelRunWaiter{ + poll: c.GetRun, + runId: capturedRunId, + }, nil +} + +// CancelRunWaiter tracks the state of the operation started by CancelRun. +type CancelRunWaiter struct { + poll func(context.Context, *GetRunRequest, ...call.Option) (*GetRunResponse, error) + runId int64 +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CancelRunWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetRunRequest{ + RunId: &w.runId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.LifeCycleState + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case RunLifeCycleState_RunLifeCycleState_Terminated, RunLifeCycleState_RunLifeCycleState_Skipped, RunLifeCycleState_RunLifeCycleState_InternalError: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CancelRunWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetRunResponse, error) { + var result *GetRunResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetRunRequest{ + RunId: &w.runId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.LifeCycleState + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case RunLifeCycleState_RunLifeCycleState_Terminated, RunLifeCycleState_RunLifeCycleState_Skipped: + result = pollResp + return nil + case RunLifeCycleState_RunLifeCycleState_InternalError: + message := "(no message)" + if pollResp.State != nil && pollResp.State.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.State.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Create a new job. +func (c *internalClient) CreateJob(ctx context.Context, req *CreateJobRequest, opts ...call.Option) (*CreateJobResponse, error) { + wireReq, err := createJobRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateJobResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createJobResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createJobResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a job. +func (c *internalClient) DeleteJob(ctx context.Context, req *DeleteJobRequest, opts ...call.Option) (*DeleteJobResponse, error) { + wireReq, err := deleteJobRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteJobResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteJobResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a non-active run. Returns an error if the run is active. +func (c *internalClient) DeleteRun(ctx context.Context, req *DeleteRunRequest, opts ...call.Option) (*DeleteRunResponse, error) { + wireReq, err := deleteRunRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/runs/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteRunResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Export and retrieve the job run task. +func (c *internalClient) ExportRun(ctx context.Context, req *ExportRunRequest, opts ...call.Option) (*ExportRunResponse, error) { + wireReq, err := exportRunRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/runs/export" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "run_id", wireReq.RunId); err != nil { + return nil, err + } + if wireReq.ViewsToExport != "" { + if err := addQueryValue(queryParams, "views_to_export", wireReq.ViewsToExport); err != nil { + return nil, err + } + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExportRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp exportRunResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = exportRunResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves the details for a single job. +// +// Large arrays in the results will be paginated when they exceed 100 elements. +// A request for a single job will return all properties for that job, and the +// first 100 elements of array properties (`tasks`, `job_clusters`, +// `environments` and `parameters`). Use the `next_page_token` field to check +// for more results and pass its value as the `page_token` in subsequent +// requests. If any array properties have more than 100 elements, additional +// results will be returned on subsequent requests. Arrays without additional +// results will be empty on later pages. +func (c *internalClient) GetJob(ctx context.Context, req *GetJobRequest, opts ...call.Option) (*GetJobResponse, error) { + wireReq, err := getJobRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "job_id", wireReq.JobId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_trigger_state", wireReq.IncludeTriggerState); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetJobResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getJobResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getJobResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves the metadata of a run. +// +// Large arrays in the results will be paginated when they exceed 100 elements. +// A request for a single run will return all properties for that run, and the +// first 100 elements of array properties (`tasks`, `job_clusters`, +// `job_parameters` and `repair_history`). Use the next_page_token field to +// check for more results and pass its value as the page_token in subsequent +// requests. If any array properties have more than 100 elements, additional +// results will be returned on subsequent requests. Arrays without additional +// results will be empty on later pages. +func (c *internalClient) GetRun(ctx context.Context, req *GetRunRequest, opts ...call.Option) (*GetRunResponse, error) { + wireReq, err := getRunRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/runs/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "run_id", wireReq.RunId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_history", wireReq.IncludeHistory); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_resolved_values", wireReq.IncludeResolvedValues); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getRunResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getRunResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieve the output and metadata of a single task run. When a notebook task +// returns a value through the `dbutils.notebook.exit()` call, you can use this +// endpoint to retrieve that value. restricts this API to returning +// the first 5 MB of the output. To return a larger result, you can store job +// results in a cloud storage service. +// +// This endpoint validates that the __run_id__ parameter is valid and returns an +// HTTP status code 400 if the __run_id__ parameter is invalid. Runs are +// automatically removed after 60 days. If you to want to reference them beyond +// 60 days, you must save old run results before they expire. +func (c *internalClient) GetRunOutput(ctx context.Context, req *GetRunOutputRequest, opts ...call.Option) (*GetRunOutputResponse, error) { + wireReq, err := getRunOutputRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/runs/get-output" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "run_id", wireReq.RunId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetRunOutputResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getRunOutputResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getRunOutputResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves a list of jobs. +func (c *internalClient) ListJobs(ctx context.Context, req *ListJobsRequest, opts ...call.Option) (*ListJobsResponse, error) { + wireReq, err := listJobsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/list" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "offset", wireReq.Offset); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "limit", wireReq.Limit); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "expand_tasks", wireReq.ExpandTasks); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListJobsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listJobsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listJobsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListJobsIter returns an iterator that iterates +// over the results of ListJobs. +// +// For example: +// +// for item, err := range c.ListJobsIter(ctx, &ListJobsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListJobs call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListJobs directly. +func (c *internalClient) ListJobsIter(ctx context.Context, req *ListJobsRequest, opts ...call.Option) iter.Seq2[*BaseJob, error] { + return func(yield func(*BaseJob, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListJobsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListJobs(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Jobs { + if !yield(&resp.Jobs[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List runs in descending order by end time. If a run has not finished, it +// falls back to start time. +func (c *internalClient) ListRuns(ctx context.Context, req *ListRunsRequest, opts ...call.Option) (*ListRunsResponse, error) { + wireReq, err := listRunsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/runs/list" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "job_id", wireReq.JobId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "active_only", wireReq.ActiveOnly); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "completed_only", wireReq.CompletedOnly); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "offset", wireReq.Offset); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "limit", wireReq.Limit); err != nil { + return nil, err + } + if wireReq.RunType != "" { + if err := addQueryValue(queryParams, "run_type", wireReq.RunType); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "expand_tasks", wireReq.ExpandTasks); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "start_time_from", wireReq.StartTimeFrom); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "start_time_to", wireReq.StartTimeTo); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListRunsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listRunsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listRunsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListRunsIter returns an iterator that iterates +// over the results of ListRuns. +// +// For example: +// +// for item, err := range c.ListRunsIter(ctx, &ListRunsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListRuns call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListRuns directly. +func (c *internalClient) ListRunsIter(ctx context.Context, req *ListRunsRequest, opts ...call.Option) iter.Seq2[*BaseRun, error] { + return func(yield func(*BaseRun, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListRunsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListRuns(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Runs { + if !yield(&resp.Runs[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Re-run one or more tasks. Tasks are re-run as part of the original job run. +// They use the current job and task settings, and can be viewed in the history +// for the original job run. +func (c *internalClient) repairBase(ctx context.Context, req *RepairRunRequest, opts ...call.Option) (*RepairRunResponse, error) { + wireReq, err := repairRunRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/runs/repair" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RepairRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp repairRunResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = repairRunResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Re-run one or more tasks. Tasks are re-run as part of the original job run. +// They use the current job and task settings, and can be viewed in the history +// for the original job run. +func (c *internalClient) Repair(ctx context.Context, req *RepairRunRequest, opts ...call.Option) (*RepairWaiter, error) { + if req.RunId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "RunId") + } + capturedRunId := *req.RunId + _, err := c.repairBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &RepairWaiter{ + poll: c.GetRun, + runId: capturedRunId, + }, nil +} + +// RepairWaiter tracks the state of the operation started by Repair. +type RepairWaiter struct { + poll func(context.Context, *GetRunRequest, ...call.Option) (*GetRunResponse, error) + runId int64 +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *RepairWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetRunRequest{ + RunId: &w.runId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.LifeCycleState + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case RunLifeCycleState_RunLifeCycleState_Terminated, RunLifeCycleState_RunLifeCycleState_Skipped, RunLifeCycleState_RunLifeCycleState_InternalError: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *RepairWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetRunResponse, error) { + var result *GetRunResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetRunRequest{ + RunId: &w.runId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.LifeCycleState + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case RunLifeCycleState_RunLifeCycleState_Terminated, RunLifeCycleState_RunLifeCycleState_Skipped: + result = pollResp + return nil + case RunLifeCycleState_RunLifeCycleState_InternalError: + message := "(no message)" + if pollResp.State != nil && pollResp.State.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.State.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Overwrite all settings for the given job. Use the [_Update_ +// endpoint](:method:jobs/update) to update job settings partially. +func (c *internalClient) ResetJob(ctx context.Context, req *ResetJobRequest, opts ...call.Option) (*ResetJobResponse, error) { + wireReq, err := resetJobRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/reset" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ResetJobResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &ResetJobResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Run a job and return the `run_id` of the triggered run. +func (c *internalClient) runNowBase(ctx context.Context, req *RunNowRequest, opts ...call.Option) (*RunNowResponse, error) { + wireReq, err := runNowRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/run-now" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RunNowResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp runNowResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = runNowResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Run a job and return the `run_id` of the triggered run. +func (c *internalClient) RunNow(ctx context.Context, req *RunNowRequest, opts ...call.Option) (*RunNowWaiter, error) { + resp, err := c.runNowBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.RunId == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "RunId") + } + return &RunNowWaiter{ + poll: c.GetRun, + runId: *resp.RunId, + }, nil +} + +// RunNowWaiter tracks the state of the operation started by RunNow. +type RunNowWaiter struct { + poll func(context.Context, *GetRunRequest, ...call.Option) (*GetRunResponse, error) + runId int64 +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *RunNowWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetRunRequest{ + RunId: &w.runId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.LifeCycleState + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case RunLifeCycleState_RunLifeCycleState_Terminated, RunLifeCycleState_RunLifeCycleState_Skipped, RunLifeCycleState_RunLifeCycleState_InternalError: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *RunNowWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetRunResponse, error) { + var result *GetRunResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetRunRequest{ + RunId: &w.runId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.LifeCycleState + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case RunLifeCycleState_RunLifeCycleState_Terminated, RunLifeCycleState_RunLifeCycleState_Skipped: + result = pollResp + return nil + case RunLifeCycleState_RunLifeCycleState_InternalError: + message := "(no message)" + if pollResp.State != nil && pollResp.State.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.State.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Submit a one-time run. This endpoint allows you to submit a workload directly +// without creating a job. Runs submitted using this endpoint don’t display in +// the UI. Use the `jobs/runs/get` API to check the run state after the job is +// submitted. +// +// **Important:** Jobs submitted using this endpoint are not saved as a job. +// They do not show up in the Jobs UI, and do not retry when they fail. Because +// they are not saved, cannot auto-optimize serverless compute in +// case of failure. If your job fails, you may want to use classic compute to +// specify the compute needs for the job. Alternatively, use the `POST +// /jobs/create` and `POST /jobs/run-now` endpoints to create and run a saved +// job. +func (c *internalClient) submitRunBase(ctx context.Context, req *SubmitRunRequest, opts ...call.Option) (*SubmitRunResponse, error) { + wireReq, err := submitRunRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/runs/submit" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SubmitRunResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp submitRunResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = submitRunResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Submit a one-time run. This endpoint allows you to submit a workload directly +// without creating a job. Runs submitted using this endpoint don’t display in +// the UI. Use the `jobs/runs/get` API to check the run state after the job is +// submitted. +// +// **Important:** Jobs submitted using this endpoint are not saved as a job. +// They do not show up in the Jobs UI, and do not retry when they fail. Because +// they are not saved, cannot auto-optimize serverless compute in +// case of failure. If your job fails, you may want to use classic compute to +// specify the compute needs for the job. Alternatively, use the `POST +// /jobs/create` and `POST /jobs/run-now` endpoints to create and run a saved +// job. +func (c *internalClient) SubmitRun(ctx context.Context, req *SubmitRunRequest, opts ...call.Option) (*SubmitRunWaiter, error) { + resp, err := c.submitRunBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.RunId == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "RunId") + } + return &SubmitRunWaiter{ + poll: c.GetRun, + runId: *resp.RunId, + }, nil +} + +// SubmitRunWaiter tracks the state of the operation started by SubmitRun. +type SubmitRunWaiter struct { + poll func(context.Context, *GetRunRequest, ...call.Option) (*GetRunResponse, error) + runId int64 +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *SubmitRunWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetRunRequest{ + RunId: &w.runId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.LifeCycleState + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case RunLifeCycleState_RunLifeCycleState_Terminated, RunLifeCycleState_RunLifeCycleState_Skipped, RunLifeCycleState_RunLifeCycleState_InternalError: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *SubmitRunWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetRunResponse, error) { + var result *GetRunResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetRunRequest{ + RunId: &w.runId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.LifeCycleState + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case RunLifeCycleState_RunLifeCycleState_Terminated, RunLifeCycleState_RunLifeCycleState_Skipped: + result = pollResp + return nil + case RunLifeCycleState_RunLifeCycleState_InternalError: + message := "(no message)" + if pollResp.State != nil && pollResp.State.StateMessage != nil { + message = fmt.Sprintf("%v", *pollResp.State.StateMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Add, update, or remove specific settings of an existing job. Use the [_Reset_ +// endpoint](:method:jobs/reset) to overwrite all job settings. +func (c *internalClient) UpdateJob(ctx context.Context, req *UpdateJobRequest, opts ...call.Option) (*UpdateJobResponse, error) { + wireReq, err := updateJobRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.2/jobs/update" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateJobResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateJobResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/jobs/v2/genhelper.go b/jobs/v2/genhelper.go new file mode 100755 index 0000000..74c3a7b --- /dev/null +++ b/jobs/v2/genhelper.go @@ -0,0 +1,199 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package jobs + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} diff --git a/jobs/v2/model.go b/jobs/v2/model.go new file mode 100755 index 0000000..9553bfc --- /dev/null +++ b/jobs/v2/model.go @@ -0,0 +1,6162 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package jobs + +type AuthenticationMethod string + +const ( + AuthenticationMethod_Unspecified AuthenticationMethod = "" + AuthenticationMethod_Pat AuthenticationMethod = "PAT" +) + +// Availability type used for all subsequent nodes past the `first_on_demand` +// ones. +// +// Note: If `first_on_demand` is zero, this availability type will be used for +// the entire cluster. +type AwsAvailability string + +const ( + AwsAvailability_Unspecified AwsAvailability = "" + // Use spot instances. + AwsAvailability_Spot AwsAvailability = "SPOT" + // Use on-demand instances. + AwsAvailability_OnDemand AwsAvailability = "ON_DEMAND" + // Preferably use spot instances, but fall back to on-demand instances if spot + // instances cannot be acquired (e.g., if AWS spot prices are too high). + AwsAvailability_SpotWithFallback AwsAvailability = "SPOT_WITH_FALLBACK" +) + +// Availability type used for all subsequent nodes past the `first_on_demand` +// ones. Note: If `first_on_demand` is zero, this availability type will be used +// for the entire cluster. +type AzureAvailability string + +const ( + AzureAvailability_Unspecified AzureAvailability = "" + // Use spot instances. + AzureAvailability_SpotAzure AzureAvailability = "SPOT_AZURE" + // Use on-demand instances. + AzureAvailability_OnDemandAzure AzureAvailability = "ON_DEMAND_AZURE" + // Preferably use spot instances, but fall back to on-demand instances if spot + // instances cannot be acquired (e.g., if Azure is out of Quota). + AzureAvailability_SpotWithFallbackAzure AzureAvailability = "SPOT_WITH_FALLBACK_AZURE" +) + +// The kind of compute described by this compute specification. +// +// Depending on `kind`, different validations and default values will be +// applied. +// +// Clusters with `kind = CLASSIC_PREVIEW` support the following fields, whereas +// clusters with no specified `kind` do not. * +// [is_single_node](/api/workspace/clusters/create#is_single_node) * +// [use_ml_runtime](/api/workspace/clusters/create#use_ml_runtime) +// +// By using the [simple form], your clusters are automatically using `kind = +// CLASSIC_PREVIEW`. +// +// [simple form]: https://docs.databricks.com/compute/simple-form.html +type ComputeKind string + +const ( + ComputeKind_Unspecified ComputeKind = "" + ComputeKind_ClassicPreview ComputeKind = "CLASSIC_PREVIEW" +) + +// Confidential computing technology for GCP instances. Aligns with gcloud's +// --confidential-compute-type flag and the REST API's +// confidentialInstanceConfig.confidentialInstanceType field. See: +// https://cloud.google.com/confidential-computing/confidential-vm/docs/create-a-confidential-vm-instance +type ConfidentialComputeType string + +const ( + ConfidentialComputeType_Unspecified ConfidentialComputeType = "" + ConfidentialComputeType_ConfidentialComputeTypeNone ConfidentialComputeType = "CONFIDENTIAL_COMPUTE_TYPE_NONE" + ConfidentialComputeType_SevSnp ConfidentialComputeType = "SEV_SNP" +) + +// Data security mode decides what data governance model to use when accessing +// data from a cluster. +// +// * `DATA_SECURITY_MODE_AUTO`: will choose the most appropriate +// access mode depending on your compute configuration. * +// `DATA_SECURITY_MODE_STANDARD`: A secure cluster that can be shared by +// multiple users. Cluster users are fully isolated so that they cannot see each +// other’s data and credentials. Most data governance features are supported +// in this mode. But programming languages and cluster features might be +// limited. * `DATA_SECURITY_MODE_DEDICATED`: A secure cluster that can only be +// exclusively used by a single user specified in `single_user_name`. Most +// programming languages, cluster features and data governance features are +// available in this mode. +// +// The following modes are legacy aliases for the above modes: +// +// * `USER_ISOLATION`: Legacy alias for `DATA_SECURITY_MODE_STANDARD`. * +// `SINGLE_USER`: Legacy alias for `DATA_SECURITY_MODE_DEDICATED`. +// +// The following modes are deprecated starting with Databricks Runtime 15.0 and +// will be removed for future Databricks Runtime versions: +// +// * `LEGACY_TABLE_ACL`: This mode is for users migrating from legacy Table ACL +// clusters. * `LEGACY_PASSTHROUGH`: This mode is for users migrating from +// legacy Passthrough on high concurrency clusters. * `LEGACY_SINGLE_USER`: This +// mode is for users migrating from legacy Passthrough on standard clusters. * +// `LEGACY_SINGLE_USER_STANDARD`: This mode provides a way that doesn’t have +// UC nor passthrough enabled. +type DataSecurityMode string + +const ( + DataSecurityMode_Unspecified DataSecurityMode = "" + // No security isolation for multiple users sharing the cluster. Data governance + // features are not available in this mode. + DataSecurityMode_None DataSecurityMode = "NONE" + // Legacy alias for `DATA_SECURITY_MODE_DEDICATED`. + DataSecurityMode_SingleUser DataSecurityMode = "SINGLE_USER" + // Legacy alias for `DATA_SECURITY_MODE_STANDARD`. + DataSecurityMode_UserIsolation DataSecurityMode = "USER_ISOLATION" + // This mode is for users migrating from legacy Table ACL clusters. + DataSecurityMode_LegacyTableAcl DataSecurityMode = "LEGACY_TABLE_ACL" + // This mode is for users migrating from legacy Passthrough on high concurrency + // clusters. + DataSecurityMode_LegacyPassthrough DataSecurityMode = "LEGACY_PASSTHROUGH" + // This mode is for users migrating from legacy Passthrough on standard + // clusters. + DataSecurityMode_LegacySingleUser DataSecurityMode = "LEGACY_SINGLE_USER" + // This is mode where single user is enforced but no actual security feature + // enabled. + DataSecurityMode_LegacySingleUserStandard DataSecurityMode = "LEGACY_SINGLE_USER_STANDARD" + // A secure cluster that can be shared by multiple users. Cluster users are + // fully isolated so that they cannot see each other's data and credentials. + // Most data governance features are supported in this mode. But programming + // languages and cluster features might be limited. + DataSecurityMode_DataSecurityModeStandard DataSecurityMode = "DATA_SECURITY_MODE_STANDARD" + // A secure cluster that can only be exclusively used by a single user specified + // in `single_user_name`. Most programming languages, cluster features and data + // governance features are available in this mode. + DataSecurityMode_DataSecurityModeDedicated DataSecurityMode = "DATA_SECURITY_MODE_DEDICATED" + // Databricks will choose `DATA_SECURITY_MODE_STANDARD` or + // `DATA_SECURITY_MODE_DEDICATED` depending on the compute configuration. + DataSecurityMode_DataSecurityModeAuto DataSecurityMode = "DATA_SECURITY_MODE_AUTO" +) + +// Response enumeration from calling the dbt platform API, for inclusion in +// output +type DbtPlatformRunStatus string + +const ( + DbtPlatformRunStatus_Unspecified DbtPlatformRunStatus = "" + DbtPlatformRunStatus_Queued DbtPlatformRunStatus = "QUEUED" + DbtPlatformRunStatus_Starting DbtPlatformRunStatus = "STARTING" + DbtPlatformRunStatus_Running DbtPlatformRunStatus = "RUNNING" + DbtPlatformRunStatus_Success DbtPlatformRunStatus = "SUCCESS" + DbtPlatformRunStatus_Error DbtPlatformRunStatus = "ERROR" + DbtPlatformRunStatus_Cancelled DbtPlatformRunStatus = "CANCELLED" +) + +// Controls dependency configuration for the cluster. +// +// * `DEPENDENCY_MODE_AUTO`: will choose the most appropriate +// dependency mode based on your compute configuration. * +// `DEPENDENCY_MODE_ENVIRONMENTS`: Enables a unified dependency management +// experience across classic and serverless, resulting in increased stability +// and performance. Supported only on DBR 19+ in Standard access mode. * +// `DEPENDENCY_MODE_CLUSTER_LIBRARIES`: Legacy mode: dependencies come from +// cluster libraries and init scripts. +type DependencyMode string + +const ( + DependencyMode_Unspecified DependencyMode = "" + DependencyMode_DependencyModeEnvironments DependencyMode = "DEPENDENCY_MODE_ENVIRONMENTS" + DependencyMode_DependencyModeClusterLibraries DependencyMode = "DEPENDENCY_MODE_CLUSTER_LIBRARIES" + DependencyMode_DependencyModeAuto DependencyMode = "DEPENDENCY_MODE_AUTO" +) + +// All EBS volume types that supports. See +// https://aws.amazon.com/ebs/details/ for details. +type EbsVolumeType string + +const ( + EbsVolumeType_Unspecified EbsVolumeType = "" + // Provision extra storage using AWS gp2 EBS volumes. + EbsVolumeType_GeneralPurposeSsd EbsVolumeType = "GENERAL_PURPOSE_SSD" + // Provision extra storage using AWS st1 volumes. + EbsVolumeType_ThroughputOptimizedHdd EbsVolumeType = "THROUGHPUT_OPTIMIZED_HDD" +) + +type Format string + +const ( + Format_Unspecified Format = "" + Format_MultiTask Format = "MULTI_TASK" +) + +// This field determines whether the instance pool will contain preemptible VMs, +// on-demand VMs, or preemptible VMs with a fallback to on-demand VMs if the +// former is unavailable. +type GcpAvailability string + +const ( + GcpAvailability_Unspecified GcpAvailability = "" + GcpAvailability_PreemptibleGcp GcpAvailability = "PREEMPTIBLE_GCP" + GcpAvailability_OnDemandGcp GcpAvailability = "ON_DEMAND_GCP" + GcpAvailability_PreemptibleWithFallbackGcp GcpAvailability = "PREEMPTIBLE_WITH_FALLBACK_GCP" +) + +// HardwareAcceleratorType: The type of hardware accelerator to use for compute +// workloads. NOTE: This enum is referenced and is intended to be used by other +// services that need to specify hardware accelerator requirements +// for AI compute workloads. +type HardwareAcceleratorType string + +const ( + HardwareAcceleratorType_Unspecified HardwareAcceleratorType = "" + // GPU_1xA10: Single A10 GPU configuration. + HardwareAcceleratorType_Gpu1xA10 HardwareAcceleratorType = "GPU_1xA10" + // GPU_8xH100: 8x H100 GPU configuration. + HardwareAcceleratorType_Gpu8xH100 HardwareAcceleratorType = "GPU_8xH100" +) + +// Edit mode of the job. +// +// * `UI_LOCKED`: The job is in a locked UI state and cannot be modified. * +// `EDITABLE`: The job is in an editable state and can be modified. +type JobEditMode string + +const ( + JobEditMode_Unspecified JobEditMode = "" + JobEditMode_UiLocked JobEditMode = "UI_LOCKED" + JobEditMode_Editable JobEditMode = "EDITABLE" +) + +// Specifies the health metric that is being evaluated for a particular health +// rule. +// +// * `RUN_DURATION_SECONDS`: Expected total time for a run in seconds. * +// `STREAMING_BACKLOG_BYTES`: An estimate of the maximum bytes of data waiting +// to be consumed across all streams. This metric is in Public Preview. * +// `STREAMING_BACKLOG_RECORDS`: An estimate of the maximum offset lag across all +// streams. This metric is in Public Preview. * `STREAMING_BACKLOG_SECONDS`: An +// estimate of the maximum consumer delay across all streams. This metric is in +// Public Preview. * `STREAMING_BACKLOG_FILES`: An estimate of the maximum +// number of outstanding files across all streams. This metric is in Public +// Preview. +type JobsHealthMetric string + +const ( + JobsHealthMetric_Unspecified JobsHealthMetric = "" + JobsHealthMetric_RunDurationSeconds JobsHealthMetric = "RUN_DURATION_SECONDS" + JobsHealthMetric_StreamingBacklogBytes JobsHealthMetric = "STREAMING_BACKLOG_BYTES" + JobsHealthMetric_StreamingBacklogRecords JobsHealthMetric = "STREAMING_BACKLOG_RECORDS" + JobsHealthMetric_StreamingBacklogSeconds JobsHealthMetric = "STREAMING_BACKLOG_SECONDS" + JobsHealthMetric_StreamingBacklogFiles JobsHealthMetric = "STREAMING_BACKLOG_FILES" +) + +// Specifies the operator used to compare the health metric value with the +// specified threshold. +type JobsHealthOperator string + +const ( + JobsHealthOperator_Unspecified JobsHealthOperator = "" + JobsHealthOperator_GreaterThan JobsHealthOperator = "GREATER_THAN" +) + +// The repair history item type. Indicates whether a run is the original run or +// a repair run. +type RepairType string + +const ( + RepairType_Unspecified RepairType = "" + RepairType_Original RepairType = "ORIGINAL" + RepairType_Repair RepairType = "REPAIR" +) + +// The type of a run. * `JOB_RUN`: Normal job run. A run created with +// :method:jobs/runNow. * `WORKFLOW_RUN`: Workflow run. A run created with +// [dbutils.notebook.run](/dev-tools/databricks-utils.html#dbutils-workflow). * +// `SUBMIT_RUN`: Submit run. A run created with :method:jobs/submit. +type RunType string + +const ( + RunType_Unspecified RunType = "" + RunType_JobRun RunType = "JOB_RUN" + RunType_WorkflowRun RunType = "WORKFLOW_RUN" + RunType_SubmitRun RunType = "SUBMIT_RUN" +) + +type RuntimeEngine string + +const ( + RuntimeEngine_Unspecified RuntimeEngine = "" + // Use standard engine + RuntimeEngine_Standard RuntimeEngine = "STANDARD" + // Use Photon engine + RuntimeEngine_Photon RuntimeEngine = "PHOTON" +) + +type SchedulePauseStatus string + +const ( + SchedulePauseStatus_Unspecified SchedulePauseStatus = "" + SchedulePauseStatus_Paused SchedulePauseStatus = "PAUSED" +) + +// Optional location type of the SQL file. When set to `WORKSPACE`, the SQL file +// will be retrieved\ from the local workspace. When set to `GIT`, +// the SQL file will be retrieved from a Git repository defined in `git_source`. +// If the value is empty, the task will use `GIT` if `git_source` is defined and +// `WORKSPACE` otherwise. +// +// * `WORKSPACE`: SQL file is located in workspace. * `GIT`: SQL +// file is located in cloud Git provider. +type Source string + +const ( + Source_Unspecified Source = "" + Source_Workspace Source = "WORKSPACE" + Source_Git Source = "GIT" +) + +// The strategy used to evaluate a SQL condition trigger against a query result +// set. +// +// * `SQL_CONDITION_TRIGGER_MODE_UNSPECIFIED`: Sentinel zero-value. Not a valid +// input — the validator rejects this when sent explicitly. Internally treated +// as `QUERY_RETURNS_ROWS` when reading legacy data that predates this field. * +// `QUERY_RETURNS_ROWS`: Fires whenever the result set has at least one row. +// Zero rows means the condition is not met. This is the original SQL condition +// behavior. * `RESULT_VALUE_CHANGES`: Fires whenever the query's single result +// value differs from the previous evaluation. The first evaluation always +// fires. Queries must return exactly one cell (one row, one column). +type SqlConditionTriggerMode string + +const ( + SqlConditionTriggerMode_Unspecified SqlConditionTriggerMode = "" + SqlConditionTriggerMode_QueryReturnsRows SqlConditionTriggerMode = "QUERY_RETURNS_ROWS" + SqlConditionTriggerMode_ResultValueChanges SqlConditionTriggerMode = "RESULT_VALUE_CHANGES" +) + +type StorageMode string + +const ( + StorageMode_Unspecified StorageMode = "" + StorageMode_Import StorageMode = "IMPORT" + StorageMode_Dual StorageMode = "DUAL" +) + +// An optional value indicating the condition that determines whether the task +// should be run once its dependencies have been completed. When omitted, +// defaults to `ALL_SUCCESS`. +// +// Possible values are: * `ALL_SUCCESS`: All dependencies have executed and +// succeeded * `AT_LEAST_ONE_SUCCESS`: At least one dependency has succeeded * +// `NONE_FAILED`: None of the dependencies have failed and at least one was +// executed * `ALL_DONE`: All dependencies have been completed * +// `AT_LEAST_ONE_FAILED`: At least one dependency failed * `ALL_FAILED`: ALl +// dependencies have failed +type TaskDependencyType string + +const ( + TaskDependencyType_Unspecified TaskDependencyType = "" + TaskDependencyType_AllSuccess TaskDependencyType = "ALL_SUCCESS" + TaskDependencyType_AllDone TaskDependencyType = "ALL_DONE" + TaskDependencyType_NoneFailed TaskDependencyType = "NONE_FAILED" + TaskDependencyType_AtLeastOneSuccess TaskDependencyType = "AT_LEAST_ONE_SUCCESS" + TaskDependencyType_AllFailed TaskDependencyType = "ALL_FAILED" + TaskDependencyType_AtLeastOneFailed TaskDependencyType = "AT_LEAST_ONE_FAILED" +) + +// task retry mode of the continuous job * NEVER: The failed task will not be +// retried. * ON_FAILURE: Retry a failed task if at least one other task in the +// job is still running its first attempt. When this condition is no longer met +// or the retry limit is reached, the job run is cancelled and a new run is +// started. +type TaskRetryMode string + +const ( + TaskRetryMode_Unspecified TaskRetryMode = "" + TaskRetryMode_Never TaskRetryMode = "NEVER" + TaskRetryMode_OnFailure TaskRetryMode = "ON_FAILURE" +) + +// The type of trigger that fired this run. +// +// * `PERIODIC`: Schedules that periodically trigger runs, such as a cron +// scheduler. * `ONE_TIME`: One time triggers that fire a single run. This +// occurs you triggered a single run on demand through the UI or the API. * +// `RETRY`: Indicates a run that is triggered as a retry of a previously failed +// run. This occurs when you request to re-run the job in case of failures. * +// `RUN_JOB_TASK`: Indicates a run that is triggered using a Run Job task. * +// `FILE_ARRIVAL`: Indicates a run that is triggered by a file arrival. * +// `CONTINUOUS`: Indicates a run that is triggered by a continuous job. * +// `TABLE`: Indicates a run that is triggered by a table update. * +// `CONTINUOUS_RESTART`: Indicates a run created by user to manually restart a +// continuous job run. * `MODEL`: Indicates a run that is triggered by a model +// update. +type TriggerType string + +const ( + TriggerType_Unspecified TriggerType = "" + TriggerType_Periodic TriggerType = "PERIODIC" + TriggerType_OneTime TriggerType = "ONE_TIME" + TriggerType_Retry TriggerType = "RETRY" + TriggerType_RunJobTask TriggerType = "RUN_JOB_TASK" + TriggerType_FileArrival TriggerType = "FILE_ARRIVAL" + TriggerType_Continuous TriggerType = "CONTINUOUS" + TriggerType_Table TriggerType = "TABLE" + TriggerType_ContinuousRestart TriggerType = "CONTINUOUS_RESTART" +) + +// * `NOTEBOOK`: Notebook view item. * `DASHBOARD`: Dashboard view item. +type ViewType string + +const ( + ViewType_Unspecified ViewType = "" + ViewType_Notebook ViewType = "NOTEBOOK" + ViewType_Dashboard ViewType = "DASHBOARD" +) + +// * `CODE`: Code view of the notebook. * `DASHBOARDS`: All dashboard views of +// the notebook. * `ALL`: All views of the notebook. +type ViewsToExport string + +const ( + ViewsToExport_Unspecified ViewsToExport = "" + ViewsToExport_Code ViewsToExport = "CODE" + ViewsToExport_Dashboards ViewsToExport = "DASHBOARDS" + ViewsToExport_All ViewsToExport = "ALL" +) + +type AccessControlRequest_JobPermission string + +const ( + AccessControlRequest_JobPermission_Unspecified AccessControlRequest_JobPermission = "" + AccessControlRequest_JobPermission_CanView AccessControlRequest_JobPermission = "CAN_VIEW" + AccessControlRequest_JobPermission_CanManageRun AccessControlRequest_JobPermission = "CAN_MANAGE_RUN" + AccessControlRequest_JobPermission_IsOwner AccessControlRequest_JobPermission = "IS_OWNER" + AccessControlRequest_JobPermission_CanManage AccessControlRequest_JobPermission = "CAN_MANAGE" +) + +// Same alert evaluation state as in redash-v2/api/proto/alertsv2/alerts.proto +type AlertEvaluationState_AlertEvaluationState string + +const ( + AlertEvaluationState_AlertEvaluationState_Unspecified AlertEvaluationState_AlertEvaluationState = "" + AlertEvaluationState_AlertEvaluationState_Unknown AlertEvaluationState_AlertEvaluationState = "UNKNOWN" + AlertEvaluationState_AlertEvaluationState_Triggered AlertEvaluationState_AlertEvaluationState = "TRIGGERED" + AlertEvaluationState_AlertEvaluationState_Ok AlertEvaluationState_AlertEvaluationState = "OK" + AlertEvaluationState_AlertEvaluationState_Error AlertEvaluationState_AlertEvaluationState = "ERROR" +) + +// Copied from elastic-spark-common/api/messages/runs.proto. Using the original +// definition to remove coupling with jobs API definition +type CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState string + +const ( + CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState_Unspecified CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState = "" + CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState_Pending CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState = "PENDING" + CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState_Running CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState = "RUNNING" + CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState_Terminating CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState = "TERMINATING" + CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState_Terminated CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState = "TERMINATED" + CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState_Skipped CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState = "SKIPPED" + CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState_InternalError CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState = "INTERNAL_ERROR" + CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState_Blocked CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState = "BLOCKED" + CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState_WaitingForRetry CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState = "WAITING_FOR_RETRY" + CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState_Queued CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState = "QUEUED" +) + +// Copied from elastic-spark-common/api/messages/runs.proto. Using the original +// definition to avoid cyclic dependency. +type CleanRoomTaskRunResultState_CleanRoomTaskRunResultState string + +const ( + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_Unspecified CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_Success CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "SUCCESS" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_Failed CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "FAILED" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_Timedout CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "TIMEDOUT" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_Canceled CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "CANCELED" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_MaximumConcurrentRunsReached CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "MAXIMUM_CONCURRENT_RUNS_REACHED" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_UpstreamCanceled CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "UPSTREAM_CANCELED" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_UpstreamFailed CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "UPSTREAM_FAILED" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_Excluded CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "EXCLUDED" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_Evicted CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "EVICTED" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_SuccessWithFailures CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "SUCCESS_WITH_FAILURES" + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_UpstreamEvicted CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "UPSTREAM_EVICTED" + // 12 is reserved for previously used SUCCESS_WITH_SKIPPED_CELLS + CleanRoomTaskRunResultState_CleanRoomTaskRunResultState_Disabled CleanRoomTaskRunResultState_CleanRoomTaskRunResultState = "DISABLED" +) + +// Hardware accelerator type for the AiRuntime workload. Per-node accelerator +// count is encoded in the value name (e.g. `GPU_8xH100` means 8 H100s per +// node). +type ComputeSpec_AcceleratorType string + +const ( + ComputeSpec_AcceleratorType_Unspecified ComputeSpec_AcceleratorType = "" + // Single A10 GPU per node. Good for development and small workloads. + ComputeSpec_AcceleratorType_Gpu1xA10 ComputeSpec_AcceleratorType = "GPU_1xA10" + // Single H100 GPU per node. + ComputeSpec_AcceleratorType_Gpu1xH100 ComputeSpec_AcceleratorType = "GPU_1xH100" + // Eight H100 GPUs per node. Typical for distributed training. + ComputeSpec_AcceleratorType_Gpu8xH100 ComputeSpec_AcceleratorType = "GPU_8xH100" +) + +// * `EQUAL_TO`, `NOT_EQUAL` operators perform string comparison of their +// operands. This means that `“12.0” == “12”` will evaluate to `false`. +// * `GREATER_THAN`, `GREATER_THAN_OR_EQUAL`, `LESS_THAN`, `LESS_THAN_OR_EQUAL` +// operators perform numeric comparison of their operands. `“12.0” >= +// “12”` will evaluate to `true`, `“10.0” >= “12”` will evaluate to +// `false`. +// +// The boolean comparison to task values can be implemented with operators +// `EQUAL_TO`, `NOT_EQUAL`. If a task value was set to a boolean value, it will +// be serialized to `“true”` or `“false”` for the comparison. +type ConditionTask_ConditionTaskOperator string + +const ( + ConditionTask_ConditionTaskOperator_Unspecified ConditionTask_ConditionTaskOperator = "" + ConditionTask_ConditionTaskOperator_EqualTo ConditionTask_ConditionTaskOperator = "EQUAL_TO" + ConditionTask_ConditionTaskOperator_GreaterThan ConditionTask_ConditionTaskOperator = "GREATER_THAN" + ConditionTask_ConditionTaskOperator_GreaterThanOrEqual ConditionTask_ConditionTaskOperator = "GREATER_THAN_OR_EQUAL" + ConditionTask_ConditionTaskOperator_LessThan ConditionTask_ConditionTaskOperator = "LESS_THAN" + ConditionTask_ConditionTaskOperator_LessThanOrEqual ConditionTask_ConditionTaskOperator = "LESS_THAN_OR_EQUAL" + ConditionTask_ConditionTaskOperator_NotEqual ConditionTask_ConditionTaskOperator = "NOT_EQUAL" +) + +// * `BUNDLE`: The job is managed by Databricks Asset Bundle. * +// `SYSTEM_MANAGED`: The job is managed by and is read-only. +type JobDeployment_DeploymentKind string + +const ( + JobDeployment_DeploymentKind_Unspecified JobDeployment_DeploymentKind = "" + JobDeployment_DeploymentKind_Bundle JobDeployment_DeploymentKind = "BUNDLE" + JobDeployment_DeploymentKind_SystemManaged JobDeployment_DeploymentKind = "SYSTEM_MANAGED" +) + +// Dirty state indicates the job is not fully synced with the job specification +// in the remote repository. +// +// Possible values are: * `NOT_SYNCED`: The job is not yet synced with the +// remote job specification. Import the remote job specification from UI to make +// the job fully synced. * `DISCONNECTED`: The job is temporary disconnected +// from the remote job specification and is allowed for live edit. Import the +// remote job specification again from UI to make the job fully synced. +type JobSource_DirtyState string + +const ( + JobSource_DirtyState_Unspecified JobSource_DirtyState = "" + JobSource_DirtyState_NotSynced JobSource_DirtyState = "NOT_SYNCED" + JobSource_DirtyState_Disconnected JobSource_DirtyState = "DISCONNECTED" +) + +type ModelTriggerConfiguration_ModelTriggerCondition string + +const ( + ModelTriggerConfiguration_ModelTriggerCondition_Unspecified ModelTriggerConfiguration_ModelTriggerCondition = "" + ModelTriggerConfiguration_ModelTriggerCondition_ModelCreated ModelTriggerConfiguration_ModelTriggerCondition = "MODEL_CREATED" + ModelTriggerConfiguration_ModelTriggerCondition_ModelVersionReady ModelTriggerConfiguration_ModelTriggerCondition = "MODEL_VERSION_READY" + ModelTriggerConfiguration_ModelTriggerCondition_ModelAliasSet ModelTriggerConfiguration_ModelTriggerCondition = "MODEL_ALIAS_SET" +) + +// PerformanceTarget defines how performant (lower latency) or cost efficient +// the execution of run on serverless compute should be. The performance mode on +// the job or pipeline should map to a performance setting that is passed to +// Cluster Manager (see cluster-common PerformanceTarget). +type PerformanceTarget_PerformanceTarget string + +const ( + PerformanceTarget_PerformanceTarget_Unspecified PerformanceTarget_PerformanceTarget = "" + PerformanceTarget_PerformanceTarget_PerformanceOptimized PerformanceTarget_PerformanceTarget = "PERFORMANCE_OPTIMIZED" + PerformanceTarget_PerformanceTarget_Standard PerformanceTarget_PerformanceTarget = "STANDARD" +) + +type PeriodicTriggerConfiguration_TimeUnit string + +const ( + PeriodicTriggerConfiguration_TimeUnit_Unspecified PeriodicTriggerConfiguration_TimeUnit = "" + PeriodicTriggerConfiguration_TimeUnit_Hours PeriodicTriggerConfiguration_TimeUnit = "HOURS" + PeriodicTriggerConfiguration_TimeUnit_Days PeriodicTriggerConfiguration_TimeUnit = "DAYS" + PeriodicTriggerConfiguration_TimeUnit_Weeks PeriodicTriggerConfiguration_TimeUnit = "WEEKS" + // Run the job every N minutes. + PeriodicTriggerConfiguration_TimeUnit_Minutes PeriodicTriggerConfiguration_TimeUnit = "MINUTES" +) + +// The reason for queuing the run. * `ACTIVE_RUNS_LIMIT_REACHED`: The run was +// queued due to reaching the workspace limit of active task runs. * +// `MAX_CONCURRENT_RUNS_REACHED`: The run was queued due to reaching the per-job +// limit of concurrent job runs. * `ACTIVE_RUN_JOB_TASKS_LIMIT_REACHED`: The run +// was queued due to reaching the workspace limit of active run job tasks. +type QueueDetailsCode_Code string + +const ( + QueueDetailsCode_Code_Unspecified QueueDetailsCode_Code = "" + QueueDetailsCode_Code_ActiveRunsLimitReached QueueDetailsCode_Code = "ACTIVE_RUNS_LIMIT_REACHED" + QueueDetailsCode_Code_MaxConcurrentRunsReached QueueDetailsCode_Code = "MAX_CONCURRENT_RUNS_REACHED" + QueueDetailsCode_Code_ActiveRunJobTasksLimitReached QueueDetailsCode_Code = "ACTIVE_RUN_JOB_TASKS_LIMIT_REACHED" +) + +// A value indicating the run's lifecycle state. The possible values are: * +// `QUEUED`: The run is queued. * `PENDING`: The run is waiting to be executed +// while the cluster and execution context are being prepared. * `RUNNING`: The +// task of this run is being executed. * `TERMINATING`: The task of this run has +// completed, and the cluster and execution context are being cleaned up. * +// `TERMINATED`: The task of this run has completed, and the cluster and +// execution context have been cleaned up. This state is terminal. * `SKIPPED`: +// This run was aborted because a previous run of the same job was already +// active. This state is terminal. * `INTERNAL_ERROR`: An exceptional state that +// indicates a failure in the Jobs service, such as network failure over a long +// period. If a run on a new cluster ends in the `INTERNAL_ERROR` state, the +// Jobs service terminates the cluster as soon as possible. This state is +// terminal. * `BLOCKED`: The run is blocked on an upstream dependency. * +// `WAITING_FOR_RETRY`: The run is waiting for a retry. +type RunLifeCycleState_RunLifeCycleState string + +const ( + RunLifeCycleState_RunLifeCycleState_Unspecified RunLifeCycleState_RunLifeCycleState = "" + RunLifeCycleState_RunLifeCycleState_Pending RunLifeCycleState_RunLifeCycleState = "PENDING" + RunLifeCycleState_RunLifeCycleState_Running RunLifeCycleState_RunLifeCycleState = "RUNNING" + RunLifeCycleState_RunLifeCycleState_Terminating RunLifeCycleState_RunLifeCycleState = "TERMINATING" + RunLifeCycleState_RunLifeCycleState_Terminated RunLifeCycleState_RunLifeCycleState = "TERMINATED" + RunLifeCycleState_RunLifeCycleState_Skipped RunLifeCycleState_RunLifeCycleState = "SKIPPED" + RunLifeCycleState_RunLifeCycleState_InternalError RunLifeCycleState_RunLifeCycleState = "INTERNAL_ERROR" + RunLifeCycleState_RunLifeCycleState_Blocked RunLifeCycleState_RunLifeCycleState = "BLOCKED" + RunLifeCycleState_RunLifeCycleState_WaitingForRetry RunLifeCycleState_RunLifeCycleState = "WAITING_FOR_RETRY" + RunLifeCycleState_RunLifeCycleState_Queued RunLifeCycleState_RunLifeCycleState = "QUEUED" +) + +// The current state of the run. +type RunLifecycleStateV2_State string + +const ( + RunLifecycleStateV2_State_Unspecified RunLifecycleStateV2_State = "" + RunLifecycleStateV2_State_Blocked RunLifecycleStateV2_State = "BLOCKED" + RunLifecycleStateV2_State_Pending RunLifecycleStateV2_State = "PENDING" + RunLifecycleStateV2_State_Queued RunLifecycleStateV2_State = "QUEUED" + RunLifecycleStateV2_State_Running RunLifecycleStateV2_State = "RUNNING" + RunLifecycleStateV2_State_Terminating RunLifecycleStateV2_State = "TERMINATING" + RunLifecycleStateV2_State_Terminated RunLifecycleStateV2_State = "TERMINATED" + // Runs in the Waiting state (e.g. cost-optimized runs) are intentionally + // delayed until an optimal compute scheduling time + RunLifecycleStateV2_State_Waiting RunLifecycleStateV2_State = "WAITING" +) + +// A value indicating the run's result. The possible values are: * `SUCCESS`: +// The task completed successfully. * `FAILED`: The task completed with an +// error. * `TIMEDOUT`: The run was stopped after reaching the timeout. * +// `CANCELED`: The run was canceled at user request. * +// `MAXIMUM_CONCURRENT_RUNS_REACHED`: The run was skipped because the maximum +// concurrent runs were reached. * `EXCLUDED`: The run was skipped because the +// necessary conditions were not met. * `SUCCESS_WITH_FAILURES`: The job run +// completed successfully with some failures; leaf tasks were successful. * +// `UPSTREAM_FAILED`: The run was skipped because of an upstream failure. * +// `UPSTREAM_CANCELED`: The run was skipped because an upstream task was +// canceled. * `DISABLED`: The run was skipped because it was disabled +// explicitly by the user. +type RunResultState_RunResultState string + +const ( + RunResultState_RunResultState_Unspecified RunResultState_RunResultState = "" + RunResultState_RunResultState_Success RunResultState_RunResultState = "SUCCESS" + RunResultState_RunResultState_Failed RunResultState_RunResultState = "FAILED" + RunResultState_RunResultState_Timedout RunResultState_RunResultState = "TIMEDOUT" + RunResultState_RunResultState_Canceled RunResultState_RunResultState = "CANCELED" + RunResultState_RunResultState_MaximumConcurrentRunsReached RunResultState_RunResultState = "MAXIMUM_CONCURRENT_RUNS_REACHED" + RunResultState_RunResultState_UpstreamCanceled RunResultState_RunResultState = "UPSTREAM_CANCELED" + RunResultState_RunResultState_UpstreamFailed RunResultState_RunResultState = "UPSTREAM_FAILED" + RunResultState_RunResultState_Excluded RunResultState_RunResultState = "EXCLUDED" + RunResultState_RunResultState_SuccessWithFailures RunResultState_RunResultState = "SUCCESS_WITH_FAILURES" + RunResultState_RunResultState_Disabled RunResultState_RunResultState = "DISABLED" +) + +// The state of the SQL alert. +// +// * UNKNOWN: alert yet to be evaluated * OK: alert evaluated and did not +// fulfill trigger conditions * TRIGGERED: alert evaluated and fulfilled trigger +// conditions +type SqlAlertState_SqlAlertState string + +const ( + SqlAlertState_SqlAlertState_Unspecified SqlAlertState_SqlAlertState = "" + SqlAlertState_SqlAlertState_Unknown SqlAlertState_SqlAlertState = "UNKNOWN" + SqlAlertState_SqlAlertState_Ok SqlAlertState_SqlAlertState = "OK" + SqlAlertState_SqlAlertState_Triggered SqlAlertState_SqlAlertState = "TRIGGERED" +) + +type SqlTask_SqlTaskQueryStatus string + +const ( + SqlTask_SqlTaskQueryStatus_Unspecified SqlTask_SqlTaskQueryStatus = "" + SqlTask_SqlTaskQueryStatus_Pending SqlTask_SqlTaskQueryStatus = "PENDING" + SqlTask_SqlTaskQueryStatus_Running SqlTask_SqlTaskQueryStatus = "RUNNING" + SqlTask_SqlTaskQueryStatus_Success SqlTask_SqlTaskQueryStatus = "SUCCESS" + SqlTask_SqlTaskQueryStatus_Failed SqlTask_SqlTaskQueryStatus = "FAILED" + SqlTask_SqlTaskQueryStatus_Cancelled SqlTask_SqlTaskQueryStatus = "CANCELLED" +) + +type TableTriggerConfiguration_Condition string + +const ( + TableTriggerConfiguration_Condition_Unspecified TableTriggerConfiguration_Condition = "" + TableTriggerConfiguration_Condition_AnyUpdated TableTriggerConfiguration_Condition = "ANY_UPDATED" + TableTriggerConfiguration_Condition_AllUpdated TableTriggerConfiguration_Condition = "ALL_UPDATED" +) + +// The code indicates why the run was terminated. Additional codes might be +// introduced in future releases. * `SUCCESS`: The run was completed +// successfully. * `SUCCESS_WITH_FAILURES`: The run was completed successfully +// but some child runs failed. * `USER_CANCELED`: The run was successfully +// canceled during execution by a user. * `CANCELED`: The run was canceled +// during execution by the platform; for example, if the maximum +// run duration was exceeded. * `SKIPPED`: Run was never executed, for example, +// if the upstream task run failed, the dependency type condition was not met, +// or there were no material tasks to execute. * `INTERNAL_ERROR`: The run +// encountered an unexpected error. Refer to the state message for further +// details. * `DRIVER_ERROR`: The run encountered an error while communicating +// with the Spark Driver. * `CLUSTER_ERROR`: The run failed due to a cluster +// error. Refer to the state message for further details. * +// `REPOSITORY_CHECKOUT_FAILED`: Failed to complete the checkout due to an error +// when communicating with the third party service. * `INVALID_CLUSTER_REQUEST`: +// The run failed because it issued an invalid request to start the cluster. * +// `WORKSPACE_RUN_LIMIT_EXCEEDED`: The workspace has reached the quota for the +// maximum number of concurrent active runs. Consider scheduling the runs over a +// larger time frame. * `FEATURE_DISABLED`: The run failed because it tried to +// access a feature unavailable for the workspace. * +// `CLUSTER_REQUEST_LIMIT_EXCEEDED`: The number of cluster creation, start, and +// upsize requests have exceeded the allotted rate limit. Consider spreading the +// run execution over a larger time frame. * `STORAGE_ACCESS_ERROR`: The run +// failed due to an error when accessing the customer blob storage. Refer to the +// state message for further details. * `RUN_EXECUTION_ERROR`: The run was +// completed with task failures. For more details, refer to the state message or +// run output. * `UNAUTHORIZED_ERROR`: The run failed due to a permission issue +// while accessing a resource. Refer to the state message for further details. * +// `LIBRARY_INSTALLATION_ERROR`: The run failed while installing the +// user-requested library. Refer to the state message for further details. The +// causes might include, but are not limited to: The provided library is +// invalid, there are insufficient permissions to install the library, and so +// forth. * `MAX_CONCURRENT_RUNS_EXCEEDED`: The scheduled run exceeds the limit +// of maximum concurrent runs set for the job. * `MAX_SPARK_CONTEXTS_EXCEEDED`: +// The run is scheduled on a cluster that has already reached the maximum number +// of contexts it is configured to create. See: [Link]. * `RESOURCE_NOT_FOUND`: +// A resource necessary for run execution does not exist. Refer to the state +// message for further details. * `INVALID_RUN_CONFIGURATION`: The run failed +// due to an invalid configuration. Refer to the state message for further +// details. * `CLOUD_FAILURE`: The run failed due to a cloud provider issue. +// Refer to the state message for further details. * +// `MAX_JOB_QUEUE_SIZE_EXCEEDED`: The run was skipped due to reaching the job +// level queue size limit. * `DISABLED`: The run was never executed because it +// was disabled explicitly by the user. * `BREAKING_CHANGE`: Run failed because +// of an intentional breaking change in Spark, but it will be retried with a +// mitigation config. * `CLUSTER_TERMINATED_BY_USER`: The run failed because the +// externally managed cluster entered an unusable state, likely due to the user +// terminating or restarting it outside the jobs service. +// +// [Link]: https://kb.databricks.com/en_US/notebooks/too-many-execution-contexts-are-open-right-now +type TerminationCode_Code string + +const ( + TerminationCode_Code_Unspecified TerminationCode_Code = "" + TerminationCode_Code_Success TerminationCode_Code = "SUCCESS" + TerminationCode_Code_Canceled TerminationCode_Code = "CANCELED" + // DriverError represents failures when the driver restarted, or became + // unhealthy or unreachable during the run. + TerminationCode_Code_DriverError TerminationCode_Code = "DRIVER_ERROR" + // ClusterError represents failures due to cluster issues. These include the + // failures that occur during creation of a new cluster / starting up an + // existing cluster, cluster issues and timeouts during the job run + TerminationCode_Code_ClusterError TerminationCode_Code = "CLUSTER_ERROR" + // Returned if [[ProjectCheckoutInternalRepo]] RPC fails + TerminationCode_Code_RepositoryCheckoutFailed TerminationCode_Code = "REPOSITORY_CHECKOUT_FAILED" + // * InvalidClusterRequest represents failures when the user provides invalid + // input for a cluster configuration for the run. For example, providing invalid + // parameter Values in the request/ providing a bad request etc + TerminationCode_Code_InvalidClusterRequest TerminationCode_Code = "INVALID_CLUSTER_REQUEST" + // * Returned if an org set a limit for number of their concurrent active runs + // and the run couldn't start because it would exceed this limit. TODO: + // JOBS-12528: The original comment (on the issue) does not seem to reflect how + // this is actually used in code It should be looked into how we're handling the + // scenario where a given job exceeds its own internal concurrency limits. + TerminationCode_Code_WorkspaceRunLimitExceeded TerminationCode_Code = "WORKSPACE_RUN_LIMIT_EXCEEDED" + TerminationCode_Code_FeatureDisabled TerminationCode_Code = "FEATURE_DISABLED" + // * ClusterRequestLimitExceeded represents failures when cluster creation, + // start, and upsize requests for a workspace exceeded the rate limit of + // [[com.databricks.backend.cluster.ClusterSizeConf.upsizeRefillRatePerMinPerOrg]] + // nodes per min. + TerminationCode_Code_ClusterRequestLimitExceeded TerminationCode_Code = "CLUSTER_REQUEST_LIMIT_EXCEEDED" + // * StorageAccessError represents failures when the access to user's + // file system fails. For example, misconfiguration on user's side + // like deleting AWS S3 bucket without cancelling the workspace, their Azure + // account being disabled, the storage buckets not being found etc. + TerminationCode_Code_StorageAccessError TerminationCode_Code = "STORAGE_ACCESS_ERROR" + TerminationCode_Code_RunExecutionError TerminationCode_Code = "RUN_EXECUTION_ERROR" + TerminationCode_Code_UnauthorizedError TerminationCode_Code = "UNAUTHORIZED_ERROR" + // * LibraryInstallationError represents failures due to issues related library + // installation. These include the failures that occur when the user provided + // invalid library or user not having enough permissions to install the library + // or any cloud dependency/ infrastructure failures during library installation + // etc + TerminationCode_Code_LibraryInstallationError TerminationCode_Code = "LIBRARY_INSTALLATION_ERROR" + TerminationCode_Code_MaxConcurrentRunsExceeded TerminationCode_Code = "MAX_CONCURRENT_RUNS_EXCEEDED" + TerminationCode_Code_MaxSparkContextsExceeded TerminationCode_Code = "MAX_SPARK_CONTEXTS_EXCEEDED" + TerminationCode_Code_ResourceNotFound TerminationCode_Code = "RESOURCE_NOT_FOUND" + TerminationCode_Code_InvalidRunConfiguration TerminationCode_Code = "INVALID_RUN_CONFIGURATION" + TerminationCode_Code_InternalError TerminationCode_Code = "INTERNAL_ERROR" + TerminationCode_Code_CloudFailure TerminationCode_Code = "CLOUD_FAILURE" + TerminationCode_Code_MaxJobQueueSizeExceeded TerminationCode_Code = "MAX_JOB_QUEUE_SIZE_EXCEEDED" + TerminationCode_Code_Skipped TerminationCode_Code = "SKIPPED" + TerminationCode_Code_UserCanceled TerminationCode_Code = "USER_CANCELED" + TerminationCode_Code_BudgetPolicyLimitExceeded TerminationCode_Code = "BUDGET_POLICY_LIMIT_EXCEEDED" + TerminationCode_Code_Disabled TerminationCode_Code = "DISABLED" + // SuccessWithFailures represents that some child runs failed but the run was + // ultimately successful. + TerminationCode_Code_SuccessWithFailures TerminationCode_Code = "SUCCESS_WITH_FAILURES" + // Run failed because of an intentional breaking change in Spark, but it will be + // retried with a mitigation config. + TerminationCode_Code_BreakingChange TerminationCode_Code = "BREAKING_CHANGE" +) + +// * `SUCCESS`: The run terminated without any issues * `INTERNAL_ERROR`: An +// error occurred in the platform. Please look at the [status page] +// or contact support if the issue persists. * `CLIENT_ERROR`: The run was +// terminated because of an error caused by user input or the job configuration. +// * `CLOUD_FAILURE`: The run was terminated because of an issue with your cloud +// provider. +// +// [status page]: https://status.databricks.com/ +type TerminationType_Type string + +const ( + TerminationType_Type_Unspecified TerminationType_Type = "" + TerminationType_Type_Success TerminationType_Type = "SUCCESS" + TerminationType_Type_InternalError TerminationType_Type = "INTERNAL_ERROR" + TerminationType_Type_ClientError TerminationType_Type = "CLIENT_ERROR" + TerminationType_Type_CloudFailure TerminationType_Type = "CLOUD_FAILURE" +) + +type AccessControlRequest struct { + PrincipalName isAccessControlRequest_PrincipalName + PermissionLevel AccessControlRequest_JobPermission +} + +type isAccessControlRequest_PrincipalName interface { + isAccessControlRequest_PrincipalName() +} + +// AccessControlRequest_PrincipalName_UserName selects UserName for AccessControlRequest.PrincipalName. +type AccessControlRequest_PrincipalName_UserName struct { + UserName string +} + +func (*AccessControlRequest_PrincipalName_UserName) isAccessControlRequest_PrincipalName() {} + +// AccessControlRequest_PrincipalName_GroupName selects GroupName for AccessControlRequest.PrincipalName. +type AccessControlRequest_PrincipalName_GroupName struct { + GroupName string +} + +func (*AccessControlRequest_PrincipalName_GroupName) isAccessControlRequest_PrincipalName() {} + +// AccessControlRequest_PrincipalName_ServicePrincipalName selects ServicePrincipalName for AccessControlRequest.PrincipalName. +type AccessControlRequest_PrincipalName_ServicePrincipalName struct { + ServicePrincipalName string +} + +func (*AccessControlRequest_PrincipalName_ServicePrincipalName) isAccessControlRequest_PrincipalName() { +} + +// A storage location in Adls Gen2. +type Adlsgen2Info struct { + // abfss destination, e.g. + // `abfss://@.dfs.core.windows.net/`. + Destination *string +} + +// AiRuntimeTask: multi-node GPU compute task definition for Databricks AI +// Runtime workloads. +// +// Jobs-framework-level concepts (retries, per-task timeout, idempotency token, +// usage/budget policy, permissions) live on the surrounding TaskSettings / +// run-submit request and are intentionally NOT duplicated here. Users compose +// `ai_runtime_task` with the standard Jobs/DABs task wrapper to get those.. +type AiRuntimeTask struct { + // MLflow experiment name for this run. If an experiment with this name already + // exists under the calling user, the run is appended to it; otherwise a new + // experiment is created. To target a specific MLflow storage location (for + // example, when running as a service principal), set + // `mlflow_experiment_directory`. + Experiment *string + // Deployment specs for this task. Exactly one deployment is currently supported + // (a single entry where every node runs the same command); this is a + // current-Preview constraint. Role-split workloads (driver + worker, parameter + // server, separate eval node, etc.) with multiple entries are the eventual + // intent but not yet supported. + Deployments []DeploymentSpec + // Workspace or UC volume path of the code-source archive, unpacked on each node + // and exposed through `$CODE_SOURCE`. Set by first-party tooling; not for + // direct callers. + CodeSourcePath *string + // Optional display name for the MLflow run created under `experiment`. If + // omitted, MLflow generates a default name. + MlflowRun *string + // Optional workspace directory under which the MLflow experiment named in + // `experiment` is created. Must start with `/Workspace`. Set this when running + // as a service principal that has no default user directory; for regular users + // the experiment defaults to the user's home directory. + MlflowExperimentDirectory *string + // Optional Docker image URL for a custom container image. When set, the task + // runs on the specified container image instead of the default + // client image. Format: `{organization}/{repository}:{tag}` + DockerImageUrl *string + // Optional root location for MLflow artifacts logged by the run. If this field + // isn't specified the default artifact location will be in dbfs i.e. + // `dbfs:/databricks/mlflow-tracking//...` If dbfs access is + // restricted or UC is preferred this can be a custom location in UC: + // `dbfs:/Volumes////...` The location should be unique + // for each experiment. + MlflowArtifactLocation *string +} + +// AiRuntimeTaskOutput: output identifiers for an AiRuntimeTask run — the +// MLflow experiment and run IDs the task wrote to. +// +// Run lifecycle and termination status are not on this message; they live on +// the surrounding `RunTask.status` field (see `runs.proto:RunTask.status`).. +type AiRuntimeTaskOutput struct { + // MLflow experiment ID the run was logged to. Use it to look up the experiment + // in MLflow APIs or the workspace MLflow UI. + MlflowExperimentId *string + // MLflow run ID for this task execution. Use it to look up the run in MLflow + // APIs or the workspace MLflow UI. + MlflowRunId *string + // Human-readable status message for this run, suitable for display to the user + // (for example, that the run is still waiting for GPU compute). Set by the + // server only when there is something to surface; empty otherwise. + StatusMessage *string +} + +type AlertEvaluationState struct { +} + +type AlertTask struct { + // The alert_id is the canonical identifier of the alert. + AlertId *string + // The warehouse_id identifies the warehouse settings used by the alert task. + WarehouseId *string + // The workspace_path is the path to the alert file in the workspace. The path: + // * must start with "/Workspace" * must be a normalized path. User has to + // select only one of alert_id or workspace_path to identify the alert. + WorkspacePath *string + // The subscribers receive alert evaluation result notifications after the alert + // task is completed. The number of subscriptions is limited to 100. + Subscribers []AlertTaskSubscriber +} + +type AlertTaskOutput struct { + AlertState AlertEvaluationState_AlertEvaluationState +} + +// Represents a subscriber that will receive alert notifications. A subscriber +// can be either a user (via email) or a notification destination (via +// destination_id).. +type AlertTaskSubscriber struct { + SubscriberType isAlertTaskSubscriber_SubscriberType +} + +type isAlertTaskSubscriber_SubscriberType interface { + isAlertTaskSubscriber_SubscriberType() +} + +// AlertTaskSubscriber_SubscriberType_UserName selects UserName for AlertTaskSubscriber.SubscriberType. +// A valid workspace email address. +type AlertTaskSubscriber_SubscriberType_UserName struct { + UserName string +} + +func (*AlertTaskSubscriber_SubscriberType_UserName) isAlertTaskSubscriber_SubscriberType() {} + +// AlertTaskSubscriber_SubscriberType_DestinationId selects DestinationId for AlertTaskSubscriber.SubscriberType. +type AlertTaskSubscriber_SubscriberType_DestinationId struct { + DestinationId string +} + +func (*AlertTaskSubscriber_SubscriberType_DestinationId) isAlertTaskSubscriber_SubscriberType() {} + +type AutoScale struct { + // The minimum number of workers to which the cluster can scale down when + // underutilized. It is also the initial number of workers the cluster will have + // after creation. + MinWorkers *int + // The maximum number of workers to which the cluster can scale up when + // overloaded. Note that `max_workers` must be strictly greater than + // `min_workers`. + MaxWorkers *int +} + +// Attributes set during cluster creation which are related to Amazon Web +// Services.. +type AwsAttributes struct { + // The first `first_on_demand` nodes of the cluster will be placed on on-demand + // instances. If this value is greater than 0, the cluster driver node in + // particular will be placed on an on-demand instance. If this value is greater + // than or equal to the current cluster size, all nodes will be placed on + // on-demand instances. If this value is less than the current cluster size, + // `first_on_demand` nodes will be placed on on-demand instances and the + // remainder will be placed on `availability` instances. Note that this value + // does not affect cluster size and cannot currently be mutated over the + // lifetime of a cluster. + FirstOnDemand *int + Availability AwsAvailability + // Identifier for the availability zone/datacenter in which the cluster resides. + // This string will be of a form like "us-west-2a". The provided availability + // zone must be in the same region as the deployment. For example, + // "us-west-2a" is not a valid zone id if the deployment resides in + // the "us-east-1" region. This is an optional field at cluster creation, and if + // not specified, the zone "auto" will be used. If the zone specified is "auto", + // will try to place cluster in a zone with high availability, and will retry + // placement in a different AZ if there is not enough capacity. The list of + // available zones as well as the default value can be found by using the `List + // Zones` method. + ZoneId *string + // Nodes for this cluster will only be placed on AWS instances with this + // instance profile. If ommitted, nodes will be placed on instances without an + // IAM instance profile. The instance profile must have previously been added to + // the environment by an account administrator. + // + // This feature may only be available to certain customer plans. + InstanceProfileArn *string + // The bid price for AWS spot instances, as a percentage of the corresponding + // instance type's on-demand price. For example, if this field is set to 50, and + // the cluster needs a new `r3.xlarge` spot instance, then the bid price is half + // of the price of on-demand `r3.xlarge` instances. Similarly, if this field is + // set to 200, the bid price is twice the price of on-demand `r3.xlarge` + // instances. If not specified, the default value is 100. When spot instances + // are requested for this cluster, only spot instances whose bid price + // percentage matches this field will be considered. Note that, for safety, we + // enforce this field to be no more than 10000. + SpotBidPricePercent *int + // The type of EBS volumes that will be launched with this cluster. + EbsVolumeType EbsVolumeType + // The number of volumes launched for each instance. Users can choose up to 10 + // volumes. This feature is only enabled for supported node types. Legacy node + // types cannot specify custom EBS volumes. For node types with no instance + // store, at least one EBS volume needs to be specified; otherwise, cluster + // creation will fail. + // + // These EBS volumes will be mounted at `/ebs0`, `/ebs1`, and etc. Instance + // store volumes will be mounted at `/local_disk0`, `/local_disk1`, and etc. + // + // If EBS volumes are attached, will configure Spark to use only + // the EBS volumes for scratch storage because heterogenously sized scratch + // devices can lead to inefficient disk utilization. If no EBS volumes are + // attached, will configure Spark to use instance store volumes. + // + // Please note that if EBS volumes are specified, then the Spark configuration + // `spark.local.dir` will be overridden. + EbsVolumeCount *int + // The size of each EBS volume (in GiB) launched for each instance. For general + // purpose SSD, this value must be within the range 100 - 4096. For throughput + // optimized HDD, this value must be within the range 500 - 4096. + EbsVolumeSize *int + // If using gp3 volumes, what IOPS to use for the disk. If this is not set, the + // maximum performance of a gp2 volume with the same volume size will be used. + EbsVolumeIops *int + // If using gp3 volumes, what throughput to use for the disk. If this is not + // set, the maximum performance of a gp2 volume with the same volume size will + // be used. + EbsVolumeThroughput *int +} + +// Attributes set during cluster creation which are related to Microsoft Azure.. +type AzureAttributes struct { + // Defines values necessary to configure and run Azure Log Analytics agent + LogAnalyticsInfo *LogAnalyticsInfo + // The first `first_on_demand` nodes of the cluster will be placed on on-demand + // instances. This value should be greater than 0, to make sure the cluster + // driver node is placed on an on-demand instance. If this value is greater than + // or equal to the current cluster size, all nodes will be placed on on-demand + // instances. If this value is less than the current cluster size, + // `first_on_demand` nodes will be placed on on-demand instances and the + // remainder will be placed on `availability` instances. Note that this value + // does not affect cluster size and cannot currently be mutated over the + // lifetime of a cluster. + FirstOnDemand *int + // Availability type used for all subsequent nodes past the `first_on_demand` + // ones. Note: If `first_on_demand` is zero, this availability type will be used + // for the entire cluster. + Availability AzureAvailability + // The max bid price to be used for Azure spot instances. The Max price for the + // bid cannot be higher than the on-demand price of the instance. If not + // specified, the default value is -1, which specifies that the instance cannot + // be evicted on the basis of price, and only on the basis of availability. + // Further, the value should > 0 or -1. + SpotBidMaxPrice *float64 + // The Azure capacity reservation group resource ID to use for launching VMs. + // When specified, VMs will be launched using the provided capacity reservation. + // + // Capacity reservations can only be specified when the workspace uses injected + // vnet (i.e. customer defined vnet not managed by databricks). Ensure the + // databricks-login-prod Enterprise Application is granted the following four + // permissions: 1. Microsoft.Compute/capacityReservationGroups/read 2. + // Microsoft.Compute/capacityReservationGroups/deploy/action 3. + // Microsoft.Compute/capacityReservationGroups/capacityReservations/read 4. + // Microsoft.Compute/capacityReservationGroups/capacityReservations/deploy/action + // + // Format: + // `/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/capacityReservationGroups/{capacityReservationGroupName}` + CapacityReservationGroup *string +} + +type BaseJob struct { + // The canonical identifier for this job. + JobId *int64 + // The creator user name. This field won’t be included in the response if the + // user has already been deleted. + CreatorUserName *string + // The email of an active workspace user or the application ID of a service + // principal that the job runs as. This value can be changed by setting the + // `run_as` field when creating or updating a job. + // + // By default, `run_as_user_name` is based on the current job settings and is + // set to the creator of the job if job access control is disabled or to the + // user with the `is_owner` permission if job access control is enabled. + RunAsUserName *string + // Settings for this job and all of its runs. These settings can be updated + // using the `resetJob` method. + Settings *JobSettings + // The time at which this job was created in epoch milliseconds (milliseconds + // since 1/1/1970 UTC). + CreatedTime *int64 + // State of the trigger associated with the job. + TriggerState *TriggerState + // Indicates if the job has more array properties (`tasks`, `job_clusters`) that + // are not shown. They can be accessed via :method:jobs/get endpoint. It is only + // relevant for API 2.2 :method:jobs/list requests with `expand_tasks=true`. + HasMore *bool + // The id of the budget policy used by this job for cost attribution purposes. + // This may be set through (in order of precedence): 1. Budget admins through + // the account or workspace console 2. Jobs UI in the job details page and Jobs + // API using `budget_policy_id` 3. Inferred default based on accessible budget + // policies of the run_as identity on job creation or modification. + EffectiveBudgetPolicyId *string + // The id of the usage policy used by this job for cost attribution purposes. + EffectiveUsagePolicyId *string + // Per-trigger runtime information for the multi-trigger surface. Same length + // and order as `JobSettings.triggers`; `trigger_details[i]` corresponds to + // `triggers[i]`. Sub-fields (`state`, `history`) are populated independently + // based on the `GetJob.include_trigger_state` / `include_trigger_history` + // flags. + TriggerDetails []TriggerDetails +} + +type BaseRun struct { + // The canonical identifier of the job that contains this run. + JobId *int64 + // The canonical identifier of the run. This ID is unique across all runs of all + // jobs. + RunId *int64 + // The creator user name. This field won’t be included in the response if the + // user has already been deleted. + CreatorUserName *string + // A unique identifier for this job run. This is set to the same value as + // `run_id`. + NumberInJob *int64 + // If this run is a retry of a prior run attempt, this field contains the run_id + // of the original attempt; otherwise, it is the same as the run_id. + OriginalAttemptRunId *int64 + // Deprecated. Please use the `status` field instead. + State *RunState + // The cron schedule that triggered this run if it was triggered by the periodic + // scheduler. + Schedule *CronSchedule + // A snapshot of the job’s cluster specification when this run was created. + ClusterSpec *ClusterSpec + // The cluster used for this run. If the run is specified to use a new cluster, + // this field is set once the Jobs service has requested a cluster for the run. + ClusterInstance *ClusterInstance + // Job-level parameters used in the run + JobParameters []Run_JobLevelParameters + // The parameters used for this run. + OverridingParameters *RunParameters + Trigger TriggerType + TriggerInfo *RunTriggerInfo + // An optional name for the run. The maximum length is 4096 bytes in UTF-8 + // encoding. + RunName *string + // The URL to the detail page of the run. + RunPageUrl *string + RunType RunType + // The list of tasks performed by the run. Each task has its own `run_id` which + // you can use to call `JobsGetOutput` to retrieve the run results. If more than + // 100 tasks are available, you can paginate through them using + // :method:jobs/getrun. Use the `next_page_token` field at the object root to + // determine if more results are available. + Tasks []RunTask + // Description of the run + Description *string + // The sequence number of this run attempt for a triggered job run. The initial + // attempt of a run has an attempt_number of 0. If the initial run attempt + // fails, and the job has a retry policy (`max_retries` > 0), subsequent runs + // are created with an `original_attempt_run_id` of the original attempt’s ID + // and an incrementing `attempt_number`. Runs are retried only until they + // succeed, and the maximum `attempt_number` is the same as the `max_retries` + // value for the job. + AttemptNumber *int + // A list of job cluster specifications that can be shared and reused by tasks + // of this job. Libraries cannot be declared in a shared job cluster. You must + // declare dependent libraries in task settings. If more than 100 job clusters + // are available, you can paginate through them using :method:jobs/getrun. + JobClusters []JobCluster + // An optional specification for a remote Git repository containing the source + // code used by tasks. Version-controlled source code is supported by notebook, + // dbt, Python script, and SQL File tasks. + // + // If `git_source` is set, these tasks retrieve the file from the remote + // repository by default. However, this behavior can be overridden by setting + // `source` to `WORKSPACE` on the task. + // + // Note: dbt and SQL File tasks support only version-controlled sources. If dbt + // or SQL File tasks are used, `git_source` must be defined on the job. + GitSource *GitSource + // The repair history of the run. + RepairHistory []Repair + Status *RunStatus + // ID of the job run that this run belongs to. For legacy and single-task job + // runs the field is populated with the job run ID. For task runs, the field is + // populated with the ID of the job run that the task run belongs to. + JobRunId *int64 + // Indicates if the run has more array properties (`tasks`, `job_clusters`) that + // are not shown. They can be accessed via :method:jobs/getrun endpoint. It is + // only relevant for API 2.2 :method:jobs/listruns requests with + // `expand_tasks=true`. + HasMore *bool + // The actual performance target used by the serverless run during execution. + // This can differ from the client-set performance target on the request + // depending on whether the performance mode is supported by the job type. + // + // * `STANDARD`: Enables cost-efficient execution of serverless workloads. * + // `PERFORMANCE_OPTIMIZED`: Prioritizes fast startup and execution times through + // rapid scaling and optimized cluster performance. + EffectivePerformanceTarget PerformanceTarget_PerformanceTarget + // The id of the usage policy used by this run for cost attribution purposes. + EffectiveUsagePolicyId *string + // ID of the deployment that produced the job when this run was created. Used to + // look up deployment metadata from the Deployment Metadata service. Only set + // for job runs of jobs with a `BUNDLE` deployment. + DeploymentId *string + // ID of the deployment version that produced the job when this run was created. + // Identifies a specific snapshot of the deployment in the Deployment Metadata + // service. Only set for job runs of jobs with a `BUNDLE` deployment. + VersionId *string + // The time at which this run was started in epoch milliseconds (milliseconds + // since 1/1/1970 UTC). This may not be the time when the job task starts + // executing, for example, if the job is scheduled to run on a new cluster, this + // is the time the cluster creation call is issued. + StartTime *int64 + // The time in milliseconds it took to set up the cluster. For runs that run on + // new clusters this is the cluster creation time, for runs that run on existing + // clusters this time should be very short. The duration of a task run is the + // sum of the `setup_duration`, `execution_duration`, and the + // `cleanup_duration`. The `setup_duration` field is set to 0 for multitask job + // runs. The total duration of a multitask job run is the value of the + // `run_duration` field. + SetupDuration *int64 + // The time in milliseconds it took to execute the commands in the JAR or + // notebook until they completed, failed, timed out, were cancelled, or + // encountered an unexpected error. The duration of a task run is the sum of the + // `setup_duration`, `execution_duration`, and the `cleanup_duration`. The + // `execution_duration` field is set to 0 for multitask job runs. The total + // duration of a multitask job run is the value of the `run_duration` field. + ExecutionDuration *int64 + // The time in milliseconds it took to terminate the cluster and clean up any + // associated artifacts. The duration of a task run is the sum of the + // `setup_duration`, `execution_duration`, and the `cleanup_duration`. The + // `cleanup_duration` field is set to 0 for multitask job runs. The total + // duration of a multitask job run is the value of the `run_duration` field. + CleanupDuration *int64 + // The time at which this run ended in epoch milliseconds (milliseconds since + // 1/1/1970 UTC). This field is set to 0 if the job is still running. + EndTime *int64 + // The time in milliseconds it took the job run and all of its repairs to + // finish. + RunDuration *int64 + // The time in milliseconds that the run has spent in the queue. + QueueDuration *int64 +} + +type CancelAllRunsRequest struct { + // The canonical identifier of the job to cancel all runs of. + JobId *int64 + // Optional boolean parameter to cancel all queued runs. If no job_id is + // provided, all queued runs in the workspace are canceled. + AllQueuedRuns *bool +} + +// All runs were cancelled successfully.. +type CancelAllRunsResponse struct { +} + +type CancelRunRequest struct { + // This field is required. + RunId *int64 +} + +// Run was cancelled successfully.. +type CancelRunResponse struct { +} + +type CleanRoomTaskRunLifeCycleState struct { +} + +type CleanRoomTaskRunResultState struct { +} + +// Stores the run state of the clean rooms notebook task.. +type CleanRoomTaskRunState struct { + // A value indicating the run's current lifecycle state. This field is always + // available in the response. Note: Additional states might be introduced in + // future releases. + LifeCycleState CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState + // A value indicating the run's result. This field is only available for + // terminal lifecycle states. Note: Additional states might be introduced in + // future releases. + ResultState CleanRoomTaskRunResultState_CleanRoomTaskRunResultState +} + +// Clean Rooms notebook task for V1 Clean Room service (GA). Replaces the +// deprecated CleanRoomNotebookTask (defined above) which was for V0 service.. +type CleanRoomsNotebookTask struct { + // The clean room that the notebook belongs to. + CleanRoomName *string + // Name of the notebook being run. + NotebookName *string + // Checksum to validate the freshness of the notebook resource (i.e. the + // notebook being run is the latest version). It can be fetched by calling the + // :method:cleanroomassets/get API. + Etag *string + // Base parameters to be used for the clean room notebook job. + NotebookBaseParameters map[string]string +} + +type CleanRoomsNotebookTask_CleanRoomsNotebookTaskOutput struct { + // The run state of the clean rooms notebook task. + CleanRoomJobRunState *CleanRoomTaskRunState + // The notebook output for the clean room run + NotebookOutput *NotebookTask_NotebookOutput + // Information on how to access the output schema for the clean room run + OutputSchemaInfo *OutputSchemaInfo +} + +type ClusterInstance struct { + // The canonical identifier for the cluster used by a run. This field is always + // available for runs on existing clusters. For runs on new clusters, it becomes + // available once the cluster is created. This value can be used to view logs by + // browsing to `/#setting/sparkui/$cluster_id/driver-logs`. The logs continue to + // be available after the run completes. + // + // The response won’t include this field if the identifier is not available + // yet. + ClusterId *string + // The canonical identifier for the Spark context used by a run. This field is + // filled in once the run begins execution. This value can be used to view the + // Spark UI by browsing to `/#setting/sparkui/$cluster_id/$spark_context_id`. + // The Spark UI continues to be available after the run has completed. + // + // The response won’t include this field if the identifier is not available + // yet. + SparkContextId *string +} + +// Cluster log delivery config. +type ClusterLogConf struct { + StorageInfo isClusterLogConf_StorageInfo +} + +type isClusterLogConf_StorageInfo interface { + isClusterLogConf_StorageInfo() +} + +// ClusterLogConf_StorageInfo_Dbfs selects Dbfs for ClusterLogConf.StorageInfo. +// destination needs to be provided. e.g. `{ "dbfs" : { "destination" : +// "dbfs:/home/cluster_log" } }` +type ClusterLogConf_StorageInfo_Dbfs struct { + Dbfs DbfsStorageInfo +} + +func (*ClusterLogConf_StorageInfo_Dbfs) isClusterLogConf_StorageInfo() {} + +// ClusterLogConf_StorageInfo_S3 selects S3 for ClusterLogConf.StorageInfo. +// destination and either the region or endpoint need to be provided. e.g. `{ +// "s3": { "destination" : "s3://cluster_log_bucket/prefix", "region" : +// "us-west-2" } }` Cluster iam role is used to access s3, please make sure the +// cluster iam role in `instance_profile_arn` has permission to write data to +// the s3 destination. +type ClusterLogConf_StorageInfo_S3 struct { + S3 S3StorageInfo +} + +func (*ClusterLogConf_StorageInfo_S3) isClusterLogConf_StorageInfo() {} + +// ClusterLogConf_StorageInfo_Volumes selects Volumes for ClusterLogConf.StorageInfo. +// destination needs to be provided, e.g. `{ "volumes": { "destination": +// "/Volumes/catalog/schema/volume/cluster_log" } }` +type ClusterLogConf_StorageInfo_Volumes struct { + Volumes VolumesStorageInfo +} + +func (*ClusterLogConf_StorageInfo_Volumes) isClusterLogConf_StorageInfo() {} + +type ClusterSpec struct { + Spec isClusterSpec_Spec + // An optional list of libraries to be installed on the cluster. The default + // value is an empty list. + Libraries []Library +} + +type isClusterSpec_Spec interface { + isClusterSpec_Spec() +} + +// ClusterSpec_Spec_ExistingClusterId selects ExistingClusterId for ClusterSpec.Spec. +// If existing_cluster_id, the ID of an existing cluster that is used for all +// runs. When running jobs or tasks on an existing cluster, you may need to +// manually restart the cluster if it stops responding. We suggest running jobs +// and tasks on new clusters for greater reliability +type ClusterSpec_Spec_ExistingClusterId struct { + ExistingClusterId string +} + +func (*ClusterSpec_Spec_ExistingClusterId) isClusterSpec_Spec() {} + +// ClusterSpec_Spec_NewCluster selects NewCluster for ClusterSpec.Spec. +// If new_cluster, a description of a new cluster that is created for each run. +type ClusterSpec_Spec_NewCluster struct { + NewCluster ClusterSpec_NewCluster +} + +func (*ClusterSpec_Spec_NewCluster) isClusterSpec_Spec() {} + +// ClusterSpec_Spec_JobClusterKey selects JobClusterKey for ClusterSpec.Spec. +// If job_cluster_key, this task is executed reusing the cluster specified in +// `job.settings.job_clusters`. +type ClusterSpec_Spec_JobClusterKey struct { + JobClusterKey string +} + +func (*ClusterSpec_Spec_JobClusterKey) isClusterSpec_Spec() {} + +type ClusterSpec_NewCluster struct { + ApplyPolicyDefaultValues *bool + // Cluster name requested by the user. This doesn't have to be unique. If not + // specified at creation, the cluster name will be an empty string. For job + // clusters, the cluster name is automatically set based on the job and job run + // IDs. + ClusterName *string + // The Spark version of the cluster, e.g. `3.3.x-scala2.11`. A list of available + // Spark versions can be retrieved by using the [clusters/sparkVersions] API + // call. + // + // [clusters/sparkVersions]: https://docs.databricks.com/api/workspace/clusters/sparkversions + SparkVersion *string + // An object containing a set of optional, user-specified Spark configuration + // key-value pairs. Users can also pass in a string of extra JVM options to the + // driver and the executors via `spark.driver.extraJavaOptions` and + // `spark.executor.extraJavaOptions` respectively. + SparkConf map[string]string + // Attributes related to clusters running on Amazon Web Services. If not + // specified at cluster creation, a set of default values will be used. + AwsAttributes *AwsAttributes + // Attributes related to clusters running on Microsoft Azure. If not specified + // at cluster creation, a set of default values will be used. + AzureAttributes *AzureAttributes + // Attributes related to clusters running on Google Cloud Platform. If not + // specified at cluster creation, a set of default values will be used. + GcpAttributes *GcpAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // [clusters/listNodeTypes] API call. + // + // [clusters/listNodeTypes]: https://docs.databricks.com/api/workspace/clusters/listnodetypes + NodeTypeId *string + // The node type of the Spark driver. Note that this field is optional; if + // unset, the driver node type will be set as the same value as `node_type_id` + // defined above. + // + // This field, along with node_type_id, should not be set if + // virtual_cluster_size is set. If both driver_node_type_id, node_type_id, and + // virtual_cluster_size are specified, driver_node_type_id and node_type_id take + // precedence. + DriverNodeTypeId *string + // Flexible node type configuration for worker nodes. + WorkerNodeTypeFlexibility *NodeTypeFlexibility + // Flexible node type configuration for the driver node. + DriverNodeTypeFlexibility *NodeTypeFlexibility + // SSH public key contents that will be added to each Spark node in this + // cluster. The corresponding private keys can be used to login with the user + // name `ubuntu` on port `2200`. Up to 10 keys can be specified. + SshPublicKeys []string + // Additional tags for cluster resources. will tag all cluster + // resources (e.g., AWS instances and EBS volumes) with these tags in addition + // to `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + // + // - Clusters can only reuse cloud resources if the resources' tags are a subset + // of the cluster tags + CustomTags map[string]string + // The configuration for delivering spark logs to a long-term storage + // destination. Three kinds of destinations (DBFS, S3 and Unity Catalog volumes) + // are supported. Only one destination can be specified for one cluster. If the + // conf is given, the logs will be delivered to the destination every `5 mins`. + // The destination of driver logs is `$destination/$clusterId/driver`, while the + // destination of executor logs is `$destination/$clusterId/executor`. + ClusterLogConf *ClusterLogConf + // An object containing a set of optional, user-specified environment variable + // key-value pairs. Please note that key-value pair of the form (X,Y) will be + // exported as is (i.e., `export X='Y'`) while launching the driver and workers. + // + // In order to specify an additional set of `SPARK_DAEMON_JAVA_OPTS`, we + // recommend appending them to `$SPARK_DAEMON_JAVA_OPTS` as shown in the example + // below. This ensures that all default databricks managed environmental + // variables are included as well. + // + // Example Spark environment variables: `{"SPARK_WORKER_MEMORY": "28000m", + // "SPARK_LOCAL_DIRS": "/local_disk0"}` or `{"SPARK_DAEMON_JAVA_OPTS": + // "$SPARK_DAEMON_JAVA_OPTS -Dspark.shuffle.service.enabled=true"}` + SparkEnvVars map[string]string + // Automatically terminates the cluster after it is inactive for this time in + // minutes. If not set, this cluster will not be automatically terminated. If + // specified, the threshold must be between 10 and 10000 minutes. Users can also + // set this value to 0 to explicitly disable automatic termination. + AutoterminationMinutes *int + // Autoscaling Local Storage: when enabled, this cluster will dynamically + // acquire additional disk space when its Spark workers are running low on disk + // space. + EnableElasticDisk *bool + // The configuration for storing init scripts. Any number of destinations can be + // specified. The scripts are executed sequentially in the order provided. If + // `cluster_log_conf` is specified, init script logs are sent to + // `//init_scripts`. + InitScripts []InitScriptInfo + // Custom docker image BYOC + DockerImage *DockerImage + // The optional ID of the instance pool to which the cluster belongs. + InstancePoolId *string + // Single user name if data_security_mode is `SINGLE_USER` + SingleUserName *string + // The ID of the cluster policy used to create the cluster if applicable. + PolicyId *string + // Whether to enable LUKS on cluster VMs' local disks + EnableLocalDiskEncryption *bool + // The optional ID of the instance pool for the driver of the cluster belongs. + // The pool cluster uses the instance pool with id (instance_pool_id) if the + // driver pool is not assigned. + DriverInstancePoolId *string + WorkloadType *WorkloadType + DataSecurityMode DataSecurityMode + // Determines the cluster's runtime engine, either standard or Photon. + // + // This field is not compatible with legacy `spark_version` values that contain + // `-photon-`. Remove `-photon-` from the `spark_version` and set + // `runtime_engine` to `PHOTON`. + // + // If left unspecified, the runtime engine defaults to standard unless the + // spark_version contains -photon-, in which case Photon will be used. + RuntimeEngine RuntimeEngine + Kind ComputeKind + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // `effective_spark_version` is determined by `spark_version` (DBR release), + // this field `use_ml_runtime`, and whether `node_type_id` is gpu node or not. + UseMlRuntime *bool + // This field can only be used when `kind = CLASSIC_PREVIEW`. + // + // When set to true, will automatically set single node related + // `custom_tags`, `spark_conf`, and `num_workers` + IsSingleNode *bool + // If set, what the configurable throughput (in Mb/s) for the remote disk is. + // Currently only supported for GCP HYPERDISK_BALANCED disks. + RemoteDiskThroughput *int + // If set, what the total initial volume size (in GB) of the remote disks should + // be. Currently only supported for GCP HYPERDISK_BALANCED disks. + TotalInitialRemoteDiskSize *int + // Controls dependency configuration for the cluster. + DependencyMode DependencyMode + Size isClusterSpec_NewCluster_Size +} + +type isClusterSpec_NewCluster_Size interface { + isClusterSpec_NewCluster_Size() +} + +// ClusterSpec_NewCluster_Size_NumWorkers selects NumWorkers for ClusterSpec_NewCluster.Size. +// Number of worker nodes that this cluster should have. A cluster has one Spark +// Driver and `num_workers` Executors for a total of `num_workers` + 1 Spark +// nodes. +// +// Note: When reading the properties of a cluster, this field reflects the +// desired number of workers rather than the actual current number of workers. +// For instance, if a cluster is resized from 5 to 10 workers, this field will +// immediately be updated to reflect the target size of 10 workers, whereas the +// workers listed in `spark_info` will gradually increase from 5 to 10 as the +// new nodes are provisioned. +type ClusterSpec_NewCluster_Size_NumWorkers struct { + NumWorkers int +} + +func (*ClusterSpec_NewCluster_Size_NumWorkers) isClusterSpec_NewCluster_Size() {} + +// ClusterSpec_NewCluster_Size_Autoscale selects Autoscale for ClusterSpec_NewCluster.Size. +// Parameters needed in order to automatically scale clusters up and down based +// on load. Note: autoscaling works best with DB runtime versions 3.0 or later. +type ClusterSpec_NewCluster_Size_Autoscale struct { + Autoscale AutoScale +} + +func (*ClusterSpec_NewCluster_Size_Autoscale) isClusterSpec_NewCluster_Size() {} + +type Compute struct { + // Hardware accelerator configuration for Serverless GPU workloads. + HardwareAccelerator HardwareAcceleratorType +} + +type ComputeConfig struct { + // Number of GPUs. + NumGpus *int + // IDof the GPU pool to use. + GpuNodePoolId *string + // GPU type. + GpuType *string +} + +// ComputeSpec: compute configuration — accelerator type and total accelerator +// count across all nodes.. +type ComputeSpec struct { + // Hardware accelerator type (for example, `GPU_1xA10` or `GPU_8xH100`). The + // number of accelerators per node is encoded in the enum value — `GPU_8xH100` + // means 8 H100 GPUs per node. + AcceleratorType ComputeSpec_AcceleratorType + // Total number of accelerators across all nodes. Must be a positive multiple of + // the per-node accelerator count encoded in `accelerator_type`. For example, + // `GPU_8xH100` with `accelerator_count: 16` allocates 2 nodes (8 GPUs per + // node). + AcceleratorCount *int +} + +type ConditionTask struct { + // * `EQUAL_TO`, `NOT_EQUAL` operators perform string comparison of their + // operands. This means that `“12.0” == “12”` will evaluate to `false`. + // * `GREATER_THAN`, `GREATER_THAN_OR_EQUAL`, `LESS_THAN`, `LESS_THAN_OR_EQUAL` + // operators perform numeric comparison of their operands. `“12.0” >= + // “12”` will evaluate to `true`, `“10.0” >= “12”` will evaluate to + // `false`. + // + // The boolean comparison to task values can be implemented with operators + // `EQUAL_TO`, `NOT_EQUAL`. If a task value was set to a boolean value, it will + // be serialized to `“true”` or `“false”` for the comparison. + Op ConditionTask_ConditionTaskOperator + // The left operand of the condition task. Can be either a string value or a job + // state or parameter reference. + Left *string + // The right operand of the condition task. Can be either a string value or a + // job state or parameter reference. + Right *string + // The condition expression evaluation result. Filled in if the task was + // successfully completed. Can be `"true"` or `"false"` + Outcome *string +} + +type ContinuousSettings struct { + // Indicate whether the continuous execution of the job is paused or not. + // Defaults to UNPAUSED. + PauseStatus SchedulePauseStatus + // Indicate whether the continuous job is applying task level retries or not. + // Defaults to NEVER. + TaskRetryMode TaskRetryMode +} + +// Continuous trigger. Stripped-down counterpart to `ContinuousSettings`: +// `pause_status` is owned by the enclosing `TriggerConfiguration` and +// intentionally omitted here.. +type ContinuousTriggerConfiguration struct { + // Whether the continuous job applies task-level retries. Defaults to NEVER. + TaskRetryMode TaskRetryMode +} + +type ContinuousTriggerState struct { + ConsecutiveFailures *int + NextAttemptMs *int64 + IsBackingOff *bool +} + +type CreateJobRequest struct { + // List of permissions to set on the job. + AccessControlList []AccessControlRequest + // An optional name for the job. The maximum length is 4096 bytes in UTF-8 + // encoding. + Name *string + // An optional description for the job. The maximum length is 27700 characters + // in UTF-8 encoding. + Description *string + // An optional set of email addresses that is notified when runs of this job + // begin or complete as well as when this job is deleted. + EmailNotifications *JobEmailNotifications + // A collection of system notification IDs to notify when runs of this job begin + // or complete. + WebhookNotifications *WebhookNotifications + // Optional notification settings that are used when sending notifications to + // each of the `email_notifications` and `webhook_notifications` for this job. + NotificationSettings *NotificationSettings + // An optional timeout applied to each run of this job. A value of `0` means no + // timeout. + TimeoutSeconds *int + Health *JobsHealthRules + // An optional periodic schedule for this job. The default behavior is that the + // job only runs when triggered by clicking “Run Now” in the Jobs UI or + // sending an API request to `runNow`. + Schedule *CronSchedule + // A configuration to trigger a run when certain conditions are met. The default + // behavior is that the job runs only when triggered by clicking “Run Now” + // in the Jobs UI or sending an API request to `runNow`. + Trigger *TriggerSettings + // An optional continuous property for this job. The continuous property will + // ensure that there is always one run executing. Only one of `schedule` and + // `continuous` can be used. + // + // Pipelines started by a continuous job also run continuously, regardless of + // their own pipeline mode setting. + Continuous *ContinuousSettings + // An optional maximum allowed number of concurrent runs of the job. Set this + // value if you want to be able to execute multiple runs of the same job + // concurrently. This is useful for example if you trigger your job on a + // frequent schedule and want to allow consecutive runs to overlap with each + // other, or if you want to trigger multiple runs which differ by their input + // parameters. This setting affects only new runs. For example, suppose the + // job’s concurrency is 4 and there are 4 concurrent active runs. Then setting + // the concurrency to 3 won’t kill any of the active runs. However, from then + // on, new runs are skipped unless there are fewer than 3 active runs. This + // value cannot exceed 1000. Setting this value to `0` causes all new runs to be + // skipped. + MaxConcurrentRuns *int + // A list of task specifications to be executed by this job. It supports up to + // 1000 elements in write endpoints (:method:jobs/create, :method:jobs/reset, + // :method:jobs/update, :method:jobs/submit). Read endpoints return only 100 + // tasks. If more than 100 tasks are available, you can paginate through them + // using :method:jobs/get. Use the `next_page_token` field at the object root to + // determine if more results are available. + Tasks []TaskSettings + // A list of job cluster specifications that can be shared and reused by tasks + // of this job. Libraries cannot be declared in a shared job cluster. You must + // declare dependent libraries in task settings. + JobClusters []JobCluster + // An optional specification for a remote Git repository containing the source + // code used by tasks. Version-controlled source code is supported by notebook, + // dbt, Python script, and SQL File tasks. + // + // If `git_source` is set, these tasks retrieve the file from the remote + // repository by default. However, this behavior can be overridden by setting + // `source` to `WORKSPACE` on the task. + // + // Note: dbt and SQL File tasks support only version-controlled sources. If dbt + // or SQL File tasks are used, `git_source` must be defined on the job. + GitSource *GitSource + // A map of tags associated with the job. These are forwarded to the cluster as + // cluster tags for jobs clusters, and are subject to the same limitations as + // cluster tags. A maximum of 25 tags can be added to the job. + Tags map[string]string + // Used to tell what is the format of the job. This field is ignored in + // Create/Update/Reset calls. When using the Jobs API 2.1 this value is always + // set to `"MULTI_TASK"`. + Format Format + // The queue settings of the job. + Queue *QueueSettings + // Job-level parameter definitions + Parameters []JobLevelParameter + // The user or service principal that the job runs as, if specified in the + // request. This field indicates the explicit configuration of `run_as` for the + // job. To find the value in all cases, explicit or implicit, use + // `run_as_user_name`. + RunAs *JobRunAs + // Edit mode of the job. + // + // * `UI_LOCKED`: The job is in a locked UI state and cannot be modified. * + // `EDITABLE`: The job is in an editable state and can be modified. + EditMode JobEditMode + // Deployment information for jobs managed by external sources. + Deployment *JobDeployment + // A list of task execution environment specifications that can be referenced by + // serverless tasks of this job. For serverless notebook tasks, if the + // environment_key is not specified, the notebook environment will be used if + // present. If a jobs environment is specified, it will override the notebook + // environment. For other serverless tasks, the task environment is required to + // be specified using environment_key in the task settings. + Environments []JobEnvironment + // The id of the user specified budget policy to use for this job. If not + // specified, a default budget policy may be applied when creating or modifying + // the job. See `effective_budget_policy_id` for the budget policy used by this + // workload. + BudgetPolicyId *string + // The id of the user specified usage policy to use for this job. If not + // specified, a default usage policy may be applied when creating or modifying + // the job. See `effective_usage_policy_id` for the usage policy used by this + // workload. + UsagePolicyId *string + // The performance mode on a serverless job. This field determines the level of + // compute performance or cost-efficiency for the run. The performance target + // does not apply to tasks that run on Serverless GPU compute. + // + // * `STANDARD`: Enables cost-efficient execution of serverless workloads. * + // `PERFORMANCE_OPTIMIZED`: Prioritizes fast startup and execution times through + // rapid scaling and optimized cluster performance. + PerformanceTarget PerformanceTarget_PerformanceTarget + // Path of the job parent folder in workspace file tree. If absent, the job + // doesn't have a workspace object. + ParentPath *string + // List of triggers attached to this job. A run starts when any active trigger + // evaluates to true. Cannot be set in the same request as the legacy + // `schedule`, `trigger`, or `continuous` fields. Gated behind the "Multiple + // Triggers" feature preview. + Triggers []TriggerConfiguration + // An optional maximum number of times to retry an unsuccessful run. A run is + // considered to be unsuccessful if it completes with the `FAILED` result_state + // or `INTERNAL_ERROR` `life_cycle_state`. The value `-1` means to retry + // indefinitely and the value `0` means to never retry. + MaxRetries *int + // An optional minimal interval in milliseconds between the start of the failed + // run and the subsequent retry run. The default behavior is that unsuccessful + // runs are immediately retried. + MinRetryIntervalMillis *int + // An optional policy to specify whether to retry a job when it times out. The + // default behavior is to not retry on timeout. + RetryOnTimeout *bool + // An option to disable auto optimization in serverless + DisableAutoOptimization *bool +} + +// Job was created successfully. +type CreateJobResponse struct { + // The canonical identifier for the newly created job. + JobId *int64 +} + +type CronSchedule struct { + // A Cron expression using Quartz syntax that describes the schedule for a job. + // See [Cron Trigger] for details. This field is required. + // + // [Cron Trigger]: http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html + QuartzCronExpression *string + // A Java timezone ID. The schedule for a job is resolved with respect to this + // timezone. See [Java TimeZone] for details. This field is required. + // + // [Java TimeZone]: https://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html + TimezoneId *string + // Indicate whether this schedule is paused or not. + PauseStatus SchedulePauseStatus + // SQL condition that must be satisfied before a scheduled run is triggered. The + // condition is evaluated after the cron expression fires and must return a + // truthy result for the run to proceed. + SqlCondition *SqlConditionConfiguration +} + +// Cron schedule trigger. Stripped-down counterpart to `CronSchedule`: +// `pause_status` and `sql_condition` are owned by the enclosing +// `TriggerConfiguration` and intentionally omitted here.. +type CronTriggerConfiguration struct { + // A Cron expression using Quartz syntax that describes the schedule for this + // trigger. See [Cron Trigger] for details. + // + // [Cron Trigger]: http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html + QuartzCronExpression *string + // A Java timezone ID. The schedule is resolved with respect to this timezone. + // See [Java TimeZone] for details. + // + // [Java TimeZone]: https://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html + TimezoneId *string +} + +type DashboardPageSnapshot struct { + PageDisplayName *string + WidgetErrorDetails []WidgetErrorDetail +} + +// Configures the Lakeview Dashboard job task type.. +type DashboardTask struct { + // Optional: subscription configuration for sending the dashboard snapshot. + Subscription *Subscription + // Optional: The warehouse id to execute the dashboard with for the schedule. If + // not specified, the default warehouse of the dashboard will be used. + WarehouseId *string + // The identifier of the dashboard to refresh. + DashboardId *string + // Dashboard task parameters. Used to apply dashboard filter values during + // dashboard task execution. Parameter values get applied to any dashboard + // filters that have a matching URL identifier as the parameter key. The + // parameter value format is dependent on the filter type: - For text and + // single-select filters, provide a single value (e.g. `"value"`) - For date and + // datetime filters, provide the value in ISO 8601 format (e.g. + // `"2000-01-01T00:00:00"`) - For multi-select filters, provide a JSON array of + // values (e.g. `"[\"value1\",\"value2\"]"`) - For range and date range filters, + // provide a JSON object with `start` and `end` (e.g. + // `"{\"start\":\"1\",\"end\":\"10\"}"`) + Filters map[string]string +} + +type DashboardTaskOutput struct { + // Should only be populated for manual PDF download jobs. + PageSnapshots []DashboardPageSnapshot +} + +// A storage location in DBFS. +type DbfsStorageInfo struct { + // dbfs destination, e.g. `dbfs:/my/path` + Destination *string +} + +// Format of response retrieved from dbt Cloud, for inclusion in output +// Deprecated in favor of DbtPlatformJobRunStep. +type DbtCloudJobRunStep struct { + // Orders the steps in the job + Index *int + // Name of the step in the job + Name *string + // State of the step + Status DbtPlatformRunStatus + // Output of the step + Logs *string +} + +// Deprecated in favor of DbtPlatformTask. +type DbtCloudTask struct { + // Id of the dbt Cloud job to be triggered + DbtCloudJobId *int64 + // The resource name of the UC connection that authenticates the dbt Cloud for + // this task + ConnectionResourceName *string +} + +// Deprecated in favor of DbtPlatformTaskOutput. +type DbtCloudTaskOutput struct { + // Id of the job run in dbt Cloud + DbtCloudJobRunId *int64 + // Url where full run details can be viewed + DbtCloudJobRunUrl *string + // Steps of the job run as received from dbt Cloud + DbtCloudJobRunOutput []DbtCloudJobRunStep +} + +// Format of response retrieved from dbt platform, for inclusion in output. +type DbtPlatformJobRunStep struct { + // Orders the steps in the job + Index *int + // Name of the step in the job + Name *string + // State of the step + Status DbtPlatformRunStatus + // Output of the step + Logs *string + // Whether the name of the job has been truncated. If true, the name has been + // truncated to 100 characters. + NameTruncated *bool + // Whether the logs of this step have been truncated. If true, the logs has been + // truncated to 10000 characters. + LogsTruncated *bool +} + +type DbtPlatformTask struct { + // Id of the dbt platform job to be triggered. Specified as a string for maximum + // compatibility with clients. + DbtPlatformJobId *string + // The resource name of the UC connection that authenticates the dbt platform + // for this task + ConnectionResourceName *string +} + +type DbtPlatformTaskOutput struct { + // Id of the job run in dbt platform. Specified as a string for maximum + // compatibility with clients. + DbtPlatformJobRunId *string + // Url where full run details can be viewed + DbtPlatformJobRunUrl *string + // Steps of the job run as received from dbt platform + DbtPlatformJobRunOutput []DbtPlatformJobRunStep + // Whether the number of steps in the output has been truncated. If true, the + // output will contain the first 20 steps of the output. + StepsTruncated *bool +} + +type DbtTask struct { + // Path to the project directory. Optional for Git sourced tasks, in which case + // if no value is provided, the root of the Git repository is used. + ProjectDirectory *string + // A list of dbt commands to execute. All commands must start with `dbt`. This + // parameter must not be empty. A maximum of up to 10 commands can be provided. + Commands []string + // Optional schema to write to. This parameter is only used when a warehouse_id + // is also provided. If not provided, the `default` schema is used. + Schema *string + // ID of the SQL warehouse to connect to. If provided, we automatically generate + // and provide the profile and connection details to dbt. It can be overridden + // on a per-command basis by using the `--profiles-dir` command line argument. + WarehouseId *string + // Optional (relative) path to the profiles directory. Can only be specified if + // no warehouse_id is specified. If no warehouse_id is specified and this folder + // is unset, the root directory is used. + ProfilesDirectory *string + // Optional name of the catalog to use. The value is the top level in the + // 3-level namespace of Unity Catalog (catalog / schema / relation). The catalog + // value can only be specified if a warehouse_id is specified. Requires + // dbt-databricks >= 1.1.1. + Catalog *string + // Optional location type of the project directory. When set to `WORKSPACE`, the + // project will be retrieved from the local workspace. When set to + // `GIT`, the project will be retrieved from a Git repository defined in + // `git_source`. If the value is empty, the task will use `GIT` if `git_source` + // is defined and `WORKSPACE` otherwise. + // + // * `WORKSPACE`: Project is located in workspace. * `GIT`: Project + // is located in cloud Git provider. + Source Source +} + +type DbtTask_DbtTaskOutput struct { + // A pre-signed URL to download the (compressed) dbt artifacts. This link is + // valid for a limited time (30 minutes). This information is only available + // after the run has finished. + ArtifactsLink *string + // An optional map of headers to send when retrieving the artifact from the + // `artifacts_link`. + ArtifactsHeaders map[string]string +} + +type DeleteJobRequest struct { + // The canonical identifier of the job to delete. This field is required. + JobId *int64 +} + +// Job was deleted successfully.. +type DeleteJobResponse struct { +} + +type DeleteRunRequest struct { + // ID of the run to delete. + RunId *int64 +} + +// Run was deleted successfully.. +type DeleteRunResponse struct { +} + +// DeploymentSpec: configuration for one deployment within an AiRuntimeTask. +// Each entry in `AiRuntimeTask.deployments` describes a group of nodes that +// share the same command and compute. Many single-program training algorithms +// use a single entry where every node runs the same command; role-split +// workloads (driver + worker, parameter server, separate eval node, etc.) use +// multiple entries.. +type DeploymentSpec struct { + // Workspace path of the script to run on each node in this deployment. Upload + // the script to this path and supply the path here. When the task runs, the + // file at this path is run on each node; if it fails, the task fails with its + // exit code. + // + // Example script contents: + // + // # Plain Python: python train.py --epochs 10 + // + // # Multi-GPU via accelerate: accelerate launch train.py --config config.yaml + // + // # Distributed via torchrun: torchrun --nproc_per_node=8 train.py + CommandPath *string + // Compute resources allocated to each node in this deployment. + Compute *ComputeSpec + // Optional human-readable name for this deployment (for example, `driver`, + // `worker`, `param_server`). Used for log and UI display. Distinct names are + // recommended so deployments can be told apart, but uniqueness is not enforced. + Name *string +} + +type DockerBasicAuth struct { + // Name of the user + Username *string + // Password of the user + Password *string +} + +type DockerImage struct { + // URL of the docker image. + Url *string + CredsOneof isDockerImage_CredsOneof +} + +type isDockerImage_CredsOneof interface { + isDockerImage_CredsOneof() +} + +// DockerImage_CredsOneof_BasicAuth selects BasicAuth for DockerImage.CredsOneof. +// Basic auth with username and password +type DockerImage_CredsOneof_BasicAuth struct { + BasicAuth DockerBasicAuth +} + +func (*DockerImage_CredsOneof_BasicAuth) isDockerImage_CredsOneof() {} + +type EnforcePolicyComplianceForJob struct { + // The ID of the job you want to enforce policy compliance on. + JobId *int64 + // If set, previews changes made to the job to comply with its policy, but does + // not update the job. + ValidateOnly *bool +} + +type EnforcePolicyComplianceResponse struct { + // Whether any changes have been made to the job cluster settings for the job to + // become compliant with its policies. + HasChanges *bool + // A list of job cluster changes that have been made to the job’s cluster + // settings in order for all job clusters to become compliant with their + // policies. + JobClusterChanges []EnforcePolicyComplianceResponse_JobClusterSettingsChange + // Updated job settings after policy enforcement. Policy enforcement only + // applies to job clusters that are created when running the job (which are + // specified in new_cluster) and does not apply to existing all-purpose + // clusters. Updated job settings are derived by applying policy default values + // to the existing job clusters in order to satisfy policy requirements. + Settings *JobSettings +} + +// Represents a change to the job cluster's settings that would be required for +// the job clusters to become compliant with their policies.. +type EnforcePolicyComplianceResponse_JobClusterSettingsChange struct { + // The field where this change would be made, prepended with the job cluster + // key. + Field *string + // The previous value of this field before enforcing policy compliance (either a + // number, a boolean, or a string) converted to a string. This is intended to be + // read by a human. The type of the field can be retrieved by reading the + // settings field in the API response. + PreviousValue *string + // The new value of this field after enforcing policy compliance (either a + // number, a boolean, or a string) converted to a string. This is intended to be + // read by a human. The typed new value of this field can be retrieved by + // reading the settings field in the API response. + NewValue *string +} + +// The environment entity used to preserve serverless environment side panel, +// jobs' environment for non-notebook task, and SDP's environment for classic +// and serverless pipelines. In this minimal environment spec, only pip and java +// dependencies are supported.. +type Environment struct { + // Use `environment_version` instead. + Client *string + // List of pip dependencies, as supported by the version of pip in this + // environment. Each dependency is a valid pip requirements file line per + // https://pip.pypa.io/en/stable/reference/requirements-file-format/. Allowed + // dependencies include a requirement specifier, an archive URL, a local project + // path (such as WSFS or UC Volumes in ), or a VCS project URL. + Dependencies []string + // The base environment this environment is built on top of. A base environment + // defines the environment version and a list of dependencies for serverless + // compute. The value can be a file path to a custom `env.yaml` file (e.g., + // `/Workspace/path/to/env.yaml`). Support for a -provided base + // environment ID (e.g., `workspace-base-environments/databricks_ai_v4`) and + // workspace base environment ID (e.g., + // `workspace-base-environments/dbe_b849b66e-b31a-4cb5-b161-1f2b10877fb7`) is in + // Beta. Either `environment_version` or `base_environment` can be provided. For + // more information about -provided base environments, see the [list + // workspace base + // environments](:method:Environments/ListWorkspaceBaseEnvironments) API. For + // more information, see + BaseEnvironment *string + // Either `environment_version` or `base_environment` needs to be provided. + // Environment version used by the environment. Each version comes with a + // specific Python version and a set of Python packages. The version is a + // string, consisting of an integer. + EnvironmentVersion *string + // List of java dependencies. Each dependency is a string representing a java + // library path. For example: `/Volumes/path/to/test.jar`. + JavaDependencies []string +} + +// Retrieves the export of a job run task.. +type ExportRunRequest struct { + // The canonical identifier for the run. This field is required. + RunId *int64 + // Which views to export (CODE, DASHBOARDS, or ALL). Defaults to CODE. + ViewsToExport ViewsToExport +} + +// Run was exported successfully.. +type ExportRunResponse struct { + // The exported content in HTML format (one for every view item). To extract the + // HTML notebook from the JSON response, download and run this [Python + // script](/_static/examples/extract.py). + Views []ViewItem +} + +type FileArrivalTriggerConfiguration struct { + // URL to be monitored for file arrivals. The path must point to the root or a + // subpath of the external location. + Url *string + // If set, the trigger starts a run only after the specified amount of time + // passed since the last time the trigger fired. The minimum allowed value is 60 + // seconds + MinTimeBetweenTriggersSeconds *int + // If set, the trigger starts a run only after no file activity has occurred for + // the specified amount of time. This makes it possible to wait for a batch of + // incoming files to arrive before triggering a run. The minimum allowed value + // is 60 seconds. + WaitAfterLastChangeSeconds *int +} + +type FileArrivalTriggerState struct { + // Indicates whether the trigger leverages file events to detect file arrivals. + UsingFileEvents *bool +} + +type ForEachTask struct { + // Array for task to iterate on. This can be a JSON string or a reference to an + // array parameter. + Inputs *string + // An optional maximum allowed number of concurrent runs of the task. Set this + // value if you want to be able to execute multiple runs of the task + // concurrently. + Concurrency *int + // Configuration for the task that will be run for each element in the array + Task *TaskSettings +} + +// Attributes set during cluster creation which are related to GCP.. +type GcpAttributes struct { + // This field determines whether the spark executors will be scheduled to run on + // preemptible VMs (when set to true) versus standard compute engine VMs (when + // set to false; default). Note: Soon to be deprecated, use the 'availability' + // field instead. + UsePreemptibleExecutors *bool + // If provided, the cluster will impersonate the google service account when + // accessing gcloud services (like GCS). The google service account must have + // previously been added to the environment by an account + // administrator. + GoogleServiceAccount *string + // Boot disk size in GB + BootDiskSize *int + // This field determines whether the spark executors will be scheduled to run on + // preemptible VMs, on-demand VMs, or preemptible VMs with a fallback to + // on-demand VMs if the former is unavailable. + Availability GcpAvailability + // Identifier for the availability zone in which the cluster resides. This can + // be one of the following: - "HA" => High availability, spread nodes across + // availability zones for a deployment region [default]. - "AUTO" + // => picks an availability zone to schedule the cluster on. - A + // GCP availability zone => Pick One of the available zones for (machine type + + // region) from https://cloud.google.com/compute/docs/regions-zones. + ZoneId *string + // If provided, each node (workers and driver) in the cluster will have this + // number of local SSDs attached. Each local SSD is 375GB in size. Refer to [GCP + // documentation] for the supported number of local SSDs for each instance type. + // + // [GCP documentation]: https://cloud.google.com/compute/docs/disks/local-ssd#choose_number_local_ssds + LocalSsdCount *int + // The first `first_on_demand` nodes of the cluster will be placed on on-demand + // instances. This value should be greater than 0, to make sure the cluster + // driver node is placed on an on-demand instance. If this value is greater than + // or equal to the current cluster size, all nodes will be placed on on-demand + // instances. If this value is less than the current cluster size, + // `first_on_demand` nodes will be placed on on-demand instances and the + // remainder will be placed on `availability` instances. Note that this value + // does not affect cluster size and cannot currently be mutated over the + // lifetime of a cluster. + FirstOnDemand *int + // The confidential computing technology for this cluster's instances. Currently + // only SEV_SNP is supported, and only on N2D instance types. When not set, no + // confidential computing is applied. + ConfidentialComputeType ConfidentialComputeType +} + +// A storage location in Google Cloud Platform's GCS. +type GcsStorageInfo struct { + // GCS destination/URI, e.g. `gs://my-bucket/some-prefix` + Destination *string +} + +// DEPRECATED — use `AiRuntimeTask` for all new BYOT multi-node GPU workloads +// (see ai_runtime_task.proto). `AiRuntimeTask` is the only supported BYOT task +// type for new workloads; this proto is retained only for AIR CLI (fka SGCLI) +// pywheel backwards compatibility and will be removed once the pywheel → +// databricks-cli migration completes (post- PuPr).. +type GenAiComputeTask struct { + // Runtime image + DlRuntimeImage *string + Compute *ComputeConfig + // Command launcher to run the actual script, e.g. bash, python etc. + Command *string + // Optional location type of the training script. When set to `WORKSPACE`, the + // script will be retrieved from the local workspace. When set to + // `GIT`, the script will be retrieved from a Git repository defined in + // `git_source`. If the value is empty, the task will use `GIT` if `git_source` + // is defined and `WORKSPACE` otherwise. * `WORKSPACE`: Script is located in + // workspace. * `GIT`: Script is located in cloud Git provider. + Source Source + // The training script file path to be executed. Cloud file URIs (such as + // dbfs:/, s3:/, adls:/, gcs:/) and workspace paths are supported. For python + // files stored in the workspace, the path must be absolute and + // begin with `/`. For files stored in a remote repository, the path must be + // relative. This field is required. + TrainingScriptPath *string + // Optional path to a YAML file containing model parameters passed to the + // training script. + YamlParametersFilePath *string + // Optional string containing model parameters passed to the training script in + // yaml format. If present, then the content in yaml_parameters_file_path will + // be ignored. + YamlParameters *string + // Optional string containing the name of the MLflow experiment to log the run + // to. If name is not found, backend will create the mlflow experiment using the + // name. + MlflowExperimentName *string +} + +// Retrieves information about a single job.. +type GetJobRequest struct { + // The canonical identifier of the job to retrieve information about. This field + // is required. + JobId *int64 + // Flag that indicates that trigger state should be included in the response. + IncludeTriggerState *bool + // Use `next_page_token` returned from the previous GetJob response to request + // the next page of the job's array properties. + PageToken *string +} + +// Job was retrieved successfully.. +type GetJobResponse struct { + // A token that can be used to list the next page of array properties. + NextPageToken *string + // The canonical identifier for this job. + JobId *int64 + // The creator user name. This field won’t be included in the response if the + // user has already been deleted. + CreatorUserName *string + // The email of an active workspace user or the application ID of a service + // principal that the job runs as. This value can be changed by setting the + // `run_as` field when creating or updating a job. + // + // By default, `run_as_user_name` is based on the current job settings and is + // set to the creator of the job if job access control is disabled or to the + // user with the `is_owner` permission if job access control is enabled. + RunAsUserName *string + // Settings for this job and all of its runs. These settings can be updated + // using the `resetJob` method. + Settings *JobSettings + // The time at which this job was created in epoch milliseconds (milliseconds + // since 1/1/1970 UTC). + CreatedTime *int64 + // State of the trigger associated with the job. + TriggerState *TriggerState + // Indicates if the job has more array properties (`tasks`, `job_clusters`) that + // are not shown. They can be accessed via :method:jobs/get endpoint. It is only + // relevant for API 2.2 :method:jobs/list requests with `expand_tasks=true`. + HasMore *bool + // The id of the budget policy used by this job for cost attribution purposes. + // This may be set through (in order of precedence): 1. Budget admins through + // the account or workspace console 2. Jobs UI in the job details page and Jobs + // API using `budget_policy_id` 3. Inferred default based on accessible budget + // policies of the run_as identity on job creation or modification. + EffectiveBudgetPolicyId *string + // The id of the usage policy used by this job for cost attribution purposes. + EffectiveUsagePolicyId *string + // Per-trigger runtime information for the multi-trigger surface. Same length + // and order as `JobSettings.triggers`; `trigger_details[i]` corresponds to + // `triggers[i]`. Sub-fields (`state`, `history`) are populated independently + // based on the `GetJob.include_trigger_state` / `include_trigger_history` + // flags. + TriggerDetails []TriggerDetails +} + +type GetPolicyComplianceForJobRequest struct { + // The ID of the job whose compliance status you are requesting. + JobId *int64 +} + +type GetPolicyComplianceForJobResponse struct { + // Whether the job is compliant with its policies or not. Jobs could be out of + // compliance if a policy they are using was updated after the job was last + // edited and some of its job clusters no longer comply with their updated + // policies. + IsCompliant *bool + // An object containing key-value mappings representing the first 200 policy + // validation errors. The keys indicate the path where the policy validation + // error is occurring. An identifier for the job cluster is prepended to the + // path. The values indicate an error message describing the policy validation + // error. + Violations map[string]string +} + +// Retrieves both the output and the metadata of a run.. +type GetRunOutputRequest struct { + // The canonical identifier for the run. + RunId *int64 +} + +// Run output was retrieved successfully.. +type GetRunOutputResponse struct { + // All details of the run except for its output. + Metadata *Run + // An error message indicating why a task failed or why output is not available. + // The message is unstructured, and its exact format is subject to change. + Error *string + Info *string + Result isGetRunOutputResponse_Result + // The output from tasks that write to standard streams (stdout/stderr) such as + // spark_jar_task, spark_python_task, python_wheel_task. + // + // It's not supported for the notebook_task, pipeline_task or spark_submit_task. + // + // restricts this API to return the last 5 MB of these logs. + Logs *string + // Whether the logs are truncated. + LogsTruncated *bool + // If there was an error executing the run, this field contains any available + // stack traces. + ErrorTrace *string +} + +type isGetRunOutputResponse_Result interface { + isGetRunOutputResponse_Result() +} + +// GetRunOutputResponse_Result_NotebookOutput selects NotebookOutput for GetRunOutputResponse.Result. +// The output of a notebook task, if available. A notebook task that terminates +// (either successfully or with a failure) without calling +// `dbutils.notebook.exit()` is considered to have an empty output. This field +// is set but its result value is empty. restricts this API to +// return the first 5 MB of the output. To return a larger result, use the +// [ClusterLogConf](/dev-tools/api/latest/clusters.html#clusterlogconf) field to +// configure log storage for the job cluster. +type GetRunOutputResponse_Result_NotebookOutput struct { + NotebookOutput NotebookTask_NotebookOutput +} + +func (*GetRunOutputResponse_Result_NotebookOutput) isGetRunOutputResponse_Result() {} + +// GetRunOutputResponse_Result_SqlOutput selects SqlOutput for GetRunOutputResponse.Result. +// The output of a SQL task, if available. +type GetRunOutputResponse_Result_SqlOutput struct { + SqlOutput SqlTask_SqlOutput +} + +func (*GetRunOutputResponse_Result_SqlOutput) isGetRunOutputResponse_Result() {} + +// GetRunOutputResponse_Result_DbtOutput selects DbtOutput for GetRunOutputResponse.Result. +// The output of a dbt task, if available. +type GetRunOutputResponse_Result_DbtOutput struct { + DbtOutput DbtTask_DbtTaskOutput +} + +func (*GetRunOutputResponse_Result_DbtOutput) isGetRunOutputResponse_Result() {} + +// GetRunOutputResponse_Result_RunJobOutput selects RunJobOutput for GetRunOutputResponse.Result. +// The output of a run job task, if available +type GetRunOutputResponse_Result_RunJobOutput struct { + RunJobOutput RunJobTask_RunJobTaskOutput +} + +func (*GetRunOutputResponse_Result_RunJobOutput) isGetRunOutputResponse_Result() {} + +// GetRunOutputResponse_Result_CleanRoomsNotebookOutput selects CleanRoomsNotebookOutput for GetRunOutputResponse.Result. +// The output of a clean rooms notebook task, if available +type GetRunOutputResponse_Result_CleanRoomsNotebookOutput struct { + CleanRoomsNotebookOutput CleanRoomsNotebookTask_CleanRoomsNotebookTaskOutput +} + +func (*GetRunOutputResponse_Result_CleanRoomsNotebookOutput) isGetRunOutputResponse_Result() {} + +// GetRunOutputResponse_Result_DashboardOutput selects DashboardOutput for GetRunOutputResponse.Result. +// The output of a dashboard task, if available +type GetRunOutputResponse_Result_DashboardOutput struct { + DashboardOutput DashboardTaskOutput +} + +func (*GetRunOutputResponse_Result_DashboardOutput) isGetRunOutputResponse_Result() {} + +// GetRunOutputResponse_Result_DbtCloudOutput selects DbtCloudOutput for GetRunOutputResponse.Result. +// Deprecated in favor of the new dbt_platform_output +type GetRunOutputResponse_Result_DbtCloudOutput struct { + DbtCloudOutput DbtCloudTaskOutput +} + +func (*GetRunOutputResponse_Result_DbtCloudOutput) isGetRunOutputResponse_Result() {} + +// GetRunOutputResponse_Result_DbtPlatformOutput selects DbtPlatformOutput for GetRunOutputResponse.Result. +type GetRunOutputResponse_Result_DbtPlatformOutput struct { + DbtPlatformOutput DbtPlatformTaskOutput +} + +func (*GetRunOutputResponse_Result_DbtPlatformOutput) isGetRunOutputResponse_Result() {} + +// GetRunOutputResponse_Result_AlertOutput selects AlertOutput for GetRunOutputResponse.Result. +// The output of an alert task, if available +type GetRunOutputResponse_Result_AlertOutput struct { + AlertOutput AlertTaskOutput +} + +func (*GetRunOutputResponse_Result_AlertOutput) isGetRunOutputResponse_Result() {} + +// GetRunOutputResponse_Result_AiRuntimeTaskOutput selects AiRuntimeTaskOutput for GetRunOutputResponse.Result. +// The output of an AiRuntimeTask, if available — MLflow identifiers, artifact +// paths, and per-replica allocated compute. Run lifecycle / termination status +// lives on the surrounding framework `RunTask.status` +// (`runs.proto:RunTask.status` of type `RunStatus`), not on this output. See +// `tasks/genai/ai_runtime_task.proto:AiRuntimeTaskOutput`. +type GetRunOutputResponse_Result_AiRuntimeTaskOutput struct { + AiRuntimeTaskOutput AiRuntimeTaskOutput +} + +func (*GetRunOutputResponse_Result_AiRuntimeTaskOutput) isGetRunOutputResponse_Result() {} + +type GetRunRequest struct { + // The canonical identifier of the run for which to retrieve the metadata. This + // field is required. + RunId *int64 + // Whether to include the repair history in the response. + IncludeHistory *bool + // Whether to include resolved parameter values in the response. + IncludeResolvedValues *bool + // Use `next_page_token` returned from the previous GetRun response to request + // the next page of the run's array properties. + PageToken *string +} + +// Run was retrieved successfully. +type GetRunResponse struct { + // A token that can be used to list the next page of array properties. + NextPageToken *string + // The canonical identifier of the job that contains this run. + JobId *int64 + // The canonical identifier of the run. This ID is unique across all runs of all + // jobs. + RunId *int64 + // The creator user name. This field won’t be included in the response if the + // user has already been deleted. + CreatorUserName *string + // A unique identifier for this job run. This is set to the same value as + // `run_id`. + NumberInJob *int64 + // If this run is a retry of a prior run attempt, this field contains the run_id + // of the original attempt; otherwise, it is the same as the run_id. + OriginalAttemptRunId *int64 + // Deprecated. Please use the `status` field instead. + State *RunState + // The cron schedule that triggered this run if it was triggered by the periodic + // scheduler. + Schedule *CronSchedule + // A snapshot of the job’s cluster specification when this run was created. + ClusterSpec *ClusterSpec + // The cluster used for this run. If the run is specified to use a new cluster, + // this field is set once the Jobs service has requested a cluster for the run. + ClusterInstance *ClusterInstance + // Job-level parameters used in the run + JobParameters []Run_JobLevelParameters + // The parameters used for this run. + OverridingParameters *RunParameters + Trigger TriggerType + TriggerInfo *RunTriggerInfo + // An optional name for the run. The maximum length is 4096 bytes in UTF-8 + // encoding. + RunName *string + // The URL to the detail page of the run. + RunPageUrl *string + RunType RunType + // The list of tasks performed by the run. Each task has its own `run_id` which + // you can use to call `JobsGetOutput` to retrieve the run results. If more than + // 100 tasks are available, you can paginate through them using + // :method:jobs/getrun. Use the `next_page_token` field at the object root to + // determine if more results are available. + Tasks []RunTask + // Description of the run + Description *string + // The sequence number of this run attempt for a triggered job run. The initial + // attempt of a run has an attempt_number of 0. If the initial run attempt + // fails, and the job has a retry policy (`max_retries` > 0), subsequent runs + // are created with an `original_attempt_run_id` of the original attempt’s ID + // and an incrementing `attempt_number`. Runs are retried only until they + // succeed, and the maximum `attempt_number` is the same as the `max_retries` + // value for the job. + AttemptNumber *int + // A list of job cluster specifications that can be shared and reused by tasks + // of this job. Libraries cannot be declared in a shared job cluster. You must + // declare dependent libraries in task settings. If more than 100 job clusters + // are available, you can paginate through them using :method:jobs/getrun. + JobClusters []JobCluster + // An optional specification for a remote Git repository containing the source + // code used by tasks. Version-controlled source code is supported by notebook, + // dbt, Python script, and SQL File tasks. + // + // If `git_source` is set, these tasks retrieve the file from the remote + // repository by default. However, this behavior can be overridden by setting + // `source` to `WORKSPACE` on the task. + // + // Note: dbt and SQL File tasks support only version-controlled sources. If dbt + // or SQL File tasks are used, `git_source` must be defined on the job. + GitSource *GitSource + // The repair history of the run. + RepairHistory []Repair + Status *RunStatus + // ID of the job run that this run belongs to. For legacy and single-task job + // runs the field is populated with the job run ID. For task runs, the field is + // populated with the ID of the job run that the task run belongs to. + JobRunId *int64 + // Indicates if the run has more array properties (`tasks`, `job_clusters`) that + // are not shown. They can be accessed via :method:jobs/getrun endpoint. It is + // only relevant for API 2.2 :method:jobs/listruns requests with + // `expand_tasks=true`. + HasMore *bool + // The actual performance target used by the serverless run during execution. + // This can differ from the client-set performance target on the request + // depending on whether the performance mode is supported by the job type. + // + // * `STANDARD`: Enables cost-efficient execution of serverless workloads. * + // `PERFORMANCE_OPTIMIZED`: Prioritizes fast startup and execution times through + // rapid scaling and optimized cluster performance. + EffectivePerformanceTarget PerformanceTarget_PerformanceTarget + // The id of the usage policy used by this run for cost attribution purposes. + EffectiveUsagePolicyId *string + // ID of the deployment that produced the job when this run was created. Used to + // look up deployment metadata from the Deployment Metadata service. Only set + // for job runs of jobs with a `BUNDLE` deployment. + DeploymentId *string + // ID of the deployment version that produced the job when this run was created. + // Identifies a specific snapshot of the deployment in the Deployment Metadata + // service. Only set for job runs of jobs with a `BUNDLE` deployment. + VersionId *string + // The time at which this run was started in epoch milliseconds (milliseconds + // since 1/1/1970 UTC). This may not be the time when the job task starts + // executing, for example, if the job is scheduled to run on a new cluster, this + // is the time the cluster creation call is issued. + StartTime *int64 + // The time in milliseconds it took to set up the cluster. For runs that run on + // new clusters this is the cluster creation time, for runs that run on existing + // clusters this time should be very short. The duration of a task run is the + // sum of the `setup_duration`, `execution_duration`, and the + // `cleanup_duration`. The `setup_duration` field is set to 0 for multitask job + // runs. The total duration of a multitask job run is the value of the + // `run_duration` field. + SetupDuration *int64 + // The time in milliseconds it took to execute the commands in the JAR or + // notebook until they completed, failed, timed out, were cancelled, or + // encountered an unexpected error. The duration of a task run is the sum of the + // `setup_duration`, `execution_duration`, and the `cleanup_duration`. The + // `execution_duration` field is set to 0 for multitask job runs. The total + // duration of a multitask job run is the value of the `run_duration` field. + ExecutionDuration *int64 + // The time in milliseconds it took to terminate the cluster and clean up any + // associated artifacts. The duration of a task run is the sum of the + // `setup_duration`, `execution_duration`, and the `cleanup_duration`. The + // `cleanup_duration` field is set to 0 for multitask job runs. The total + // duration of a multitask job run is the value of the `run_duration` field. + CleanupDuration *int64 + // The time at which this run ended in epoch milliseconds (milliseconds since + // 1/1/1970 UTC). This field is set to 0 if the job is still running. + EndTime *int64 + // The time in milliseconds it took the job run and all of its repairs to + // finish. + RunDuration *int64 + // The time in milliseconds that the run has spent in the queue. + QueueDuration *int64 +} + +// Read-only state of the remote repository at the time the job was run. This +// field is only included on job runs.. +type GitMetadataSnapshot struct { + // Commit that was used to execute the run. If git_branch was specified, this + // points to the HEAD of the branch at the time of the run; if git_tag was + // specified, this points to the commit the tag points to. + UsedCommit *string +} + +// An optional specification for a remote Git repository containing the source +// code used by tasks. Version-controlled source code is supported by notebook, +// dbt, Python script, and SQL File tasks. +// +// If `git_source` is set, these tasks retrieve the file from the remote +// repository by default. However, this behavior can be overridden by setting +// `source` to `WORKSPACE` on the task. +// +// Note: dbt and SQL File tasks support only version-controlled sources. If dbt +// or SQL File tasks are used, `git_source` must be defined on the job.. +type GitSource struct { + // URL of the repository to be cloned by this job. + GitUrl *string + // Unique identifier of the service used to host the Git repository. The value + // is case insensitive. + GitProvider *string + GitReference isGitSource_GitReference + GitSnapshot *GitMetadataSnapshot + // The source of the job specification in the remote repository when the job is + // source controlled. + JobSource *JobSource + SparseCheckout *SparseCheckout +} + +type isGitSource_GitReference interface { + isGitSource_GitReference() +} + +// GitSource_GitReference_GitBranch selects GitBranch for GitSource.GitReference. +// Name of the branch to be checked out and used by this job. This field cannot +// be specified in conjunction with git_tag or git_commit. +type GitSource_GitReference_GitBranch struct { + GitBranch string +} + +func (*GitSource_GitReference_GitBranch) isGitSource_GitReference() {} + +// GitSource_GitReference_GitTag selects GitTag for GitSource.GitReference. +// Name of the tag to be checked out and used by this job. This field cannot be +// specified in conjunction with git_branch or git_commit. +type GitSource_GitReference_GitTag struct { + GitTag string +} + +func (*GitSource_GitReference_GitTag) isGitSource_GitReference() {} + +// GitSource_GitReference_GitCommit selects GitCommit for GitSource.GitReference. +// Commit to be checked out and used by this job. This field cannot be specified +// in conjunction with git_branch or git_tag. +type GitSource_GitReference_GitCommit struct { + GitCommit string +} + +func (*GitSource_GitReference_GitCommit) isGitSource_GitReference() {} + +// Config for an individual init script. +type InitScriptInfo struct { + StorageInfo isInitScriptInfo_StorageInfo +} + +type isInitScriptInfo_StorageInfo interface { + isInitScriptInfo_StorageInfo() +} + +// InitScriptInfo_StorageInfo_Dbfs selects Dbfs for InitScriptInfo.StorageInfo. +// destination needs to be provided. e.g. `{ "dbfs": { "destination" : +// "dbfs:/home/cluster_log" } }` +type InitScriptInfo_StorageInfo_Dbfs struct { + Dbfs DbfsStorageInfo +} + +func (*InitScriptInfo_StorageInfo_Dbfs) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_S3 selects S3 for InitScriptInfo.StorageInfo. +// destination and either the region or endpoint need to be provided. e.g. `{ +// \"s3\": { \"destination\": \"s3://cluster_log_bucket/prefix\", \"region\": +// \"us-west-2\" } }` Cluster iam role is used to access s3, please make sure +// the cluster iam role in `instance_profile_arn` has permission to write data +// to the s3 destination. +type InitScriptInfo_StorageInfo_S3 struct { + S3 S3StorageInfo +} + +func (*InitScriptInfo_StorageInfo_S3) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_File selects File for InitScriptInfo.StorageInfo. +// destination needs to be provided, e.g. `{ "file": { "destination": +// "file:/my/local/file.sh" } }` +type InitScriptInfo_StorageInfo_File struct { + File LocalFileInfo +} + +func (*InitScriptInfo_StorageInfo_File) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_Gcs selects Gcs for InitScriptInfo.StorageInfo. +// destination needs to be provided, e.g. `{ "gcs": { "destination": +// "gs://my-bucket/file.sh" } }` +type InitScriptInfo_StorageInfo_Gcs struct { + Gcs GcsStorageInfo +} + +func (*InitScriptInfo_StorageInfo_Gcs) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_Abfss selects Abfss for InitScriptInfo.StorageInfo. +// destination needs to be provided, e.g. +// `abfss://@.dfs.core.windows.net/` +type InitScriptInfo_StorageInfo_Abfss struct { + Abfss Adlsgen2Info +} + +func (*InitScriptInfo_StorageInfo_Abfss) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_Workspace selects Workspace for InitScriptInfo.StorageInfo. +// destination needs to be provided, e.g. `{ "workspace": { "destination": +// "/cluster-init-scripts/setup-datadog.sh" } }` +type InitScriptInfo_StorageInfo_Workspace struct { + Workspace WorkspaceStorageInfo +} + +func (*InitScriptInfo_StorageInfo_Workspace) isInitScriptInfo_StorageInfo() {} + +// InitScriptInfo_StorageInfo_Volumes selects Volumes for InitScriptInfo.StorageInfo. +// destination needs to be provided. e.g. `{ \"volumes\" : { \"destination\" : +// \"/Volumes/my-init.sh\" } }` +type InitScriptInfo_StorageInfo_Volumes struct { + Volumes VolumesStorageInfo +} + +func (*InitScriptInfo_StorageInfo_Volumes) isInitScriptInfo_StorageInfo() {} + +type JobCluster struct { + // A unique name for the job cluster. This field is required and must be unique + // within the job. `JobTaskSettings` may refer to this field to determine which + // cluster to launch for the task execution. + JobClusterKey *string + // If new_cluster, a description of a cluster that is created for each task. + NewCluster *ClusterSpec_NewCluster + // The ID of the serverless compute object to bind this cluster to. At most one + // JobCluster per job may set this field; the rate limit defined on the + // referenced serverless compute applies across all tasks bound to this cluster. + ServerlessComputeId *string +} + +type JobDeployment struct { + // The kind of deployment that manages the job. + // + // * `BUNDLE`: The job is managed by Databricks Asset Bundle. * + // `SYSTEM_MANAGED`: The job is managed by and is read-only. + Kind JobDeployment_DeploymentKind + // Path of the file that contains deployment metadata. + MetadataFilePath *string + // ID of the deployment that manages this job. Only set when `kind` is `BUNDLE`. + // Used to look up deployment metadata from the Deployment Metadata service. + DeploymentId *string + // ID of the version of the deployment that produced this job. Only set when + // `kind` is `BUNDLE`. Identifies a specific snapshot of the deployment in the + // Deployment Metadata service. + VersionId *string +} + +type JobEmailNotifications struct { + // A list of email addresses to be notified when a run begins. If not specified + // on job creation, reset, or update, the list is empty, and notifications are + // not sent. + OnStart []string + // A list of email addresses to be notified when a run successfully completes. A + // run is considered to have completed successfully if it ends with a + // `TERMINATED` `life_cycle_state` and a `SUCCESS` result_state. If not + // specified on job creation, reset, or update, the list is empty, and + // notifications are not sent. + OnSuccess []string + // A list of email addresses to be notified when a run unsuccessfully completes. + // A run is considered to have completed unsuccessfully if it ends with an + // `INTERNAL_ERROR` `life_cycle_state` or a `FAILED`, or `TIMED_OUT` + // result_state. If this is not specified on job creation, reset, or update the + // list is empty, and notifications are not sent. + OnFailure []string + // A list of email addresses to be notified when the duration of a run exceeds + // the threshold specified for the `RUN_DURATION_SECONDS` metric in the `health` + // field. If no rule for the `RUN_DURATION_SECONDS` metric is specified in the + // `health` field for the job, notifications are not sent. + OnDurationWarningThresholdExceeded []string + // A list of email addresses to notify when any streaming backlog thresholds are + // exceeded for any stream. Streaming backlog thresholds can be set in the + // `health` field using the following metrics: `STREAMING_BACKLOG_BYTES`, + // `STREAMING_BACKLOG_RECORDS`, `STREAMING_BACKLOG_SECONDS`, or + // `STREAMING_BACKLOG_FILES`. Alerting is based on the 10-minute average of + // these metrics. If the issue persists, notifications are resent every 30 + // minutes. + OnStreamingBacklogExceeded []string + // If true, do not send email to recipients specified in `on_failure` if the run + // is skipped. This field is `deprecated`. Please use the + // `notification_settings.no_alert_for_skipped_runs` field. + NoAlertForSkippedRuns *bool +} + +type JobEnvironment struct { + // The key of an environment. It has to be unique within a job. + EnvironmentKey *string + Spec *Environment +} + +type JobLevelParameter struct { + // The name of the defined parameter. May only contain alphanumeric characters, + // `_`, `-`, and `.` + Name *string + // Default value of the parameter. + Default *string +} + +// Write-only setting. Specifies the user or service principal that the job runs +// as. If not specified, the job runs as the user who created the job. +// +// Either `user_name` or `service_principal_name` should be specified. If not, +// an error is thrown.. +type JobRunAs struct { + Identity isJobRunAs_Identity +} + +type isJobRunAs_Identity interface { + isJobRunAs_Identity() +} + +// JobRunAs_Identity_UserName selects UserName for JobRunAs.Identity. +// The email of an active workspace user. Non-admin users can only set this +// field to their own email. +type JobRunAs_Identity_UserName struct { + UserName string +} + +func (*JobRunAs_Identity_UserName) isJobRunAs_Identity() {} + +// JobRunAs_Identity_ServicePrincipalName selects ServicePrincipalName for JobRunAs.Identity. +// Application ID of an active service principal. Setting this field requires +// the `servicePrincipal/user` role. +type JobRunAs_Identity_ServicePrincipalName struct { + ServicePrincipalName string +} + +func (*JobRunAs_Identity_ServicePrincipalName) isJobRunAs_Identity() {} + +// JobRunAs_Identity_GroupName selects GroupName for JobRunAs.Identity. +// Group name of an account group assigned to the workspace. Setting this field +// requires being a member of the group. +type JobRunAs_Identity_GroupName struct { + GroupName string +} + +func (*JobRunAs_Identity_GroupName) isJobRunAs_Identity() {} + +type JobSettings struct { + // An optional name for the job. The maximum length is 4096 bytes in UTF-8 + // encoding. + Name *string + // An optional description for the job. The maximum length is 27700 characters + // in UTF-8 encoding. + Description *string + // An optional set of email addresses that is notified when runs of this job + // begin or complete as well as when this job is deleted. + EmailNotifications *JobEmailNotifications + // A collection of system notification IDs to notify when runs of this job begin + // or complete. + WebhookNotifications *WebhookNotifications + // Optional notification settings that are used when sending notifications to + // each of the `email_notifications` and `webhook_notifications` for this job. + NotificationSettings *NotificationSettings + // An optional timeout applied to each run of this job. A value of `0` means no + // timeout. + TimeoutSeconds *int + Health *JobsHealthRules + // An optional periodic schedule for this job. The default behavior is that the + // job only runs when triggered by clicking “Run Now” in the Jobs UI or + // sending an API request to `runNow`. + Schedule *CronSchedule + // A configuration to trigger a run when certain conditions are met. The default + // behavior is that the job runs only when triggered by clicking “Run Now” + // in the Jobs UI or sending an API request to `runNow`. + Trigger *TriggerSettings + // An optional continuous property for this job. The continuous property will + // ensure that there is always one run executing. Only one of `schedule` and + // `continuous` can be used. + // + // Pipelines started by a continuous job also run continuously, regardless of + // their own pipeline mode setting. + Continuous *ContinuousSettings + // An optional maximum allowed number of concurrent runs of the job. Set this + // value if you want to be able to execute multiple runs of the same job + // concurrently. This is useful for example if you trigger your job on a + // frequent schedule and want to allow consecutive runs to overlap with each + // other, or if you want to trigger multiple runs which differ by their input + // parameters. This setting affects only new runs. For example, suppose the + // job’s concurrency is 4 and there are 4 concurrent active runs. Then setting + // the concurrency to 3 won’t kill any of the active runs. However, from then + // on, new runs are skipped unless there are fewer than 3 active runs. This + // value cannot exceed 1000. Setting this value to `0` causes all new runs to be + // skipped. + MaxConcurrentRuns *int + // A list of task specifications to be executed by this job. It supports up to + // 1000 elements in write endpoints (:method:jobs/create, :method:jobs/reset, + // :method:jobs/update, :method:jobs/submit). Read endpoints return only 100 + // tasks. If more than 100 tasks are available, you can paginate through them + // using :method:jobs/get. Use the `next_page_token` field at the object root to + // determine if more results are available. + Tasks []TaskSettings + // A list of job cluster specifications that can be shared and reused by tasks + // of this job. Libraries cannot be declared in a shared job cluster. You must + // declare dependent libraries in task settings. + JobClusters []JobCluster + // An optional specification for a remote Git repository containing the source + // code used by tasks. Version-controlled source code is supported by notebook, + // dbt, Python script, and SQL File tasks. + // + // If `git_source` is set, these tasks retrieve the file from the remote + // repository by default. However, this behavior can be overridden by setting + // `source` to `WORKSPACE` on the task. + // + // Note: dbt and SQL File tasks support only version-controlled sources. If dbt + // or SQL File tasks are used, `git_source` must be defined on the job. + GitSource *GitSource + // A map of tags associated with the job. These are forwarded to the cluster as + // cluster tags for jobs clusters, and are subject to the same limitations as + // cluster tags. A maximum of 25 tags can be added to the job. + Tags map[string]string + // Used to tell what is the format of the job. This field is ignored in + // Create/Update/Reset calls. When using the Jobs API 2.1 this value is always + // set to `"MULTI_TASK"`. + Format Format + // The queue settings of the job. + Queue *QueueSettings + // Job-level parameter definitions + Parameters []JobLevelParameter + // The user or service principal that the job runs as, if specified in the + // request. This field indicates the explicit configuration of `run_as` for the + // job. To find the value in all cases, explicit or implicit, use + // `run_as_user_name`. + RunAs *JobRunAs + // Edit mode of the job. + // + // * `UI_LOCKED`: The job is in a locked UI state and cannot be modified. * + // `EDITABLE`: The job is in an editable state and can be modified. + EditMode JobEditMode + // Deployment information for jobs managed by external sources. + Deployment *JobDeployment + // A list of task execution environment specifications that can be referenced by + // serverless tasks of this job. For serverless notebook tasks, if the + // environment_key is not specified, the notebook environment will be used if + // present. If a jobs environment is specified, it will override the notebook + // environment. For other serverless tasks, the task environment is required to + // be specified using environment_key in the task settings. + Environments []JobEnvironment + // The id of the user specified budget policy to use for this job. If not + // specified, a default budget policy may be applied when creating or modifying + // the job. See `effective_budget_policy_id` for the budget policy used by this + // workload. + BudgetPolicyId *string + // The id of the user specified usage policy to use for this job. If not + // specified, a default usage policy may be applied when creating or modifying + // the job. See `effective_usage_policy_id` for the usage policy used by this + // workload. + UsagePolicyId *string + // The performance mode on a serverless job. This field determines the level of + // compute performance or cost-efficiency for the run. The performance target + // does not apply to tasks that run on Serverless GPU compute. + // + // * `STANDARD`: Enables cost-efficient execution of serverless workloads. * + // `PERFORMANCE_OPTIMIZED`: Prioritizes fast startup and execution times through + // rapid scaling and optimized cluster performance. + PerformanceTarget PerformanceTarget_PerformanceTarget + // Path of the job parent folder in workspace file tree. If absent, the job + // doesn't have a workspace object. + ParentPath *string + // List of triggers attached to this job. A run starts when any active trigger + // evaluates to true. Cannot be set in the same request as the legacy + // `schedule`, `trigger`, or `continuous` fields. Gated behind the "Multiple + // Triggers" feature preview. + Triggers []TriggerConfiguration + // An optional maximum number of times to retry an unsuccessful run. A run is + // considered to be unsuccessful if it completes with the `FAILED` result_state + // or `INTERNAL_ERROR` `life_cycle_state`. The value `-1` means to retry + // indefinitely and the value `0` means to never retry. + MaxRetries *int + // An optional minimal interval in milliseconds between the start of the failed + // run and the subsequent retry run. The default behavior is that unsuccessful + // runs are immediately retried. + MinRetryIntervalMillis *int + // An optional policy to specify whether to retry a job when it times out. The + // default behavior is to not retry on timeout. + RetryOnTimeout *bool + // An option to disable auto optimization in serverless + DisableAutoOptimization *bool +} + +// The source of the job specification in the remote repository when the job is +// source controlled.. +type JobSource struct { + // Path of the job YAML file that contains the job specification. + JobConfigPath *string + ImportFromGitReference isJobSource_ImportFromGitReference + // Dirty state indicates the job is not fully synced with the job specification + // in the remote repository. + // + // Possible values are: * `NOT_SYNCED`: The job is not yet synced with the + // remote job specification. Import the remote job specification from UI to make + // the job fully synced. * `DISCONNECTED`: The job is temporary disconnected + // from the remote job specification and is allowed for live edit. Import the + // remote job specification again from UI to make the job fully synced. + DirtyState JobSource_DirtyState +} + +type isJobSource_ImportFromGitReference interface { + isJobSource_ImportFromGitReference() +} + +// JobSource_ImportFromGitReference_ImportFromGitBranch selects ImportFromGitBranch for JobSource.ImportFromGitReference. +// Name of the branch which the job is imported from. +type JobSource_ImportFromGitReference_ImportFromGitBranch struct { + ImportFromGitBranch string +} + +func (*JobSource_ImportFromGitReference_ImportFromGitBranch) isJobSource_ImportFromGitReference() {} + +type JobsHealthRule struct { + Metric JobsHealthMetric + Op JobsHealthOperator + // Specifies the threshold value that the health metric should obey to satisfy + // the health rule. + Value *int64 +} + +// An optional set of health rules that can be defined for this job.. +type JobsHealthRules struct { + Rules []JobsHealthRule +} + +type Library struct { + Lib isLibrary_Lib +} + +type isLibrary_Lib interface { + isLibrary_Lib() +} + +// Library_Lib_Jar selects Jar for Library.Lib. +// URI of the JAR library to install. Supported URIs include Workspace paths, +// Unity Catalog Volumes paths, and S3 URIs. For example: `{ "jar": +// "/Workspace/path/to/library.jar" }`, `{ "jar" : +// "/Volumes/path/to/library.jar" }` or `{ "jar": "s3://my-bucket/library.jar" +// }`. If S3 is used, please make sure the cluster has read access on the +// library. You may need to launch the cluster with an IAM role to access the S3 +// URI. +type Library_Lib_Jar struct { + Jar string +} + +func (*Library_Lib_Jar) isLibrary_Lib() {} + +// Library_Lib_Egg selects Egg for Library.Lib. +// Deprecated. URI of the egg library to install. Installing Python egg files is +// deprecated and is not supported in Databricks Runtime 14.0 and above. +type Library_Lib_Egg struct { + Egg string +} + +func (*Library_Lib_Egg) isLibrary_Lib() {} + +// Library_Lib_Pypi selects Pypi for Library.Lib. +// Specification of a PyPi library to be installed. For example: `{ "package": +// "simplejson" }` +type Library_Lib_Pypi struct { + Pypi PythonPyPiLibrary +} + +func (*Library_Lib_Pypi) isLibrary_Lib() {} + +// Library_Lib_Maven selects Maven for Library.Lib. +// Specification of a maven library to be installed. For example: `{ +// "coordinates": "org.jsoup:jsoup:1.7.2" }` +type Library_Lib_Maven struct { + Maven MavenLibrary +} + +func (*Library_Lib_Maven) isLibrary_Lib() {} + +// Library_Lib_Cran selects Cran for Library.Lib. +// Specification of a CRAN library to be installed as part of the library +type Library_Lib_Cran struct { + Cran RCranLibrary +} + +func (*Library_Lib_Cran) isLibrary_Lib() {} + +// Library_Lib_Whl selects Whl for Library.Lib. +// URI of the wheel library to install. Supported URIs include Workspace paths, +// Unity Catalog Volumes paths, and S3 URIs. For example: `{ "whl": +// "/Workspace/path/to/library.whl" }`, `{ "whl" : +// "/Volumes/path/to/library.whl" }` or `{ "whl": "s3://my-bucket/library.whl" +// }`. If S3 is used, please make sure the cluster has read access on the +// library. You may need to launch the cluster with an IAM role to access the S3 +// URI. +type Library_Lib_Whl struct { + Whl string +} + +func (*Library_Lib_Whl) isLibrary_Lib() {} + +// Library_Lib_Requirements selects Requirements for Library.Lib. +// URI of the requirements.txt file to install. Only Workspace paths and Unity +// Catalog Volumes paths are supported. For example: `{ "requirements": +// "/Workspace/path/to/requirements.txt" }` or `{ "requirements" : +// "/Volumes/path/to/requirements.txt" }` +type Library_Lib_Requirements struct { + Requirements string +} + +func (*Library_Lib_Requirements) isLibrary_Lib() {} + +type ListJobComplianceForPolicy struct { + // Canonical unique identifier for the cluster policy. + PolicyId *string + // A page token that can be used to navigate to the next page or previous page + // as returned by `next_page_token` or `prev_page_token`. + PageToken *string + // Use this field to specify the maximum number of results to be returned by the + // server. The server may further constrain the maximum number of results + // returned in a single page. + PageSize *int +} + +type ListJobComplianceForPolicy_JobCompliance struct { + // Canonical unique identifier for a job. + JobId *int64 + // Whether this job is in compliance with the latest version of its policy. + IsCompliant *bool + // An object containing key-value mappings representing the first 200 policy + // validation errors. The keys indicate the path where the policy validation + // error is occurring. An identifier for the job cluster is prepended to the + // path. The values indicate an error message describing the policy validation + // error. + Violations map[string]string +} + +type ListJobComplianceResponse struct { + // A list of jobs and their policy compliance statuses. + Jobs []ListJobComplianceForPolicy_JobCompliance + // This field represents the pagination token to retrieve the next page of + // results. If this field is not in the response, it means no further results + // for the request. + NextPageToken *string + // This field represents the pagination token to retrieve the previous page of + // results. If this field is not in the response, it means no further results + // for the request. + PrevPageToken *string +} + +// Lists all jobs.. +type ListJobsRequest struct { + // The offset of the first job to return, relative to the most recently created + // job. Deprecated since June 2023. Use `page_token` to iterate through the + // pages instead. + Offset *int + // The number of jobs to return. This value must be greater than 0 and less or + // equal to 100. The default value is 20. + Limit *int + // Whether to include task and cluster details in the response. Note that only + // the first 100 elements will be shown. Use :method:jobs/get to paginate + // through all tasks and clusters. + ExpandTasks *bool + // A filter on the list based on the exact (case insensitive) job name. + Name *string + // Use `next_page_token` or `prev_page_token` returned from the previous request + // to list the next or previous page of jobs respectively. + PageToken *string +} + +// List of jobs was retrieved successfully.. +type ListJobsResponse struct { + // The list of jobs. Only included in the response if there are jobs to list. + Jobs []BaseJob + // If true, additional jobs matching the provided filter are available for + // listing. + HasMore *bool + // A token that can be used to list the next page of jobs (if applicable). + NextPageToken *string + // A token that can be used to list the previous page of jobs (if applicable). + PrevPageToken *string +} + +// Lists runs from most recently started to least.. +type ListRunsRequest struct { + // The job for which to list runs. If omitted, the Jobs service lists runs from + // all jobs. + JobId *int64 + StateConstraint isListRunsRequest_StateConstraint + // The offset of the first run to return, relative to the most recent run. + // Deprecated since June 2023. Use `page_token` to iterate through the pages + // instead. + Offset *int + // The number of runs to return. This value must be greater than 0 and less than + // 25. The default value is 20. If a request specifies a limit of 0, the service + // instead uses the maximum limit. + Limit *int + // The type of runs to return. For a description of run types, see + // :method:jobs/getRun. + RunType RunType + // Whether to include task and cluster details in the response. Note that only + // the first 100 elements will be shown. Use :method:jobs/getrun to paginate + // through all tasks and clusters. + ExpandTasks *bool + // Show runs that started _at or after_ this value. The value must be a UTC + // timestamp in milliseconds. Can be combined with _start_time_to_ to filter by + // a time range. + StartTimeFrom *int64 + // Show runs that started _at or before_ this value. The value must be a UTC + // timestamp in milliseconds. Can be combined with _start_time_from_ to filter + // by a time range. + StartTimeTo *int64 + // Use `next_page_token` or `prev_page_token` returned from the previous request + // to list the next or previous page of runs respectively. + PageToken *string +} + +type isListRunsRequest_StateConstraint interface { + isListRunsRequest_StateConstraint() +} + +// ListRunsRequest_StateConstraint_ActiveOnly selects ActiveOnly for ListRunsRequest.StateConstraint. +// If active_only is `true`, only active runs are included in the results; +// otherwise, lists both active and completed runs. An active run is a run in +// the `QUEUED`, `PENDING`, `RUNNING`, or `TERMINATING`. This field cannot be +// `true` when completed_only is `true`. +type ListRunsRequest_StateConstraint_ActiveOnly struct { + ActiveOnly bool +} + +func (*ListRunsRequest_StateConstraint_ActiveOnly) isListRunsRequest_StateConstraint() {} + +// ListRunsRequest_StateConstraint_CompletedOnly selects CompletedOnly for ListRunsRequest.StateConstraint. +// If completed_only is `true`, only completed runs are included in the results; +// otherwise, lists both active and completed runs. This field cannot be `true` +// when active_only is `true`. +type ListRunsRequest_StateConstraint_CompletedOnly struct { + CompletedOnly bool +} + +func (*ListRunsRequest_StateConstraint_CompletedOnly) isListRunsRequest_StateConstraint() {} + +// List of runs was retrieved successfully.. +type ListRunsResponse struct { + // A list of runs, from most recently started to least. Only included in the + // response if there are runs to list. + Runs []BaseRun + // If true, additional runs matching the provided filter are available for + // listing. + HasMore *bool + // A token that can be used to list the next page of runs (if applicable). + NextPageToken *string + // A token that can be used to list the previous page of runs (if applicable). + PrevPageToken *string +} + +type LocalFileInfo struct { + // local file destination, e.g. `file:/my/local/file.sh` + Destination *string +} + +type LogAnalyticsInfo struct { + LogAnalyticsWorkspaceId *string + LogAnalyticsPrimaryKey *string +} + +type MavenLibrary struct { + // Gradle-style maven coordinates. For example: "org.jsoup:jsoup:1.7.2". + Coordinates *string + // Maven repo to install the Maven package from. If omitted, both Maven Central + // Repository and Spark Packages are searched. + Repo *string + // List of dependences to exclude. For example: `["slf4j:slf4j", + // "*:hadoop-client"]`. + // + // Maven dependency exclusions: + // https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html. + Exclusions []string +} + +type ModelTriggerConfiguration struct { + // Name of the securable to monitor ("mycatalog.myschema.mymodel" in the case of + // model-level triggers, "mycatalog.myschema" in the case of schema-level + // triggers) or empty in the case of metastore-level triggers. + SecurableName *string + // Aliases of the model versions to monitor. Can only be used in conjunction + // with condition MODEL_ALIAS_SET. + Aliases []string + // The condition based on which to trigger a job run. + Condition ModelTriggerConfiguration_ModelTriggerCondition + // If set, the trigger starts a run only after the specified amount of time has + // passed since the last time the trigger fired. The minimum allowed value is 60 + // seconds. + MinTimeBetweenTriggersSeconds *int + // If set, the trigger starts a run only after no model updates have occurred + // for the specified time and can be used to wait for a series of model updates + // before triggering a run. The minimum allowed value is 60 seconds. + WaitAfterLastChangeSeconds *int +} + +// Runtime state for a model trigger. Currently empty because model triggers do +// not expose any trigger-specific runtime state.. +type ModelTriggerState struct { +} + +// Configuration for flexible node types, allowing fallback to alternate node +// types during cluster launch and upscale.. +type NodeTypeFlexibility struct { + // A list of node type IDs to use as fallbacks when the primary node type is + // unavailable. + AlternateNodeTypeIds []string +} + +type NotebookTask struct { + // The path of the notebook to be run in the workspace or remote + // repository. For notebooks stored in the workspace, the path must + // be absolute and begin with a slash. For notebooks stored in a remote + // repository, the path must be relative. This field is required. + NotebookPath *string + // Base parameters to be used for each run of this job. If the run is initiated + // by a call to :method:jobs/run Now with parameters specified, the two + // parameters maps are merged. If the same key is specified in `base_parameters` + // and in `run-now`, the value from `run-now` is used. Use [Task parameter + // variables](/jobs.html#parameter-variables) to set parameters containing + // information about job runs. + // + // If the notebook takes a parameter that is not specified in the job’s + // `base_parameters` or the `run-now` override parameters, the default value + // from the notebook is used. + // + // Retrieve these parameters in a notebook using + // [dbutils.widgets.get](/dev-tools/databricks-utils.html#dbutils-widgets). + // + // The JSON representation of this field cannot exceed 1MB. + BaseParameters map[string]string + // Optional location type of the notebook. When set to `WORKSPACE`, the notebook + // will be retrieved from the local workspace. When set to `GIT`, + // the notebook will be retrieved from a Git repository defined in `git_source`. + // If the value is empty, the task will use `GIT` if `git_source` is defined and + // `WORKSPACE` otherwise. * `WORKSPACE`: Notebook is located in + // workspace. * `GIT`: Notebook is located in cloud Git provider. + Source Source + // Optional `warehouse_id` to run the notebook on a SQL warehouse. Classic SQL + // warehouses are NOT supported, please use serverless or pro SQL warehouses. + // + // Note that SQL warehouses only support SQL cells; if the notebook contains + // non-SQL cells, the run will fail. + WarehouseId *string +} + +type NotebookTask_NotebookOutput struct { + // The value passed to + // [dbutils.notebook.exit()](/notebooks/notebook-workflows.html#notebook-workflows-exit). + // restricts this API to return the first 5 MB of the value. For a + // larger result, your job can store the results in a cloud storage service. + // This field is absent if `dbutils.notebook.exit()` was never called. + Result *string + // Whether or not the result was truncated. + Truncated *bool +} + +type NotificationSettings struct { + // If true, do not send notifications to recipients specified in `on_failure` if + // the run is skipped. + NoAlertForSkippedRuns *bool + // If true, do not send notifications to recipients specified in `on_failure` if + // the run is canceled. + NoAlertForCanceledRuns *bool + // If true, do not send notifications to recipients specified in `on_start` for + // the retried runs and do not send notifications to recipients specified in + // `on_failure` until the last retry of the run. + AlertOnLastAttempt *bool +} + +// Stores the catalog name, schema name, and the output schema expiration time +// for the clean room run.. +type OutputSchemaInfo struct { + CatalogName *string + SchemaName *string + // The expiration time for the output schema as a Unix timestamp in + // milliseconds. + ExpirationTime *int64 +} + +// Per-trigger runtime state for the multi-trigger surface. Mirrors +// `TriggerConfiguration`'s trigger-type variants 1:1; each entry sets exactly +// one variant matching the corresponding trigger's type. Variants with no +// runtime state today (`schedule`, `model`) are emitted as empty messages.. +type PerTriggerState struct { + // (-- Next ID: 9. --) Runtime-state variant for the corresponding trigger; + // exactly one field is set, matching the trigger's type in + // `TriggerConfiguration`. + TriggerType isPerTriggerState_TriggerType + // State for SQL condition evaluation, can coexist with other trigger states. + SqlCondition *SqlConditionState + // Whether this trigger is paused or not. Mirrors the configured pause_status. + PauseStatus SchedulePauseStatus +} + +type isPerTriggerState_TriggerType interface { + isPerTriggerState_TriggerType() +} + +// PerTriggerState_TriggerType_Periodic selects Periodic for PerTriggerState.TriggerType. +type PerTriggerState_TriggerType_Periodic struct { + Periodic PeriodicTriggerState +} + +func (*PerTriggerState_TriggerType_Periodic) isPerTriggerState_TriggerType() {} + +// PerTriggerState_TriggerType_Schedule selects Schedule for PerTriggerState.TriggerType. +type PerTriggerState_TriggerType_Schedule struct { + Schedule ScheduleTriggerState +} + +func (*PerTriggerState_TriggerType_Schedule) isPerTriggerState_TriggerType() {} + +// PerTriggerState_TriggerType_Continuous selects Continuous for PerTriggerState.TriggerType. +type PerTriggerState_TriggerType_Continuous struct { + Continuous ContinuousTriggerState +} + +func (*PerTriggerState_TriggerType_Continuous) isPerTriggerState_TriggerType() {} + +// PerTriggerState_TriggerType_FileArrival selects FileArrival for PerTriggerState.TriggerType. +type PerTriggerState_TriggerType_FileArrival struct { + FileArrival FileArrivalTriggerState +} + +func (*PerTriggerState_TriggerType_FileArrival) isPerTriggerState_TriggerType() {} + +// PerTriggerState_TriggerType_TableUpdate selects TableUpdate for PerTriggerState.TriggerType. +type PerTriggerState_TriggerType_TableUpdate struct { + TableUpdate TableTriggerState +} + +func (*PerTriggerState_TriggerType_TableUpdate) isPerTriggerState_TriggerType() {} + +// PerTriggerState_TriggerType_Model selects Model for PerTriggerState.TriggerType. +type PerTriggerState_TriggerType_Model struct { + Model ModelTriggerState +} + +func (*PerTriggerState_TriggerType_Model) isPerTriggerState_TriggerType() {} + +type PerformanceTarget struct { +} + +type PeriodicTriggerConfiguration struct { + // The interval at which the trigger should run. + Interval *int + // The unit of time for the interval. + Unit PeriodicTriggerConfiguration_TimeUnit +} + +type PeriodicTriggerState struct { + NextRunTime *int64 +} + +type PipelineParameters struct { + // If true, triggers a full refresh on the spark declarative pipeline. + FullRefresh *bool + // A list of tables to update without fullRefresh. + RefreshSelection []string + // A list of tables to update with fullRefresh. + FullRefreshSelection []string + // A list of streaming flows to reset checkpoints without clearing data. + ResetCheckpointSelection []string + // Flow names to selectively refresh. These are unioned with other selective + // refresh options (refresh_selection, full_refresh_selection) to determine the + // final set of flows to refresh. + RefreshFlowSelection []string +} + +type PipelineTask struct { + // The full name of the pipeline task to execute. + PipelineId *string + // Key/value-map of parameters passed to the pipeline execution. Limited to 10k + // characters in total. + PipelineTaskParameters map[string]string + // If true, triggers a full refresh on the spark declarative pipeline. + FullRefresh *bool + // A list of tables to update without fullRefresh. + RefreshSelection []string + // A list of tables to update with fullRefresh. + FullRefreshSelection []string + // A list of streaming flows to reset checkpoints without clearing data. + ResetCheckpointSelection []string + // Flow names to selectively refresh. These are unioned with other selective + // refresh options (refresh_selection, full_refresh_selection) to determine the + // final set of flows to refresh. + RefreshFlowSelection []string +} + +type PowerBiModel struct { + // The name of the Power BI workspace of the model + WorkspaceName *string + // The name of the Power BI model + ModelName *string + // The default storage mode of the Power BI model + StorageMode StorageMode + // How the published Power BI model authenticates to + AuthenticationMethod AuthenticationMethod + // Whether to overwrite existing Power BI models + OverwriteExisting *bool +} + +type PowerBiTable struct { + // The table name in + Name *string + // The catalog name in + Catalog *string + // The schema name in + Schema *string + // The Power BI storage mode of the table + StorageMode StorageMode +} + +type PowerBiTask struct { + // The tables to be exported to Power BI + Tables []PowerBiTable + // The SQL warehouse ID to use as the Power BI data source + WarehouseId *string + // The semantic model to update + PowerBiModel *PowerBiModel + // The resource name of the UC connection to authenticate from to + // Power BI + ConnectionResourceName *string + // Whether the model should be refreshed after the update + RefreshAfterUpdate *bool +} + +type PythonOperatorTask struct { + // An ordered list of task parameters. TODO(JOBS-30885): Add limits for + // parameters. + Parameters []PythonOperatorTask_Parameter + // Fully qualified name of the main class or function. For example, + // `my_project.my_function` or `my_project.MyOperator`. + Main *string +} + +type PythonOperatorTask_Parameter struct { + Name *string + Value *string +} + +type PythonPyPiLibrary struct { + // The name of the pypi package to install. An optional exact version + // specification is also supported. Examples: "simplejson" and + // "simplejson==3.8.0". + Package *string + // The repository where the package can be found. If not specified, the default + // pip index is used. + Repo *string +} + +type PythonWheelTask struct { + // Name of the package to execute + PackageName *string + // Named entry point to use, if it does not exist in the metadata of the package + // it executes the function from the package directly using + // `$packageName.$entryPoint()` + EntryPoint *string + // Command-line parameters passed to Python wheel task. Leave it empty if + // `named_parameters` is not null. + Parameters []string + // Command-line parameters passed to Python wheel task in the form of + // `["--name=task", "--data=dbfs:/path/to/data.json"]`. Leave it empty if + // `parameters` is not null. + NamedParameters map[string]string +} + +type QueueDetails struct { + Code QueueDetailsCode_Code + // A descriptive message with the queuing details. This field is unstructured, + // and its exact format is subject to change. + Message *string +} + +type QueueDetailsCode struct { +} + +type QueueSettings struct { + // If true, enable queueing for the job. This is a required field. + Enabled *bool +} + +type RCranLibrary struct { + // The name of the CRAN package to install. + Package *string + // The repository where the package can be found. If not specified, the default + // CRAN repo is used. + Repo *string +} + +type Repair struct { + // The repair history item type. Indicates whether a run is the original run or + // a repair run. + Type RepairType + // The start time of the (repaired) run. + StartTime *int64 + // The end time of the (repaired) run. + EndTime *int64 + // Deprecated. Please use the `status` field instead. + State *RunState + // The ID of the repair. Only returned for the items that represent a repair in + // `repair_history`. + Id *int64 + // The run IDs of the task runs that ran as part of this repair history item. + TaskRunIds []int64 + Status *RunStatus + // The actual performance target used by the serverless run during execution. + // This can differ from the client-set performance target on the request + // depending on whether the performance mode is supported by the job type. + // + // * `STANDARD`: Enables cost-efficient execution of serverless workloads. * + // `PERFORMANCE_OPTIMIZED`: Prioritizes fast startup and execution times through + // rapid scaling and optimized cluster performance. + EffectivePerformanceTarget PerformanceTarget_PerformanceTarget +} + +type RepairRunRequest struct { + // The job run ID of the run to repair. The run must not be in progress. + RunId *int64 + // The ID of the latest repair. This parameter is not required when repairing a + // run for the first time, but must be provided on subsequent requests to repair + // the same run. + LatestRepairId *int64 + // The task keys of the task runs to repair. + RerunTasks []string + // Job-level parameters used in the run. for example `"param": "overriding_val"` + JobParameters map[string]string + // If true, repair all failed tasks. Only one of `rerun_tasks` or + // `rerun_all_failed_tasks` can be used. + RerunAllFailedTasks *bool + // If true, repair all tasks that depend on the tasks in `rerun_tasks`, even if + // they were previously successful. Can be also used in combination with + // `rerun_all_failed_tasks`. + RerunDependentTasks *bool + // The performance mode on a serverless job. The performance target determines + // the level of compute performance or cost-efficiency for the run. This field + // overrides the performance target defined on the job level. + // + // * `STANDARD`: Enables cost-efficient execution of serverless workloads. * + // `PERFORMANCE_OPTIMIZED`: Prioritizes fast startup and execution times through + // rapid scaling and optimized cluster performance. + PerformanceTarget PerformanceTarget_PerformanceTarget + // Controls whether the pipeline should perform a full refresh + PipelineParams *PipelineParameters + // A list of parameters for jobs with Spark JAR tasks, for example + // `"jar_params": ["john doe", "35"]`. The parameters are used to invoke the + // main function of the main class specified in the Spark JAR task. If not + // specified upon `run-now`, it defaults to an empty list. jar_params cannot be + // specified in conjunction with notebook_params. The JSON representation of + // this field (for example `{"jar_params":["john doe","35"]}`) cannot exceed + // 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + JarParams []string + // A map from keys to values for jobs with notebook task, for example + // `"notebook_params": {"name": "john doe", "age": "35"}`. The map is passed to + // the notebook and is accessible through the + // [dbutils.widgets.get](/dev-tools/databricks-utils.html) function. + // + // If not specified upon `run-now`, the triggered run uses the job’s base + // parameters. + // + // notebook_params cannot be specified in conjunction with jar_params. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // The JSON representation of this field (for example + // `{"notebook_params":{"name":"john doe","age":"35"}}`) cannot exceed 10,000 + // bytes. + NotebookParams map[string]string + // A list of parameters for jobs with Python tasks, for example + // `"python_params": ["john doe", "35"]`. The parameters are passed to Python + // file as command-line parameters. If specified upon `run-now`, it would + // overwrite the parameters specified in job setting. The JSON representation of + // this field (for example `{"python_params":["john doe","35"]}`) cannot exceed + // 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // Important + // + // These parameters accept only Latin characters (ASCII character set). Using + // non-ASCII characters returns an error. Examples of invalid, non-ASCII + // characters are Chinese, Japanese kanjis, and emojis. + PythonParams []string + // A list of parameters for jobs with spark submit task, for example + // `"spark_submit_params": ["--class", "org.apache.spark.examples.SparkPi"]`. + // The parameters are passed to spark-submit script as command-line parameters. + // If specified upon `run-now`, it would overwrite the parameters specified in + // job setting. The JSON representation of this field (for example + // `{"python_params":["john doe","35"]}`) cannot exceed 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // Important + // + // These parameters accept only Latin characters (ASCII character set). Using + // non-ASCII characters returns an error. Examples of invalid, non-ASCII + // characters are Chinese, Japanese kanjis, and emojis. + SparkSubmitParams []string + PythonNamedParams map[string]string + // A map from keys to values for jobs with SQL task, for example `"sql_params": + // {"name": "john doe", "age": "35"}`. The SQL alert task does not support + // custom parameters. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + SqlParams map[string]string + // An array of commands to execute for jobs with the dbt task, for example + // `"dbt_commands": ["dbt deps", "dbt seed", "dbt deps", "dbt seed", "dbt run"]` + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + DbtCommands []string +} + +// Run repair was initiated.. +type RepairRunResponse struct { + // The ID of the repair. Must be provided in subsequent repairs using the + // `latest_repair_id` field to ensure sequential repairs. + RepairId *int64 +} + +type ResetJobRequest struct { + // The canonical identifier of the job to reset. This field is required. + JobId *int64 + // The new settings of the job. These settings completely replace the old + // settings. + // + // Changes to the field `JobBaseSettings.timeout_seconds` are applied to active + // runs. Changes to other fields are applied to future runs only. + NewSettings *JobSettings +} + +// Job was overwritten successfully.. +type ResetJobResponse struct { +} + +type ResolvedValues struct { + Resolved isResolvedValues_Resolved +} + +type isResolvedValues_Resolved interface { + isResolvedValues_Resolved() +} + +// ResolvedValues_Resolved_NotebookTask selects NotebookTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_NotebookTask struct { + NotebookTask ResolvedValues_NotebookTaskResolvedValues +} + +func (*ResolvedValues_Resolved_NotebookTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_SparkJarTask selects SparkJarTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_SparkJarTask struct { + SparkJarTask ResolvedValues_SparkJarTaskResolvedValues +} + +func (*ResolvedValues_Resolved_SparkJarTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_SparkPythonTask selects SparkPythonTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_SparkPythonTask struct { + SparkPythonTask ResolvedValues_SparkPythonTaskResolvedValues +} + +func (*ResolvedValues_Resolved_SparkPythonTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_SparkSubmitTask selects SparkSubmitTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_SparkSubmitTask struct { + SparkSubmitTask ResolvedValues_SparkSubmitTaskResolvedValues +} + +func (*ResolvedValues_Resolved_SparkSubmitTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_PythonWheelTask selects PythonWheelTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_PythonWheelTask struct { + PythonWheelTask ResolvedValues_PythonWheelTaskResolvedValues +} + +func (*ResolvedValues_Resolved_PythonWheelTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_DbtTask selects DbtTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_DbtTask struct { + DbtTask ResolvedValues_DbtTaskResolvedValues +} + +func (*ResolvedValues_Resolved_DbtTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_SqlTask selects SqlTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_SqlTask struct { + SqlTask ResolvedValues_SqlTaskResolvedValues +} + +func (*ResolvedValues_Resolved_SqlTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_RunJobTask selects RunJobTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_RunJobTask struct { + RunJobTask ResolvedValues_RunJobTaskResolvedValues +} + +func (*ResolvedValues_Resolved_RunJobTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_ConditionTask selects ConditionTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_ConditionTask struct { + ConditionTask ResolvedValues_ConditionTaskResolvedValues +} + +func (*ResolvedValues_Resolved_ConditionTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_SimulationTask selects SimulationTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_SimulationTask struct { + SimulationTask ResolvedValues_SimulationTaskResolvedValues +} + +func (*ResolvedValues_Resolved_SimulationTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_PipelineTask selects PipelineTask for ResolvedValues.Resolved. +type ResolvedValues_Resolved_PipelineTask struct { + PipelineTask ResolvedValues_PipelineTaskResolvedValues +} + +func (*ResolvedValues_Resolved_PipelineTask) isResolvedValues_Resolved() {} + +// ResolvedValues_Resolved_AiRuntimeTask selects AiRuntimeTask for ResolvedValues.Resolved. +// Resolved values for an AI Runtime task — env_vars with +// `{{tasks..values.}}` references substituted to concrete values +// before submission to the training service. +type ResolvedValues_Resolved_AiRuntimeTask struct { + AiRuntimeTask ResolvedValues_AiRuntimeTaskResolvedValues +} + +func (*ResolvedValues_Resolved_AiRuntimeTask) isResolvedValues_Resolved() {} + +// Resolved values for an AiRuntimeTask after dynamic-value substitution, so +// Jobs can expand `{{tasks..values.}}` references before submission.. +type ResolvedValues_AiRuntimeTaskResolvedValues struct { +} + +type ResolvedValues_ConditionTaskResolvedValues struct { + Left *string + Right *string +} + +type ResolvedValues_DbtTaskResolvedValues struct { + Commands []string +} + +type ResolvedValues_NotebookTaskResolvedValues struct { + BaseParameters map[string]string +} + +type ResolvedValues_PipelineTaskResolvedValues struct { + // Key/value-map of parameters passed to the pipeline execution. Limited to 10k + // characters in total. + PipelineTaskParameters map[string]string +} + +type ResolvedValues_PythonWheelTaskResolvedValues struct { + Parameters []string + NamedParameters map[string]string +} + +type ResolvedValues_RunJobTaskResolvedValues struct { + Parameters map[string]string + JobParameters map[string]string +} + +type ResolvedValues_SimulationTaskResolvedValues struct { + Parameters map[string]string +} + +type ResolvedValues_SparkJarTaskResolvedValues struct { + Parameters []string +} + +type ResolvedValues_SparkPythonTaskResolvedValues struct { +} + +type ResolvedValues_SparkSubmitTaskResolvedValues struct { +} + +type ResolvedValues_SqlTaskResolvedValues struct { + Parameters map[string]string +} + +type Run struct { + // The canonical identifier of the job that contains this run. + JobId *int64 + // The canonical identifier of the run. This ID is unique across all runs of all + // jobs. + RunId *int64 + // The creator user name. This field won’t be included in the response if the + // user has already been deleted. + CreatorUserName *string + // A unique identifier for this job run. This is set to the same value as + // `run_id`. + NumberInJob *int64 + // If this run is a retry of a prior run attempt, this field contains the run_id + // of the original attempt; otherwise, it is the same as the run_id. + OriginalAttemptRunId *int64 + // Deprecated. Please use the `status` field instead. + State *RunState + // The cron schedule that triggered this run if it was triggered by the periodic + // scheduler. + Schedule *CronSchedule + // A snapshot of the job’s cluster specification when this run was created. + ClusterSpec *ClusterSpec + // The cluster used for this run. If the run is specified to use a new cluster, + // this field is set once the Jobs service has requested a cluster for the run. + ClusterInstance *ClusterInstance + // Job-level parameters used in the run + JobParameters []Run_JobLevelParameters + // The parameters used for this run. + OverridingParameters *RunParameters + Trigger TriggerType + TriggerInfo *RunTriggerInfo + // An optional name for the run. The maximum length is 4096 bytes in UTF-8 + // encoding. + RunName *string + // The URL to the detail page of the run. + RunPageUrl *string + RunType RunType + // The list of tasks performed by the run. Each task has its own `run_id` which + // you can use to call `JobsGetOutput` to retrieve the run results. If more than + // 100 tasks are available, you can paginate through them using + // :method:jobs/getrun. Use the `next_page_token` field at the object root to + // determine if more results are available. + Tasks []RunTask + // Description of the run + Description *string + // The sequence number of this run attempt for a triggered job run. The initial + // attempt of a run has an attempt_number of 0. If the initial run attempt + // fails, and the job has a retry policy (`max_retries` > 0), subsequent runs + // are created with an `original_attempt_run_id` of the original attempt’s ID + // and an incrementing `attempt_number`. Runs are retried only until they + // succeed, and the maximum `attempt_number` is the same as the `max_retries` + // value for the job. + AttemptNumber *int + // A list of job cluster specifications that can be shared and reused by tasks + // of this job. Libraries cannot be declared in a shared job cluster. You must + // declare dependent libraries in task settings. If more than 100 job clusters + // are available, you can paginate through them using :method:jobs/getrun. + JobClusters []JobCluster + // An optional specification for a remote Git repository containing the source + // code used by tasks. Version-controlled source code is supported by notebook, + // dbt, Python script, and SQL File tasks. + // + // If `git_source` is set, these tasks retrieve the file from the remote + // repository by default. However, this behavior can be overridden by setting + // `source` to `WORKSPACE` on the task. + // + // Note: dbt and SQL File tasks support only version-controlled sources. If dbt + // or SQL File tasks are used, `git_source` must be defined on the job. + GitSource *GitSource + // The repair history of the run. + RepairHistory []Repair + Status *RunStatus + // ID of the job run that this run belongs to. For legacy and single-task job + // runs the field is populated with the job run ID. For task runs, the field is + // populated with the ID of the job run that the task run belongs to. + JobRunId *int64 + // Indicates if the run has more array properties (`tasks`, `job_clusters`) that + // are not shown. They can be accessed via :method:jobs/getrun endpoint. It is + // only relevant for API 2.2 :method:jobs/listruns requests with + // `expand_tasks=true`. + HasMore *bool + // The actual performance target used by the serverless run during execution. + // This can differ from the client-set performance target on the request + // depending on whether the performance mode is supported by the job type. + // + // * `STANDARD`: Enables cost-efficient execution of serverless workloads. * + // `PERFORMANCE_OPTIMIZED`: Prioritizes fast startup and execution times through + // rapid scaling and optimized cluster performance. + EffectivePerformanceTarget PerformanceTarget_PerformanceTarget + // The id of the usage policy used by this run for cost attribution purposes. + EffectiveUsagePolicyId *string + // ID of the deployment that produced the job when this run was created. Used to + // look up deployment metadata from the Deployment Metadata service. Only set + // for job runs of jobs with a `BUNDLE` deployment. + DeploymentId *string + // ID of the deployment version that produced the job when this run was created. + // Identifies a specific snapshot of the deployment in the Deployment Metadata + // service. Only set for job runs of jobs with a `BUNDLE` deployment. + VersionId *string + // The time at which this run was started in epoch milliseconds (milliseconds + // since 1/1/1970 UTC). This may not be the time when the job task starts + // executing, for example, if the job is scheduled to run on a new cluster, this + // is the time the cluster creation call is issued. + StartTime *int64 + // The time in milliseconds it took to set up the cluster. For runs that run on + // new clusters this is the cluster creation time, for runs that run on existing + // clusters this time should be very short. The duration of a task run is the + // sum of the `setup_duration`, `execution_duration`, and the + // `cleanup_duration`. The `setup_duration` field is set to 0 for multitask job + // runs. The total duration of a multitask job run is the value of the + // `run_duration` field. + SetupDuration *int64 + // The time in milliseconds it took to execute the commands in the JAR or + // notebook until they completed, failed, timed out, were cancelled, or + // encountered an unexpected error. The duration of a task run is the sum of the + // `setup_duration`, `execution_duration`, and the `cleanup_duration`. The + // `execution_duration` field is set to 0 for multitask job runs. The total + // duration of a multitask job run is the value of the `run_duration` field. + ExecutionDuration *int64 + // The time in milliseconds it took to terminate the cluster and clean up any + // associated artifacts. The duration of a task run is the sum of the + // `setup_duration`, `execution_duration`, and the `cleanup_duration`. The + // `cleanup_duration` field is set to 0 for multitask job runs. The total + // duration of a multitask job run is the value of the `run_duration` field. + CleanupDuration *int64 + // The time at which this run ended in epoch milliseconds (milliseconds since + // 1/1/1970 UTC). This field is set to 0 if the job is still running. + EndTime *int64 + // The time in milliseconds it took the job run and all of its repairs to + // finish. + RunDuration *int64 + // The time in milliseconds that the run has spent in the queue. + QueueDuration *int64 +} + +type Run_JobLevelParameters struct { + // The name of the parameter + Name *string + // The optional default value of the parameter + Default *string + // The value used in the run + Value *string +} + +type RunJobTask struct { + // ID of the job to trigger. + JobId *int64 + // Job-level parameters used to trigger the job. + JobParameters map[string]string + // Controls whether the pipeline should perform a full refresh + PipelineParams *PipelineParameters + // A list of parameters for jobs with Spark JAR tasks, for example + // `"jar_params": ["john doe", "35"]`. The parameters are used to invoke the + // main function of the main class specified in the Spark JAR task. If not + // specified upon `run-now`, it defaults to an empty list. jar_params cannot be + // specified in conjunction with notebook_params. The JSON representation of + // this field (for example `{"jar_params":["john doe","35"]}`) cannot exceed + // 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + JarParams []string + // A map from keys to values for jobs with notebook task, for example + // `"notebook_params": {"name": "john doe", "age": "35"}`. The map is passed to + // the notebook and is accessible through the + // [dbutils.widgets.get](/dev-tools/databricks-utils.html) function. + // + // If not specified upon `run-now`, the triggered run uses the job’s base + // parameters. + // + // notebook_params cannot be specified in conjunction with jar_params. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // The JSON representation of this field (for example + // `{"notebook_params":{"name":"john doe","age":"35"}}`) cannot exceed 10,000 + // bytes. + NotebookParams map[string]string + // A list of parameters for jobs with Python tasks, for example + // `"python_params": ["john doe", "35"]`. The parameters are passed to Python + // file as command-line parameters. If specified upon `run-now`, it would + // overwrite the parameters specified in job setting. The JSON representation of + // this field (for example `{"python_params":["john doe","35"]}`) cannot exceed + // 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // Important + // + // These parameters accept only Latin characters (ASCII character set). Using + // non-ASCII characters returns an error. Examples of invalid, non-ASCII + // characters are Chinese, Japanese kanjis, and emojis. + PythonParams []string + // A list of parameters for jobs with spark submit task, for example + // `"spark_submit_params": ["--class", "org.apache.spark.examples.SparkPi"]`. + // The parameters are passed to spark-submit script as command-line parameters. + // If specified upon `run-now`, it would overwrite the parameters specified in + // job setting. The JSON representation of this field (for example + // `{"python_params":["john doe","35"]}`) cannot exceed 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // Important + // + // These parameters accept only Latin characters (ASCII character set). Using + // non-ASCII characters returns an error. Examples of invalid, non-ASCII + // characters are Chinese, Japanese kanjis, and emojis. + SparkSubmitParams []string + PythonNamedParams map[string]string + // A map from keys to values for jobs with SQL task, for example `"sql_params": + // {"name": "john doe", "age": "35"}`. The SQL alert task does not support + // custom parameters. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + SqlParams map[string]string + // An array of commands to execute for jobs with the dbt task, for example + // `"dbt_commands": ["dbt deps", "dbt seed", "dbt deps", "dbt seed", "dbt run"]` + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + DbtCommands []string +} + +type RunJobTask_RunJobTaskOutput struct { + // The run id of the triggered job run + RunId *int64 +} + +type RunLifeCycleState struct { +} + +type RunLifecycleStateV2 struct { +} + +type RunNowRequest struct { + // The ID of the job to be executed + JobId *int64 + // Job-level parameters used in the run. for example `"param": "overriding_val"` + JobParameters map[string]string + // An optional token to guarantee the idempotency of job run requests. If a run + // with the provided token already exists, the request does not create a new run + // but returns the ID of the existing run instead. If a run with the provided + // token is deleted, an error is returned. + // + // If you specify the idempotency token, upon failure you can retry until the + // request succeeds. guarantees that exactly one run is launched + // with that idempotency token. + // + // This token must have at most 64 characters. + IdempotencyToken *string + // The queue settings of the run. + Queue *QueueSettings + // A list of task keys to run inside of the job. If this field is not provided, + // all tasks in the job will be run. + // + // Prefix a task key with `+` to also run its upstream tasks, or suffix it with + // `+` to also run its downstream tasks. For example, `+my_task` runs `my_task` + // and everything upstream of it, `my_task+` runs `my_task` and everything + // downstream of it, and `+my_task+` runs both. A task key with no `+` runs only + // that task. + Only []string + // The performance mode on a serverless job. The performance target determines + // the level of compute performance or cost-efficiency for the run. This field + // overrides the performance target defined on the job level. + // + // * `STANDARD`: Enables cost-efficient execution of serverless workloads. * + // `PERFORMANCE_OPTIMIZED`: Prioritizes fast startup and execution times through + // rapid scaling and optimized cluster performance. + PerformanceTarget PerformanceTarget_PerformanceTarget + // Controls whether the pipeline should perform a full refresh + PipelineParams *PipelineParameters + // A list of parameters for jobs with Spark JAR tasks, for example + // `"jar_params": ["john doe", "35"]`. The parameters are used to invoke the + // main function of the main class specified in the Spark JAR task. If not + // specified upon `run-now`, it defaults to an empty list. jar_params cannot be + // specified in conjunction with notebook_params. The JSON representation of + // this field (for example `{"jar_params":["john doe","35"]}`) cannot exceed + // 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + JarParams []string + // A map from keys to values for jobs with notebook task, for example + // `"notebook_params": {"name": "john doe", "age": "35"}`. The map is passed to + // the notebook and is accessible through the + // [dbutils.widgets.get](/dev-tools/databricks-utils.html) function. + // + // If not specified upon `run-now`, the triggered run uses the job’s base + // parameters. + // + // notebook_params cannot be specified in conjunction with jar_params. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // The JSON representation of this field (for example + // `{"notebook_params":{"name":"john doe","age":"35"}}`) cannot exceed 10,000 + // bytes. + NotebookParams map[string]string + // A list of parameters for jobs with Python tasks, for example + // `"python_params": ["john doe", "35"]`. The parameters are passed to Python + // file as command-line parameters. If specified upon `run-now`, it would + // overwrite the parameters specified in job setting. The JSON representation of + // this field (for example `{"python_params":["john doe","35"]}`) cannot exceed + // 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // Important + // + // These parameters accept only Latin characters (ASCII character set). Using + // non-ASCII characters returns an error. Examples of invalid, non-ASCII + // characters are Chinese, Japanese kanjis, and emojis. + PythonParams []string + // A list of parameters for jobs with spark submit task, for example + // `"spark_submit_params": ["--class", "org.apache.spark.examples.SparkPi"]`. + // The parameters are passed to spark-submit script as command-line parameters. + // If specified upon `run-now`, it would overwrite the parameters specified in + // job setting. The JSON representation of this field (for example + // `{"python_params":["john doe","35"]}`) cannot exceed 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // Important + // + // These parameters accept only Latin characters (ASCII character set). Using + // non-ASCII characters returns an error. Examples of invalid, non-ASCII + // characters are Chinese, Japanese kanjis, and emojis. + SparkSubmitParams []string + PythonNamedParams map[string]string + // A map from keys to values for jobs with SQL task, for example `"sql_params": + // {"name": "john doe", "age": "35"}`. The SQL alert task does not support + // custom parameters. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + SqlParams map[string]string + // An array of commands to execute for jobs with the dbt task, for example + // `"dbt_commands": ["dbt deps", "dbt seed", "dbt deps", "dbt seed", "dbt run"]` + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + DbtCommands []string +} + +// Run was started successfully.. +type RunNowResponse struct { + // The globally unique ID of the newly triggered run. + RunId *int64 + // A unique identifier for this job run. This is set to the same value as + // `run_id`. + NumberInJob *int64 +} + +type RunParameters struct { + // Controls whether the pipeline should perform a full refresh + PipelineParams *PipelineParameters + // A list of parameters for jobs with Spark JAR tasks, for example + // `"jar_params": ["john doe", "35"]`. The parameters are used to invoke the + // main function of the main class specified in the Spark JAR task. If not + // specified upon `run-now`, it defaults to an empty list. jar_params cannot be + // specified in conjunction with notebook_params. The JSON representation of + // this field (for example `{"jar_params":["john doe","35"]}`) cannot exceed + // 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + JarParams []string + // A map from keys to values for jobs with notebook task, for example + // `"notebook_params": {"name": "john doe", "age": "35"}`. The map is passed to + // the notebook and is accessible through the + // [dbutils.widgets.get](/dev-tools/databricks-utils.html) function. + // + // If not specified upon `run-now`, the triggered run uses the job’s base + // parameters. + // + // notebook_params cannot be specified in conjunction with jar_params. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // The JSON representation of this field (for example + // `{"notebook_params":{"name":"john doe","age":"35"}}`) cannot exceed 10,000 + // bytes. + NotebookParams map[string]string + // A list of parameters for jobs with Python tasks, for example + // `"python_params": ["john doe", "35"]`. The parameters are passed to Python + // file as command-line parameters. If specified upon `run-now`, it would + // overwrite the parameters specified in job setting. The JSON representation of + // this field (for example `{"python_params":["john doe","35"]}`) cannot exceed + // 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // Important + // + // These parameters accept only Latin characters (ASCII character set). Using + // non-ASCII characters returns an error. Examples of invalid, non-ASCII + // characters are Chinese, Japanese kanjis, and emojis. + PythonParams []string + // A list of parameters for jobs with spark submit task, for example + // `"spark_submit_params": ["--class", "org.apache.spark.examples.SparkPi"]`. + // The parameters are passed to spark-submit script as command-line parameters. + // If specified upon `run-now`, it would overwrite the parameters specified in + // job setting. The JSON representation of this field (for example + // `{"python_params":["john doe","35"]}`) cannot exceed 10,000 bytes. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + // + // Important + // + // These parameters accept only Latin characters (ASCII character set). Using + // non-ASCII characters returns an error. Examples of invalid, non-ASCII + // characters are Chinese, Japanese kanjis, and emojis. + SparkSubmitParams []string + PythonNamedParams map[string]string + // A map from keys to values for jobs with SQL task, for example `"sql_params": + // {"name": "john doe", "age": "35"}`. The SQL alert task does not support + // custom parameters. + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + SqlParams map[string]string + // An array of commands to execute for jobs with the dbt task, for example + // `"dbt_commands": ["dbt deps", "dbt seed", "dbt deps", "dbt seed", "dbt run"]` + // + // ⚠ **Deprecation note** Use [job + // parameters](/jobs/job-parameters.html#job-parameter-pushdown) to pass + // information down to tasks. + DbtCommands []string +} + +type RunResultState struct { +} + +// The current state of the run.. +type RunState struct { + // A value indicating the run's current lifecycle state. This field is always + // available in the response. Note: Additional states might be introduced in + // future releases. + LifeCycleState RunLifeCycleState_RunLifeCycleState + // A value indicating the run's result. This field is only available for + // terminal lifecycle states. Note: Additional states might be introduced in + // future releases. + ResultState RunResultState_RunResultState + // A descriptive message for the current state. This field is unstructured, and + // its exact format is subject to change. + StateMessage *string + // A value indicating whether a run was canceled manually by a user or by the + // scheduler because the run timed out. + UserCancelledOrTimedout *bool + // The reason indicating why the run was queued. + QueueReason *string +} + +// The current status of the run. +type RunStatus struct { + State RunLifecycleStateV2_State + // If the run is in a TERMINATING or TERMINATED state, details about the reason + // for terminating the run. + TerminationDetails *TerminationDetails + // If the run was queued, details about the reason for queuing the run. + QueueDetails *QueueDetails +} + +// Used when outputting a child run, in GetRun or ListRuns.. +type RunTask struct { + // The ID of the task run. + RunId *int64 + // Deprecated. Please use the `status` field instead. + State *RunState + RunPageUrl *string + // The cluster used for this run. If the run is specified to use a new cluster, + // this field is set once the Jobs service has requested a cluster for the run. + ClusterInstance *ClusterInstance + // The sequence number of this run attempt for a triggered job run. The initial + // attempt of a run has an attempt_number of 0. If the initial run attempt + // fails, and the job has a retry policy (`max_retries` > 0), subsequent runs + // are created with an `original_attempt_run_id` of the original attempt’s ID + // and an incrementing `attempt_number`. Runs are retried only until they + // succeed, and the maximum `attempt_number` is the same as the `max_retries` + // value for the job. + AttemptNumber *int + // An optional specification for a remote Git repository containing the source + // code used by tasks. Version-controlled source code is supported by notebook, + // dbt, Python script, and SQL File tasks. If `git_source` is set, these tasks + // retrieve the file from the remote repository by default. However, this + // behavior can be overridden by setting `source` to `WORKSPACE` on the task. + // Note: dbt and SQL File tasks support only version-controlled sources. If dbt + // or SQL File tasks are used, `git_source` must be defined on the job. + GitSource *GitSource + // Parameter values including resolved references + ResolvedValues *ResolvedValues + Status *RunStatus + // The actual performance target used by the serverless run during execution. + // This can differ from the client-set performance target on the request + // depending on whether the performance mode is supported by the job type. + // + // * `STANDARD`: Enables cost-efficient execution of serverless workloads. * + // `PERFORMANCE_OPTIMIZED`: Prioritizes fast startup and execution times through + // rapid scaling and optimized cluster performance. + EffectivePerformanceTarget PerformanceTarget_PerformanceTarget + // The id of the serverless compute this task ran on, either explicitly + // configured on the task or the workspace default. Only set once the compute + // has been resolved at run trigger. + EffectiveServerlessComputeId *string + // A unique name for the task. This field is used to refer to this task from + // other tasks. This field is required and must be unique within its parent job. + // On Update or Reset, this field is used to reference the tasks to be updated + // or reset. + TaskKey *string + // An optional description for this task. + Description *string + // An optional array of objects specifying the dependency graph of the task. All + // tasks specified in this field must complete successfully before executing + // this task. The key is `task_key`, and the value is the name assigned to the + // dependent task. + DependsOn []TaskDependency + // An optional value indicating the condition that determines whether the task + // should be run once its dependencies have been completed. When omitted, + // defaults to `ALL_SUCCESS`. See :method:jobs/create for a list of possible + // values. + RunIf TaskDependencyType + // An optional timeout applied to each run of this job task. A value of `0` + // means no timeout. + TimeoutSeconds *int + // An optional set of email addresses notified when the task run begins or + // completes. The default behavior is to not send any emails. + EmailNotifications *JobEmailNotifications + Health *JobsHealthRules + // Optional notification settings that are used when sending notifications to + // each of the `email_notifications` and `webhook_notifications` for this task + // run. + NotificationSettings *NotificationSettings + // A collection of system notification IDs to notify when the run begins or + // completes. The default behavior is to not send any system notifications. Task + // webhooks respect the task notification settings. + WebhookNotifications *WebhookNotifications + EnvironmentRef isRunTask_EnvironmentRef + // An optional flag to disable the task. If set to true, the task will not run + // even if it is part of a job. + Disabled *bool + // Task level compute configuration. + Compute *Compute + // DO NOT ADD ANY NEW FIELDS TO JobTask OUTSIDE OF THIS ONEOF as it will break + // the TaskRegistry + Task isRunTask_Task + Spec isRunTask_Spec + // An optional list of libraries to be installed on the cluster. The default + // value is an empty list. + Libraries []Library + // An optional maximum number of times to retry an unsuccessful run. A run is + // considered to be unsuccessful if it completes with the `FAILED` result_state + // or `INTERNAL_ERROR` `life_cycle_state`. The value `-1` means to retry + // indefinitely and the value `0` means to never retry. + MaxRetries *int + // An optional minimal interval in milliseconds between the start of the failed + // run and the subsequent retry run. The default behavior is that unsuccessful + // runs are immediately retried. + MinRetryIntervalMillis *int + // An optional policy to specify whether to retry a job when it times out. The + // default behavior is to not retry on timeout. + RetryOnTimeout *bool + // An option to disable auto optimization in serverless + DisableAutoOptimization *bool + // The time at which this run was started in epoch milliseconds (milliseconds + // since 1/1/1970 UTC). This may not be the time when the job task starts + // executing, for example, if the job is scheduled to run on a new cluster, this + // is the time the cluster creation call is issued. + StartTime *int64 + // The time in milliseconds it took to set up the cluster. For runs that run on + // new clusters this is the cluster creation time, for runs that run on existing + // clusters this time should be very short. The duration of a task run is the + // sum of the `setup_duration`, `execution_duration`, and the + // `cleanup_duration`. The `setup_duration` field is set to 0 for multitask job + // runs. The total duration of a multitask job run is the value of the + // `run_duration` field. + SetupDuration *int64 + // The time in milliseconds it took to execute the commands in the JAR or + // notebook until they completed, failed, timed out, were cancelled, or + // encountered an unexpected error. The duration of a task run is the sum of the + // `setup_duration`, `execution_duration`, and the `cleanup_duration`. The + // `execution_duration` field is set to 0 for multitask job runs. The total + // duration of a multitask job run is the value of the `run_duration` field. + ExecutionDuration *int64 + // The time in milliseconds it took to terminate the cluster and clean up any + // associated artifacts. The duration of a task run is the sum of the + // `setup_duration`, `execution_duration`, and the `cleanup_duration`. The + // `cleanup_duration` field is set to 0 for multitask job runs. The total + // duration of a multitask job run is the value of the `run_duration` field. + CleanupDuration *int64 + // The time at which this run ended in epoch milliseconds (milliseconds since + // 1/1/1970 UTC). This field is set to 0 if the job is still running. + EndTime *int64 + // The time in milliseconds it took the job run and all of its repairs to + // finish. + RunDuration *int64 + // The time in milliseconds that the run has spent in the queue. + QueueDuration *int64 +} + +type isRunTask_EnvironmentRef interface { + isRunTask_EnvironmentRef() +} + +// RunTask_EnvironmentRef_EnvironmentKey selects EnvironmentKey for RunTask.EnvironmentRef. +// The key that references an environment spec in a job. This field is required +// for Python script, Python wheel and dbt tasks when using serverless compute. +type RunTask_EnvironmentRef_EnvironmentKey struct { + EnvironmentKey string +} + +func (*RunTask_EnvironmentRef_EnvironmentKey) isRunTask_EnvironmentRef() {} + +type isRunTask_Task interface { + isRunTask_Task() +} + +// RunTask_Task_NotebookTask selects NotebookTask for RunTask.Task. +// The task runs a notebook when the `notebook_task` field is present. +type RunTask_Task_NotebookTask struct { + NotebookTask NotebookTask +} + +func (*RunTask_Task_NotebookTask) isRunTask_Task() {} + +// RunTask_Task_SparkJarTask selects SparkJarTask for RunTask.Task. +// The task runs a JAR when the `spark_jar_task` field is present. +type RunTask_Task_SparkJarTask struct { + SparkJarTask SparkJarTask +} + +func (*RunTask_Task_SparkJarTask) isRunTask_Task() {} + +// RunTask_Task_SparkPythonTask selects SparkPythonTask for RunTask.Task. +// The task runs a Python file when the `spark_python_task` field is present. +type RunTask_Task_SparkPythonTask struct { + SparkPythonTask SparkPythonTask +} + +func (*RunTask_Task_SparkPythonTask) isRunTask_Task() {} + +// RunTask_Task_SparkSubmitTask selects SparkSubmitTask for RunTask.Task. +// (Legacy) The task runs the spark-submit script when the spark_submit_task +// field is present. Databricks recommends using the spark_jar_task instead; see +// [Spark Submit task for jobs](/jobs/spark-submit). +type RunTask_Task_SparkSubmitTask struct { + SparkSubmitTask SparkSubmitTask +} + +func (*RunTask_Task_SparkSubmitTask) isRunTask_Task() {} + +// RunTask_Task_PipelineTask selects PipelineTask for RunTask.Task. +// The task triggers a pipeline update when the `pipeline_task` field is +// present. Only pipelines configured to use triggered more are supported. +type RunTask_Task_PipelineTask struct { + PipelineTask PipelineTask +} + +func (*RunTask_Task_PipelineTask) isRunTask_Task() {} + +// RunTask_Task_PythonWheelTask selects PythonWheelTask for RunTask.Task. +// The task runs a Python wheel when the `python_wheel_task` field is present. +type RunTask_Task_PythonWheelTask struct { + PythonWheelTask PythonWheelTask +} + +func (*RunTask_Task_PythonWheelTask) isRunTask_Task() {} + +// RunTask_Task_DbtTask selects DbtTask for RunTask.Task. +// The task runs one or more dbt commands when the `dbt_task` field is present. +// The dbt task requires both Databricks SQL and the ability to use a serverless +// or a pro SQL warehouse. +type RunTask_Task_DbtTask struct { + DbtTask DbtTask +} + +func (*RunTask_Task_DbtTask) isRunTask_Task() {} + +// RunTask_Task_SqlTask selects SqlTask for RunTask.Task. +// The task runs a SQL query or file, or it refreshes a SQL alert or a legacy +// SQL dashboard when the `sql_task` field is present. +type RunTask_Task_SqlTask struct { + SqlTask SqlTask +} + +func (*RunTask_Task_SqlTask) isRunTask_Task() {} + +// RunTask_Task_RunJobTask selects RunJobTask for RunTask.Task. +// The task triggers another job when the `run_job_task` field is present. +type RunTask_Task_RunJobTask struct { + RunJobTask RunJobTask +} + +func (*RunTask_Task_RunJobTask) isRunTask_Task() {} + +// RunTask_Task_ConditionTask selects ConditionTask for RunTask.Task. +// The task evaluates a condition that can be used to control the execution of +// other tasks when the `condition_task` field is present. The condition task +// does not require a cluster to execute and does not support retries or +// notifications. +type RunTask_Task_ConditionTask struct { + ConditionTask ConditionTask +} + +func (*RunTask_Task_ConditionTask) isRunTask_Task() {} + +// RunTask_Task_ForEachTask selects ForEachTask for RunTask.Task. +// The task executes a nested task for every input provided when the +// `for_each_task` field is present. +type RunTask_Task_ForEachTask struct { + ForEachTask ForEachTask +} + +func (*RunTask_Task_ForEachTask) isRunTask_Task() {} + +// RunTask_Task_CleanRoomsNotebookTask selects CleanRoomsNotebookTask for RunTask.Task. +// The task runs a [clean rooms](/clean-rooms/index.html) notebook when the +// `clean_rooms_notebook_task` field is present. +type RunTask_Task_CleanRoomsNotebookTask struct { + CleanRoomsNotebookTask CleanRoomsNotebookTask +} + +func (*RunTask_Task_CleanRoomsNotebookTask) isRunTask_Task() {} + +// RunTask_Task_GenAiComputeTask selects GenAiComputeTask for RunTask.Task. +type RunTask_Task_GenAiComputeTask struct { + GenAiComputeTask GenAiComputeTask +} + +func (*RunTask_Task_GenAiComputeTask) isRunTask_Task() {} + +// RunTask_Task_AlertTask selects AlertTask for RunTask.Task. +// The task evaluates a alert and sends notifications to +// subscribers when the `alert_task` field is present. +type RunTask_Task_AlertTask struct { + AlertTask AlertTask +} + +func (*RunTask_Task_AlertTask) isRunTask_Task() {} + +// RunTask_Task_PowerBiTask selects PowerBiTask for RunTask.Task. +// The task triggers a Power BI semantic model update when the `power_bi_task` +// field is present. +type RunTask_Task_PowerBiTask struct { + PowerBiTask PowerBiTask +} + +func (*RunTask_Task_PowerBiTask) isRunTask_Task() {} + +// RunTask_Task_DashboardTask selects DashboardTask for RunTask.Task. +// The task refreshes a dashboard and sends a snapshot to subscribers. +type RunTask_Task_DashboardTask struct { + DashboardTask DashboardTask +} + +func (*RunTask_Task_DashboardTask) isRunTask_Task() {} + +// RunTask_Task_DbtCloudTask selects DbtCloudTask for RunTask.Task. +// Task type for dbt cloud, deprecated in favor of the new name +// dbt_platform_task +type RunTask_Task_DbtCloudTask struct { + DbtCloudTask DbtCloudTask +} + +func (*RunTask_Task_DbtCloudTask) isRunTask_Task() {} + +// RunTask_Task_DbtPlatformTask selects DbtPlatformTask for RunTask.Task. +type RunTask_Task_DbtPlatformTask struct { + DbtPlatformTask DbtPlatformTask +} + +func (*RunTask_Task_DbtPlatformTask) isRunTask_Task() {} + +// RunTask_Task_PythonOperatorTask selects PythonOperatorTask for RunTask.Task. +// The task runs a Python operator task. +type RunTask_Task_PythonOperatorTask struct { + PythonOperatorTask PythonOperatorTask +} + +func (*RunTask_Task_PythonOperatorTask) isRunTask_Task() {} + +// RunTask_Task_AiRuntimeTask selects AiRuntimeTask for RunTask.Task. +// The task runs a multi-gpu compute workload on Databricks AI Runtime. Specify +// the accelerator type and count, the command to run, and where the workload's +// code and MLflow output are stored. +type RunTask_Task_AiRuntimeTask struct { + AiRuntimeTask AiRuntimeTask +} + +func (*RunTask_Task_AiRuntimeTask) isRunTask_Task() {} + +type isRunTask_Spec interface { + isRunTask_Spec() +} + +// RunTask_Spec_ExistingClusterId selects ExistingClusterId for RunTask.Spec. +// If existing_cluster_id, the ID of an existing cluster that is used for all +// runs. When running jobs or tasks on an existing cluster, you may need to +// manually restart the cluster if it stops responding. We suggest running jobs +// and tasks on new clusters for greater reliability +type RunTask_Spec_ExistingClusterId struct { + ExistingClusterId string +} + +func (*RunTask_Spec_ExistingClusterId) isRunTask_Spec() {} + +// RunTask_Spec_NewCluster selects NewCluster for RunTask.Spec. +// If new_cluster, a description of a new cluster that is created for each run. +type RunTask_Spec_NewCluster struct { + NewCluster ClusterSpec_NewCluster +} + +func (*RunTask_Spec_NewCluster) isRunTask_Spec() {} + +// RunTask_Spec_JobClusterKey selects JobClusterKey for RunTask.Spec. +// If job_cluster_key, this task is executed reusing the cluster specified in +// `job.settings.job_clusters`. +type RunTask_Spec_JobClusterKey struct { + JobClusterKey string +} + +func (*RunTask_Spec_JobClusterKey) isRunTask_Spec() {} + +type RunTaskSettings struct { + // A unique name for the task. This field is used to refer to this task from + // other tasks. This field is required and must be unique within its parent job. + // On Update or Reset, this field is used to reference the tasks to be updated + // or reset. + TaskKey *string + // An optional description for this task. + Description *string + // An optional array of objects specifying the dependency graph of the task. All + // tasks specified in this field must complete successfully before executing + // this task. The key is `task_key`, and the value is the name assigned to the + // dependent task. + DependsOn []TaskDependency + // An optional value indicating the condition that determines whether the task + // should be run once its dependencies have been completed. When omitted, + // defaults to `ALL_SUCCESS`. See :method:jobs/create for a list of possible + // values. + RunIf TaskDependencyType + // An optional timeout applied to each run of this job task. A value of `0` + // means no timeout. + TimeoutSeconds *int + // An optional set of email addresses notified when the task run begins or + // completes. The default behavior is to not send any emails. + EmailNotifications *JobEmailNotifications + Health *JobsHealthRules + // Optional notification settings that are used when sending notifications to + // each of the `email_notifications` and `webhook_notifications` for this task + // run. + NotificationSettings *NotificationSettings + // A collection of system notification IDs to notify when the run begins or + // completes. The default behavior is to not send any system notifications. Task + // webhooks respect the task notification settings. + WebhookNotifications *WebhookNotifications + EnvironmentRef isRunTaskSettings_EnvironmentRef + // An optional flag to disable the task. If set to true, the task will not run + // even if it is part of a job. + Disabled *bool + // Task level compute configuration. + Compute *Compute + // DO NOT ADD ANY NEW FIELDS TO JobTask OUTSIDE OF THIS ONEOF as it will break + // the TaskRegistry + Task isRunTaskSettings_Task + Spec isRunTaskSettings_Spec + // An optional list of libraries to be installed on the cluster. The default + // value is an empty list. + Libraries []Library + // An optional maximum number of times to retry an unsuccessful run. A run is + // considered to be unsuccessful if it completes with the `FAILED` result_state + // or `INTERNAL_ERROR` `life_cycle_state`. The value `-1` means to retry + // indefinitely and the value `0` means to never retry. + MaxRetries *int + // An optional minimal interval in milliseconds between the start of the failed + // run and the subsequent retry run. The default behavior is that unsuccessful + // runs are immediately retried. + MinRetryIntervalMillis *int + // An optional policy to specify whether to retry a job when it times out. The + // default behavior is to not retry on timeout. + RetryOnTimeout *bool + // An option to disable auto optimization in serverless + DisableAutoOptimization *bool +} + +type isRunTaskSettings_EnvironmentRef interface { + isRunTaskSettings_EnvironmentRef() +} + +// RunTaskSettings_EnvironmentRef_EnvironmentKey selects EnvironmentKey for RunTaskSettings.EnvironmentRef. +// The key that references an environment spec in a job. This field is required +// for Python script, Python wheel and dbt tasks when using serverless compute. +type RunTaskSettings_EnvironmentRef_EnvironmentKey struct { + EnvironmentKey string +} + +func (*RunTaskSettings_EnvironmentRef_EnvironmentKey) isRunTaskSettings_EnvironmentRef() {} + +type isRunTaskSettings_Task interface { + isRunTaskSettings_Task() +} + +// RunTaskSettings_Task_NotebookTask selects NotebookTask for RunTaskSettings.Task. +// The task runs a notebook when the `notebook_task` field is present. +type RunTaskSettings_Task_NotebookTask struct { + NotebookTask NotebookTask +} + +func (*RunTaskSettings_Task_NotebookTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_SparkJarTask selects SparkJarTask for RunTaskSettings.Task. +// The task runs a JAR when the `spark_jar_task` field is present. +type RunTaskSettings_Task_SparkJarTask struct { + SparkJarTask SparkJarTask +} + +func (*RunTaskSettings_Task_SparkJarTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_SparkPythonTask selects SparkPythonTask for RunTaskSettings.Task. +// The task runs a Python file when the `spark_python_task` field is present. +type RunTaskSettings_Task_SparkPythonTask struct { + SparkPythonTask SparkPythonTask +} + +func (*RunTaskSettings_Task_SparkPythonTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_SparkSubmitTask selects SparkSubmitTask for RunTaskSettings.Task. +// (Legacy) The task runs the spark-submit script when the spark_submit_task +// field is present. Databricks recommends using the spark_jar_task instead; see +// [Spark Submit task for jobs](/jobs/spark-submit). +type RunTaskSettings_Task_SparkSubmitTask struct { + SparkSubmitTask SparkSubmitTask +} + +func (*RunTaskSettings_Task_SparkSubmitTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_PipelineTask selects PipelineTask for RunTaskSettings.Task. +// The task triggers a pipeline update when the `pipeline_task` field is +// present. Only pipelines configured to use triggered more are supported. +type RunTaskSettings_Task_PipelineTask struct { + PipelineTask PipelineTask +} + +func (*RunTaskSettings_Task_PipelineTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_PythonWheelTask selects PythonWheelTask for RunTaskSettings.Task. +// The task runs a Python wheel when the `python_wheel_task` field is present. +type RunTaskSettings_Task_PythonWheelTask struct { + PythonWheelTask PythonWheelTask +} + +func (*RunTaskSettings_Task_PythonWheelTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_DbtTask selects DbtTask for RunTaskSettings.Task. +// The task runs one or more dbt commands when the `dbt_task` field is present. +// The dbt task requires both Databricks SQL and the ability to use a serverless +// or a pro SQL warehouse. +type RunTaskSettings_Task_DbtTask struct { + DbtTask DbtTask +} + +func (*RunTaskSettings_Task_DbtTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_SqlTask selects SqlTask for RunTaskSettings.Task. +// The task runs a SQL query or file, or it refreshes a SQL alert or a legacy +// SQL dashboard when the `sql_task` field is present. +type RunTaskSettings_Task_SqlTask struct { + SqlTask SqlTask +} + +func (*RunTaskSettings_Task_SqlTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_RunJobTask selects RunJobTask for RunTaskSettings.Task. +// The task triggers another job when the `run_job_task` field is present. +type RunTaskSettings_Task_RunJobTask struct { + RunJobTask RunJobTask +} + +func (*RunTaskSettings_Task_RunJobTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_ConditionTask selects ConditionTask for RunTaskSettings.Task. +// The task evaluates a condition that can be used to control the execution of +// other tasks when the `condition_task` field is present. The condition task +// does not require a cluster to execute and does not support retries or +// notifications. +type RunTaskSettings_Task_ConditionTask struct { + ConditionTask ConditionTask +} + +func (*RunTaskSettings_Task_ConditionTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_ForEachTask selects ForEachTask for RunTaskSettings.Task. +// The task executes a nested task for every input provided when the +// `for_each_task` field is present. +type RunTaskSettings_Task_ForEachTask struct { + ForEachTask ForEachTask +} + +func (*RunTaskSettings_Task_ForEachTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_CleanRoomsNotebookTask selects CleanRoomsNotebookTask for RunTaskSettings.Task. +// The task runs a [clean rooms](/clean-rooms/index.html) notebook when the +// `clean_rooms_notebook_task` field is present. +type RunTaskSettings_Task_CleanRoomsNotebookTask struct { + CleanRoomsNotebookTask CleanRoomsNotebookTask +} + +func (*RunTaskSettings_Task_CleanRoomsNotebookTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_GenAiComputeTask selects GenAiComputeTask for RunTaskSettings.Task. +type RunTaskSettings_Task_GenAiComputeTask struct { + GenAiComputeTask GenAiComputeTask +} + +func (*RunTaskSettings_Task_GenAiComputeTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_AlertTask selects AlertTask for RunTaskSettings.Task. +// The task evaluates a alert and sends notifications to +// subscribers when the `alert_task` field is present. +type RunTaskSettings_Task_AlertTask struct { + AlertTask AlertTask +} + +func (*RunTaskSettings_Task_AlertTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_PowerBiTask selects PowerBiTask for RunTaskSettings.Task. +// The task triggers a Power BI semantic model update when the `power_bi_task` +// field is present. +type RunTaskSettings_Task_PowerBiTask struct { + PowerBiTask PowerBiTask +} + +func (*RunTaskSettings_Task_PowerBiTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_DashboardTask selects DashboardTask for RunTaskSettings.Task. +// The task refreshes a dashboard and sends a snapshot to subscribers. +type RunTaskSettings_Task_DashboardTask struct { + DashboardTask DashboardTask +} + +func (*RunTaskSettings_Task_DashboardTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_DbtCloudTask selects DbtCloudTask for RunTaskSettings.Task. +// Task type for dbt cloud, deprecated in favor of the new name +// dbt_platform_task +type RunTaskSettings_Task_DbtCloudTask struct { + DbtCloudTask DbtCloudTask +} + +func (*RunTaskSettings_Task_DbtCloudTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_DbtPlatformTask selects DbtPlatformTask for RunTaskSettings.Task. +type RunTaskSettings_Task_DbtPlatformTask struct { + DbtPlatformTask DbtPlatformTask +} + +func (*RunTaskSettings_Task_DbtPlatformTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_PythonOperatorTask selects PythonOperatorTask for RunTaskSettings.Task. +// The task runs a Python operator task. +type RunTaskSettings_Task_PythonOperatorTask struct { + PythonOperatorTask PythonOperatorTask +} + +func (*RunTaskSettings_Task_PythonOperatorTask) isRunTaskSettings_Task() {} + +// RunTaskSettings_Task_AiRuntimeTask selects AiRuntimeTask for RunTaskSettings.Task. +// The task runs a multi-gpu compute workload on Databricks AI Runtime. Specify +// the accelerator type and count, the command to run, and where the workload's +// code and MLflow output are stored. +type RunTaskSettings_Task_AiRuntimeTask struct { + AiRuntimeTask AiRuntimeTask +} + +func (*RunTaskSettings_Task_AiRuntimeTask) isRunTaskSettings_Task() {} + +type isRunTaskSettings_Spec interface { + isRunTaskSettings_Spec() +} + +// RunTaskSettings_Spec_ExistingClusterId selects ExistingClusterId for RunTaskSettings.Spec. +// If existing_cluster_id, the ID of an existing cluster that is used for all +// runs. When running jobs or tasks on an existing cluster, you may need to +// manually restart the cluster if it stops responding. We suggest running jobs +// and tasks on new clusters for greater reliability +type RunTaskSettings_Spec_ExistingClusterId struct { + ExistingClusterId string +} + +func (*RunTaskSettings_Spec_ExistingClusterId) isRunTaskSettings_Spec() {} + +// RunTaskSettings_Spec_NewCluster selects NewCluster for RunTaskSettings.Spec. +// If new_cluster, a description of a new cluster that is created for each run. +type RunTaskSettings_Spec_NewCluster struct { + NewCluster ClusterSpec_NewCluster +} + +func (*RunTaskSettings_Spec_NewCluster) isRunTaskSettings_Spec() {} + +// RunTaskSettings_Spec_JobClusterKey selects JobClusterKey for RunTaskSettings.Spec. +// If job_cluster_key, this task is executed reusing the cluster specified in +// `job.settings.job_clusters`. +type RunTaskSettings_Spec_JobClusterKey struct { + JobClusterKey string +} + +func (*RunTaskSettings_Spec_JobClusterKey) isRunTaskSettings_Spec() {} + +// Additional details about what triggered the run. +type RunTriggerInfo struct { + // SQL condition evaluation details for this run + SqlCondition *SqlConditionRunInfoDetails + // The run id of the Run Job task run + RunId *int64 +} + +// A storage location in Amazon S3. +type S3StorageInfo struct { + // S3 destination, e.g. `s3://my-bucket/some-prefix` Note that logs will be + // delivered using cluster iam role, please make sure you set cluster iam role + // and the role has write access to the destination. Please also note that you + // cannot use AWS keys to deliver logs. + Destination *string + // S3 region, e.g. `us-west-2`. Either region or endpoint needs to be set. If + // both are set, endpoint will be used. + Region *string + // S3 endpoint, e.g. `https://s3-us-west-2.amazonaws.com`. Either region or + // endpoint needs to be set. If both are set, endpoint will be used. + Endpoint *string + // (Optional) Flag to enable server side encryption, `false` by default. + EnableEncryption *bool + // (Optional) The encryption type, it could be `sse-s3` or `sse-kms`. It will be + // used only when encryption is enabled and the default type is `sse-s3`. + EncryptionType *string + // (Optional) Kms key which will be used if encryption is enabled and encryption + // type is set to `sse-kms`. + KmsKey *string + // (Optional) Set canned access control list for the logs, e.g. + // `bucket-owner-full-control`. If `canned_cal` is set, please make sure the + // cluster iam role has `s3:PutObjectAcl` permission on the destination bucket + // and prefix. The full list of possible canned acl can be found at + // http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl. + // Please also note that by default only the object owner gets full controls. If + // you are using cross account role for writing data, you may want to set + // `bucket-owner-full-control` to make bucket owner able to read the logs. + CannedAcl *string +} + +// Runtime state for a schedule trigger. Currently empty because schedule +// triggers do not expose any trigger-specific runtime state.. +type ScheduleTriggerState struct { +} + +type SparkJarTask struct { + // Deprecated since 04/2016. For classic compute, provide a `jar` through the + // `libraries` field instead. For serverless compute, provide a `jar` though the + // `java_dependencies` field inside the `environments` list. + // + // See the examples of classic and serverless compute usage at the top of the + // page. + JarUri *string + // The full name of the class containing the main method to be executed. This + // class must be contained in a JAR provided as a library. + // + // The code must use `SparkContext.getOrCreate` to obtain a Spark context; + // otherwise, runs of the job fail. + MainClassName *string + // Parameters passed to the main method. + // + // Use [Task parameter variables](/jobs.html#parameter-variables) to set + // parameters containing information about job runs. + Parameters []string + // Deprecated. A value of `false` is no longer supported. + RunAsRepl *bool +} + +type SparkPythonTask struct { + // The Python file to be executed. Cloud file URIs (such as dbfs:/, s3:/, + // adls:/, gcs:/) and workspace paths are supported. For python files stored in + // the workspace, the path must be absolute and begin with `/`. For + // files stored in a remote repository, the path must be relative. This field is + // required. + PythonFile *string + // Command line parameters passed to the Python file. + // + // Use [Task parameter variables](/jobs.html#parameter-variables) to set + // parameters containing information about job runs. + Parameters []string + // Optional location type of the Python file. When set to `WORKSPACE` or not + // specified, the file will be retrieved from the local workspace + // or cloud location (if the `python_file` has a URI format). When set to `GIT`, + // the Python file will be retrieved from a Git repository defined in + // `git_source`. + // + // * `WORKSPACE`: The Python file is located in a workspace or at a + // cloud filesystem URI. * `GIT`: The Python file is located in a remote Git + // repository. + Source Source +} + +type SparkSubmitTask struct { + // Command-line parameters passed to spark submit. + // + // Use [Task parameter variables](/jobs.html#parameter-variables) to set + // parameters containing information about job runs. + Parameters []string +} + +type SparseCheckout struct { + // List of patterns to include for sparse checkout. + Patterns []string +} + +type SqlAlertState struct { +} + +type SqlConditionConfiguration struct { + // The ID of the SQL query to evaluate as the trigger condition. + SqlQueryId *string + // The canonical identifier of the SQL warehouse to run the condition query + // against. + WarehouseId *string + // Determines how the SQL query result is interpreted to decide whether the + // condition fires. Must be set to a recognized value when provided. When unset + // on an existing serialized configuration, the server preserves the original + // semantics by interpreting it as `QUERY_RETURNS_ROWS`. New configurations + // should set this explicitly — explicit + // `SQL_CONDITION_TRIGGER_MODE_UNSPECIFIED` is rejected at validation. + TriggerMode SqlConditionTriggerMode +} + +// SQL condition evaluation details captured at the time the run was triggered. +type SqlConditionRunInfoDetails struct { + // The SQL statement ID of the condition evaluation, set when the condition is + // evaluated by running a single SQL statement (the RESULT_VALUE_CHANGES trigger + // mode). The UI uses it to link to the query execution details. + ConditionEvaluationSqlStatementId *string + // Whether the last condition evaluation was satisfied (query returned truthy + // result). + ConditionEvaluationSatisfied *bool + // The ID of the SQL session, used by the UI to track session context. Set for + // the QUERY_RETURNS_ROWS trigger mode. + ConditionEvaluationSqlSessionId *string +} + +type SqlConditionState struct { + // The SEA statement ID of the SQL statement executed for the latest condition + // evaluation. Populated for RESULT_VALUE_CHANGES, which executes the query + // through the SQL execution API. + LatestConditionEvaluationSqlStatementId *string + // Whether the last condition evaluation was satisfied (query returned truthy + // result). + LatestConditionEvaluationSatisfied *bool + // The ID of the SQL session, used by UI to track session context. Populated for + // QUERY_RETURNS_ROWS, which executes the query through Redash. + LatestConditionEvaluationSqlSessionId *string +} + +type SqlTask struct { + // Parameters to be used for each run of this job. The SQL alert task does not + // support custom parameters. + Parameters map[string]string + SqlTaskType isSqlTask_SqlTaskType + // The canonical identifier of the SQL warehouse. Recommended to use with + // serverless or pro SQL warehouses. Classic SQL warehouses are only supported + // for SQL alert, dashboard and query tasks and are limited to scheduled + // single-task jobs. + WarehouseId *string +} + +type isSqlTask_SqlTaskType interface { + isSqlTask_SqlTaskType() +} + +// SqlTask_SqlTaskType_Query selects Query for SqlTask.SqlTaskType. +// If query, indicates that this job must execute a SQL query. +type SqlTask_SqlTaskType_Query struct { + Query SqlTaskQuery +} + +func (*SqlTask_SqlTaskType_Query) isSqlTask_SqlTaskType() {} + +// SqlTask_SqlTaskType_Dashboard selects Dashboard for SqlTask.SqlTaskType. +// If dashboard, indicates that this job must refresh a SQL dashboard. +type SqlTask_SqlTaskType_Dashboard struct { + Dashboard SqlTaskDashboard +} + +func (*SqlTask_SqlTaskType_Dashboard) isSqlTask_SqlTaskType() {} + +// SqlTask_SqlTaskType_Alert selects Alert for SqlTask.SqlTaskType. +// If alert, indicates that this job must refresh a SQL alert. +type SqlTask_SqlTaskType_Alert struct { + Alert SqlTaskAlert +} + +func (*SqlTask_SqlTaskType_Alert) isSqlTask_SqlTaskType() {} + +// SqlTask_SqlTaskType_File selects File for SqlTask.SqlTaskType. +// If file, indicates that this job runs a SQL file in a remote Git repository. +type SqlTask_SqlTaskType_File struct { + File SqlTaskFile +} + +func (*SqlTask_SqlTaskType_File) isSqlTask_SqlTaskType() {} + +type SqlTask_SqlAlertOutput struct { + // The text of the SQL query. Can Run permission of the SQL query associated + // with the SQL alert is required to view this field. + QueryText *string + // Information about SQL statements executed in the run. + SqlStatements []SqlTask_SqlStatementOutput + // The link to find the output results. + OutputLink *string + // The canonical identifier of the SQL warehouse. + WarehouseId *string + AlertState SqlAlertState_SqlAlertState +} + +type SqlTask_SqlDashboardOutput struct { + // Widgets executed in the run. Only SQL query based widgets are listed. + Widgets []SqlTask_SqlDashboardWidgetOutput + // The canonical identifier of the SQL warehouse. + WarehouseId *string +} + +type SqlTask_SqlDashboardWidgetOutput struct { + // The canonical identifier of the SQL widget. + WidgetId *string + // The title of the SQL widget. + WidgetTitle *string + // The link to find the output results. + OutputLink *string + // The execution status of the SQL widget. + Status SqlTask_SqlTaskQueryStatus + // The information about the error when execution fails. + Error *SqlTask_SqlOutputError + // Time (in epoch milliseconds) when execution of the SQL widget starts. + StartTime *int64 + // Time (in epoch milliseconds) when execution of the SQL widget ends. + EndTime *int64 +} + +type SqlTask_SqlOutput struct { + SqlOutputType isSqlTask_SqlOutput_SqlOutputType +} + +type isSqlTask_SqlOutput_SqlOutputType interface { + isSqlTask_SqlOutput_SqlOutputType() +} + +// SqlTask_SqlOutput_SqlOutputType_QueryOutput selects QueryOutput for SqlTask_SqlOutput.SqlOutputType. +// The output of a SQL query task, if available. +type SqlTask_SqlOutput_SqlOutputType_QueryOutput struct { + QueryOutput SqlTask_SqlQueryOutput +} + +func (*SqlTask_SqlOutput_SqlOutputType_QueryOutput) isSqlTask_SqlOutput_SqlOutputType() {} + +// SqlTask_SqlOutput_SqlOutputType_DashboardOutput selects DashboardOutput for SqlTask_SqlOutput.SqlOutputType. +// The output of a SQL dashboard task, if available. +type SqlTask_SqlOutput_SqlOutputType_DashboardOutput struct { + DashboardOutput SqlTask_SqlDashboardOutput +} + +func (*SqlTask_SqlOutput_SqlOutputType_DashboardOutput) isSqlTask_SqlOutput_SqlOutputType() {} + +// SqlTask_SqlOutput_SqlOutputType_AlertOutput selects AlertOutput for SqlTask_SqlOutput.SqlOutputType. +// The output of a SQL alert task, if available. +type SqlTask_SqlOutput_SqlOutputType_AlertOutput struct { + AlertOutput SqlTask_SqlAlertOutput +} + +func (*SqlTask_SqlOutput_SqlOutputType_AlertOutput) isSqlTask_SqlOutput_SqlOutputType() {} + +type SqlTask_SqlOutputError struct { + // The error message when execution fails. + Message *string +} + +type SqlTask_SqlQueryOutput struct { + // The text of the SQL query. Can Run permission of the SQL query is required to + // view this field. + QueryText *string + EndpointId *string + // Information about SQL statements executed in the run. + SqlStatements []SqlTask_SqlStatementOutput + // The link to find the output results. + OutputLink *string + // The canonical identifier of the SQL warehouse. + WarehouseId *string +} + +type SqlTask_SqlStatementOutput struct { + // A key that can be used to look up query details. + LookupKey *string +} + +type SqlTaskAlert struct { + // The canonical identifier of the SQL alert. + AlertId *string + // If specified, alert notifications are sent to subscribers. + Subscriptions []SqlTaskSubscription + // If true, the alert notifications are not sent to subscribers. + PauseSubscriptions *bool +} + +type SqlTaskDashboard struct { + // The canonical identifier of the SQL dashboard. + DashboardId *string + // If specified, dashboard snapshots are sent to subscriptions. + Subscriptions []SqlTaskSubscription + // Subject of the email sent to subscribers of this task. + CustomSubject *string + // If true, the dashboard snapshot is not taken, and emails are not sent to + // subscribers. + PauseSubscriptions *bool +} + +type SqlTaskFile struct { + // Path of the SQL file. Must be relative if the source is a remote Git + // repository and absolute for workspace paths. + Path *string + // Optional location type of the SQL file. When set to `WORKSPACE`, the SQL file + // will be retrieved from the local workspace. When set to `GIT`, + // the SQL file will be retrieved from a Git repository defined in `git_source`. + // If the value is empty, the task will use `GIT` if `git_source` is defined and + // `WORKSPACE` otherwise. + // + // * `WORKSPACE`: SQL file is located in workspace. * `GIT`: SQL + // file is located in cloud Git provider. + Source Source +} + +type SqlTaskQuery struct { + QueryType isSqlTaskQuery_QueryType +} + +type isSqlTaskQuery_QueryType interface { + isSqlTaskQuery_QueryType() +} + +// SqlTaskQuery_QueryType_QueryId selects QueryId for SqlTaskQuery.QueryType. +// The canonical identifier of the SQL query. +type SqlTaskQuery_QueryType_QueryId struct { + QueryId string +} + +func (*SqlTaskQuery_QueryType_QueryId) isSqlTaskQuery_QueryType() {} + +type SqlTaskSubscription struct { + SubscriptionType isSqlTaskSubscription_SubscriptionType +} + +type isSqlTaskSubscription_SubscriptionType interface { + isSqlTaskSubscription_SubscriptionType() +} + +// SqlTaskSubscription_SubscriptionType_UserName selects UserName for SqlTaskSubscription.SubscriptionType. +// The user name to receive the subscription email. This parameter is mutually +// exclusive with destination_id. You cannot set both destination_id and +// user_name for subscription notifications. +type SqlTaskSubscription_SubscriptionType_UserName struct { + UserName string +} + +func (*SqlTaskSubscription_SubscriptionType_UserName) isSqlTaskSubscription_SubscriptionType() {} + +// SqlTaskSubscription_SubscriptionType_DestinationId selects DestinationId for SqlTaskSubscription.SubscriptionType. +// The canonical identifier of the destination to receive email notification. +// This parameter is mutually exclusive with user_name. You cannot set both +// destination_id and user_name for subscription notifications. +type SqlTaskSubscription_SubscriptionType_DestinationId struct { + DestinationId string +} + +func (*SqlTaskSubscription_SubscriptionType_DestinationId) isSqlTaskSubscription_SubscriptionType() {} + +type SubmitRunRequest struct { + // List of permissions to set on the job. + AccessControlList []AccessControlRequest + // The queue settings of the one-time run. + Queue *QueueSettings + // Specifies the user or service principal that the job runs as. If not + // specified, the job runs as the user who submits the request. + RunAs *JobRunAs + // An optional name for the run. The default value is `Untitled`. + RunName *string + // An optional timeout applied to each run of this job. A value of `0` means no + // timeout. + TimeoutSeconds *int + Health *JobsHealthRules + // An optional token that can be used to guarantee the idempotency of job run + // requests. If a run with the provided token already exists, the request does + // not create a new run but returns the ID of the existing run instead. If a run + // with the provided token is deleted, an error is returned. + // + // If you specify the idempotency token, upon failure you can retry until the + // request succeeds. guarantees that exactly one run is launched + // with that idempotency token. + // + // This token must have at most 64 characters. + IdempotencyToken *string + Tasks []RunTaskSettings + // An optional specification for a remote Git repository containing the source + // code used by tasks. Version-controlled source code is supported by notebook, + // dbt, Python script, and SQL File tasks. + // + // If `git_source` is set, these tasks retrieve the file from the remote + // repository by default. However, this behavior can be overridden by setting + // `source` to `WORKSPACE` on the task. + // + // Note: dbt and SQL File tasks support only version-controlled sources. If dbt + // or SQL File tasks are used, `git_source` must be defined on the job. + GitSource *GitSource + // A collection of system notification IDs to notify when the run begins or + // completes. + WebhookNotifications *WebhookNotifications + // An optional set of email addresses notified when the run begins or completes. + EmailNotifications *JobEmailNotifications + // Optional notification settings that are used when sending notifications to + // each of the `email_notifications` and `webhook_notifications` for this run. + NotificationSettings *NotificationSettings + // A list of task execution environment specifications that can be referenced by + // tasks of this run. + Environments []JobEnvironment + // The user specified id of the budget policy to use for this one-time run. If + // not specified, the run will be not be attributed to any budget policy. + BudgetPolicyId *string + // The user specified id of the usage policy to use for this one-time run. If + // not specified, a default usage policy may be applied when creating or + // modifying the job. + UsagePolicyId *string + // The performance mode on a serverless one-time run. This field determines the + // level of compute performance or cost-efficiency for the run. The performance + // target does not apply to tasks that run on Serverless GPU compute. + // + // * `STANDARD`: Enables cost-efficient execution of serverless workloads. * + // `PERFORMANCE_OPTIMIZED`: Prioritizes fast startup and execution times through + // rapid scaling and optimized cluster performance. + PerformanceTarget PerformanceTarget_PerformanceTarget +} + +// Run was created and started successfully.. +type SubmitRunResponse struct { + // The canonical identifier for the newly submitted run. + RunId *int64 +} + +type Subscription struct { + // The list of subscribers to send the snapshot of the dashboard to. + Subscribers []Subscription_Subscriber + // When true, the subscription will not send emails. + Paused *bool + // Optional: Allows users to specify a custom subject line on the email sent to + // subscribers. + CustomSubject *string +} + +type Subscription_Subscriber struct { + SubscriptionType isSubscription_Subscriber_SubscriptionType +} + +type isSubscription_Subscriber_SubscriptionType interface { + isSubscription_Subscriber_SubscriptionType() +} + +// Subscription_Subscriber_SubscriptionType_UserName selects UserName for Subscription_Subscriber.SubscriptionType. +// A snapshot of the dashboard will be sent to the user's email when the +// `user_name` field is present. +type Subscription_Subscriber_SubscriptionType_UserName struct { + UserName string +} + +func (*Subscription_Subscriber_SubscriptionType_UserName) isSubscription_Subscriber_SubscriptionType() { +} + +// Subscription_Subscriber_SubscriptionType_DestinationId selects DestinationId for Subscription_Subscriber.SubscriptionType. +// A snapshot of the dashboard will be sent to the destination when the +// `destination_id` field is present. +type Subscription_Subscriber_SubscriptionType_DestinationId struct { + DestinationId string +} + +func (*Subscription_Subscriber_SubscriptionType_DestinationId) isSubscription_Subscriber_SubscriptionType() { +} + +type TableState struct { + // Full table name of the table to monitor, e.g. `mycatalog.myschema.mytable` + TableName *string + // Whether or not the table has seen updates since either the creation of the + // trigger or the last successful evaluation of the trigger + HasSeenUpdates *bool +} + +type TableTriggerConfiguration struct { + // A list of tables to monitor for changes. The table name must be in the format + // `catalog_name.schema_name.table_name`. + TableNames []string + // If set, the trigger starts a run only after the specified amount of time has + // passed since the last time the trigger fired. The minimum allowed value is 60 + // seconds. + MinTimeBetweenTriggersSeconds *int + // If set, the trigger starts a run only after no table updates have occurred + // for the specified time and can be used to wait for a series of table updates + // before triggering a run. The minimum allowed value is 60 seconds. + WaitAfterLastChangeSeconds *int + // The table(s) condition based on which to trigger a job run. + Condition TableTriggerConfiguration_Condition +} + +type TableTriggerState struct { + LastSeenTableStates []TableState + // Indicates whether the trigger is using scalable monitoring. + UsingScalableMonitoring *bool +} + +type TaskDependency struct { + // The name of the task this task depends on. + TaskKey *string + // Can only be specified on condition task dependencies. The outcome of the + // dependent task that must be met for this task to run. + Outcome *string +} + +type TaskSettings struct { + // A unique name for the task. This field is used to refer to this task from + // other tasks. This field is required and must be unique within its parent job. + // On Update or Reset, this field is used to reference the tasks to be updated + // or reset. + TaskKey *string + // An optional array of objects specifying the dependency graph of the task. All + // tasks specified in this field must complete before executing this task. The + // task will run only if the `run_if` condition is true. The key is `task_key`, + // and the value is the name assigned to the dependent task. + DependsOn []TaskDependency + // An optional value specifying the condition determining whether the task is + // run once its dependencies have been completed. + // + // * `ALL_SUCCESS`: All dependencies have executed and succeeded * + // `AT_LEAST_ONE_SUCCESS`: At least one dependency has succeeded * + // `NONE_FAILED`: None of the dependencies have failed and at least one was + // executed * `ALL_DONE`: All dependencies have been completed * + // `AT_LEAST_ONE_FAILED`: At least one dependency failed * `ALL_FAILED`: ALl + // dependencies have failed + RunIf TaskDependencyType + // An optional timeout applied to each run of this job task. A value of `0` + // means no timeout. + TimeoutSeconds *int + Health *JobsHealthRules + // An optional set of email addresses that is notified when runs of this task + // begin or complete as well as when this task is deleted. The default behavior + // is to not send any emails. + EmailNotifications *JobEmailNotifications + // Optional notification settings that are used when sending notifications to + // each of the `email_notifications` and `webhook_notifications` for this task. + NotificationSettings *NotificationSettings + // A collection of system notification IDs to notify when runs of this task + // begin or complete. The default behavior is to not send any system + // notifications. + WebhookNotifications *WebhookNotifications + // An optional description for this task. + Description *string + EnvironmentRef isTaskSettings_EnvironmentRef + // An optional flag to disable the task. If set to true, the task will not run + // even if it is part of a job. + Disabled *bool + // Task level compute configuration. + Compute *Compute + // DO NOT ADD ANY NEW FIELDS TO JobTask OUTSIDE OF THIS ONEOF as it will break + // the TaskRegistry + Task isTaskSettings_Task + Spec isTaskSettings_Spec + // An optional list of libraries to be installed on the cluster. The default + // value is an empty list. + Libraries []Library + // An optional maximum number of times to retry an unsuccessful run. A run is + // considered to be unsuccessful if it completes with the `FAILED` result_state + // or `INTERNAL_ERROR` `life_cycle_state`. The value `-1` means to retry + // indefinitely and the value `0` means to never retry. + MaxRetries *int + // An optional minimal interval in milliseconds between the start of the failed + // run and the subsequent retry run. The default behavior is that unsuccessful + // runs are immediately retried. + MinRetryIntervalMillis *int + // An optional policy to specify whether to retry a job when it times out. The + // default behavior is to not retry on timeout. + RetryOnTimeout *bool + // An option to disable auto optimization in serverless + DisableAutoOptimization *bool +} + +type isTaskSettings_EnvironmentRef interface { + isTaskSettings_EnvironmentRef() +} + +// TaskSettings_EnvironmentRef_EnvironmentKey selects EnvironmentKey for TaskSettings.EnvironmentRef. +// The key that references an environment spec in a job. This field is required +// for Python script, Python wheel and dbt tasks when using serverless compute. +type TaskSettings_EnvironmentRef_EnvironmentKey struct { + EnvironmentKey string +} + +func (*TaskSettings_EnvironmentRef_EnvironmentKey) isTaskSettings_EnvironmentRef() {} + +type isTaskSettings_Task interface { + isTaskSettings_Task() +} + +// TaskSettings_Task_NotebookTask selects NotebookTask for TaskSettings.Task. +// The task runs a notebook when the `notebook_task` field is present. +type TaskSettings_Task_NotebookTask struct { + NotebookTask NotebookTask +} + +func (*TaskSettings_Task_NotebookTask) isTaskSettings_Task() {} + +// TaskSettings_Task_SparkJarTask selects SparkJarTask for TaskSettings.Task. +// The task runs a JAR when the `spark_jar_task` field is present. +type TaskSettings_Task_SparkJarTask struct { + SparkJarTask SparkJarTask +} + +func (*TaskSettings_Task_SparkJarTask) isTaskSettings_Task() {} + +// TaskSettings_Task_SparkPythonTask selects SparkPythonTask for TaskSettings.Task. +// The task runs a Python file when the `spark_python_task` field is present. +type TaskSettings_Task_SparkPythonTask struct { + SparkPythonTask SparkPythonTask +} + +func (*TaskSettings_Task_SparkPythonTask) isTaskSettings_Task() {} + +// TaskSettings_Task_SparkSubmitTask selects SparkSubmitTask for TaskSettings.Task. +// (Legacy) The task runs the spark-submit script when the spark_submit_task +// field is present. Databricks recommends using the spark_jar_task instead; see +// [Spark Submit task for jobs](/jobs/spark-submit). +type TaskSettings_Task_SparkSubmitTask struct { + SparkSubmitTask SparkSubmitTask +} + +func (*TaskSettings_Task_SparkSubmitTask) isTaskSettings_Task() {} + +// TaskSettings_Task_PipelineTask selects PipelineTask for TaskSettings.Task. +// The task triggers a pipeline update when the `pipeline_task` field is +// present. Only pipelines configured to use triggered more are supported. +type TaskSettings_Task_PipelineTask struct { + PipelineTask PipelineTask +} + +func (*TaskSettings_Task_PipelineTask) isTaskSettings_Task() {} + +// TaskSettings_Task_PythonWheelTask selects PythonWheelTask for TaskSettings.Task. +// The task runs a Python wheel when the `python_wheel_task` field is present. +type TaskSettings_Task_PythonWheelTask struct { + PythonWheelTask PythonWheelTask +} + +func (*TaskSettings_Task_PythonWheelTask) isTaskSettings_Task() {} + +// TaskSettings_Task_DbtTask selects DbtTask for TaskSettings.Task. +// The task runs one or more dbt commands when the `dbt_task` field is present. +// The dbt task requires both Databricks SQL and the ability to use a serverless +// or a pro SQL warehouse. +type TaskSettings_Task_DbtTask struct { + DbtTask DbtTask +} + +func (*TaskSettings_Task_DbtTask) isTaskSettings_Task() {} + +// TaskSettings_Task_SqlTask selects SqlTask for TaskSettings.Task. +// The task runs a SQL query or file, or it refreshes a SQL alert or a legacy +// SQL dashboard when the `sql_task` field is present. +type TaskSettings_Task_SqlTask struct { + SqlTask SqlTask +} + +func (*TaskSettings_Task_SqlTask) isTaskSettings_Task() {} + +// TaskSettings_Task_RunJobTask selects RunJobTask for TaskSettings.Task. +// The task triggers another job when the `run_job_task` field is present. +type TaskSettings_Task_RunJobTask struct { + RunJobTask RunJobTask +} + +func (*TaskSettings_Task_RunJobTask) isTaskSettings_Task() {} + +// TaskSettings_Task_ConditionTask selects ConditionTask for TaskSettings.Task. +// The task evaluates a condition that can be used to control the execution of +// other tasks when the `condition_task` field is present. The condition task +// does not require a cluster to execute and does not support retries or +// notifications. +type TaskSettings_Task_ConditionTask struct { + ConditionTask ConditionTask +} + +func (*TaskSettings_Task_ConditionTask) isTaskSettings_Task() {} + +// TaskSettings_Task_ForEachTask selects ForEachTask for TaskSettings.Task. +// The task executes a nested task for every input provided when the +// `for_each_task` field is present. +type TaskSettings_Task_ForEachTask struct { + ForEachTask ForEachTask +} + +func (*TaskSettings_Task_ForEachTask) isTaskSettings_Task() {} + +// TaskSettings_Task_CleanRoomsNotebookTask selects CleanRoomsNotebookTask for TaskSettings.Task. +// The task runs a [clean rooms](/clean-rooms/index.html) notebook when the +// `clean_rooms_notebook_task` field is present. +type TaskSettings_Task_CleanRoomsNotebookTask struct { + CleanRoomsNotebookTask CleanRoomsNotebookTask +} + +func (*TaskSettings_Task_CleanRoomsNotebookTask) isTaskSettings_Task() {} + +// TaskSettings_Task_GenAiComputeTask selects GenAiComputeTask for TaskSettings.Task. +type TaskSettings_Task_GenAiComputeTask struct { + GenAiComputeTask GenAiComputeTask +} + +func (*TaskSettings_Task_GenAiComputeTask) isTaskSettings_Task() {} + +// TaskSettings_Task_AlertTask selects AlertTask for TaskSettings.Task. +// The task evaluates a alert and sends notifications to +// subscribers when the `alert_task` field is present. +type TaskSettings_Task_AlertTask struct { + AlertTask AlertTask +} + +func (*TaskSettings_Task_AlertTask) isTaskSettings_Task() {} + +// TaskSettings_Task_PowerBiTask selects PowerBiTask for TaskSettings.Task. +// The task triggers a Power BI semantic model update when the `power_bi_task` +// field is present. +type TaskSettings_Task_PowerBiTask struct { + PowerBiTask PowerBiTask +} + +func (*TaskSettings_Task_PowerBiTask) isTaskSettings_Task() {} + +// TaskSettings_Task_DashboardTask selects DashboardTask for TaskSettings.Task. +// The task refreshes a dashboard and sends a snapshot to subscribers. +type TaskSettings_Task_DashboardTask struct { + DashboardTask DashboardTask +} + +func (*TaskSettings_Task_DashboardTask) isTaskSettings_Task() {} + +// TaskSettings_Task_DbtCloudTask selects DbtCloudTask for TaskSettings.Task. +// Task type for dbt cloud, deprecated in favor of the new name +// dbt_platform_task +type TaskSettings_Task_DbtCloudTask struct { + DbtCloudTask DbtCloudTask +} + +func (*TaskSettings_Task_DbtCloudTask) isTaskSettings_Task() {} + +// TaskSettings_Task_DbtPlatformTask selects DbtPlatformTask for TaskSettings.Task. +type TaskSettings_Task_DbtPlatformTask struct { + DbtPlatformTask DbtPlatformTask +} + +func (*TaskSettings_Task_DbtPlatformTask) isTaskSettings_Task() {} + +// TaskSettings_Task_PythonOperatorTask selects PythonOperatorTask for TaskSettings.Task. +// The task runs a Python operator task. +type TaskSettings_Task_PythonOperatorTask struct { + PythonOperatorTask PythonOperatorTask +} + +func (*TaskSettings_Task_PythonOperatorTask) isTaskSettings_Task() {} + +// TaskSettings_Task_AiRuntimeTask selects AiRuntimeTask for TaskSettings.Task. +// The task runs a multi-gpu compute workload on Databricks AI Runtime. Specify +// the accelerator type and count, the command to run, and where the workload's +// code and MLflow output are stored. +type TaskSettings_Task_AiRuntimeTask struct { + AiRuntimeTask AiRuntimeTask +} + +func (*TaskSettings_Task_AiRuntimeTask) isTaskSettings_Task() {} + +type isTaskSettings_Spec interface { + isTaskSettings_Spec() +} + +// TaskSettings_Spec_ExistingClusterId selects ExistingClusterId for TaskSettings.Spec. +// If existing_cluster_id, the ID of an existing cluster that is used for all +// runs. When running jobs or tasks on an existing cluster, you may need to +// manually restart the cluster if it stops responding. We suggest running jobs +// and tasks on new clusters for greater reliability +type TaskSettings_Spec_ExistingClusterId struct { + ExistingClusterId string +} + +func (*TaskSettings_Spec_ExistingClusterId) isTaskSettings_Spec() {} + +// TaskSettings_Spec_NewCluster selects NewCluster for TaskSettings.Spec. +// If new_cluster, a description of a new cluster that is created for each run. +type TaskSettings_Spec_NewCluster struct { + NewCluster ClusterSpec_NewCluster +} + +func (*TaskSettings_Spec_NewCluster) isTaskSettings_Spec() {} + +// TaskSettings_Spec_JobClusterKey selects JobClusterKey for TaskSettings.Spec. +// If job_cluster_key, this task is executed reusing the cluster specified in +// `job.settings.job_clusters`. +type TaskSettings_Spec_JobClusterKey struct { + JobClusterKey string +} + +func (*TaskSettings_Spec_JobClusterKey) isTaskSettings_Spec() {} + +type TerminationCode struct { +} + +type TerminationDetails struct { + Code TerminationCode_Code + Type TerminationType_Type + // A descriptive message with the termination details. This field is + // unstructured and the format might change. + Message *string +} + +type TerminationType struct { +} + +// A single trigger attached to a job via `JobSettings.triggers`. Exactly one of +// the trigger-type fields (`periodic`, `schedule`, `continuous`, +// `file_arrival`, `table_update`, `model`) must be set; mutual exclusivity is +// enforced in the API handler rather than via `oneof` so that codegen, +// validation, and JSON serialization across SDKs and Terraform behave +// consistently.. +type TriggerConfiguration struct { + // Whether this trigger is paused. Defaults to UNPAUSED when unset; the server + // always returns an explicit value on read. + PauseStatus SchedulePauseStatus + // Trigger type: exactly one must be set; mutual exclusivity is enforced in the + // API handler Periodic trigger configuration. + Periodic *PeriodicTriggerConfiguration + // Cron schedule trigger configuration. + Schedule *CronTriggerConfiguration + // Continuous trigger configuration. + Continuous *ContinuousTriggerConfiguration + // File arrival trigger configuration. + FileArrival *FileArrivalTriggerConfiguration + // Table update trigger configuration. + TableUpdate *TableTriggerConfiguration + // Model trigger configuration. + Model *ModelTriggerConfiguration + // Optional SQL condition that gates whether this trigger fires. + SqlCondition *SqlConditionConfiguration +} + +// Per-trigger runtime details returned by `GetJob`. Same length and order as +// `JobSettings.triggers`; sub-fields are populated independently based on the +// corresponding `GetJob.include_trigger_state` / `include_trigger_history` +// flags.. +type TriggerDetails struct { + // Current runtime state. Populated when `GetJob.include_trigger_state` is set. + State *PerTriggerState + // Recent evaluation history. Populated when `GetJob.include_trigger_history` is + // set. + History *TriggerHistory +} + +type TriggerEvaluation struct { + // Timestamp at which the trigger was evaluated. + Timestamp *int64 + // Human-readable description of the trigger evaluation result. Explains why the + // trigger evaluation triggered or did not trigger a run, or failed. + Description *string + // The ID of the run that was triggered by the trigger evaluation. Only returned + // if a run was triggered. + RunId *int64 +} + +type TriggerHistory struct { + // The last time the run was triggered due to a file arrival. + LastTriggered *TriggerEvaluation + // The last time the trigger was evaluated but did not trigger a run. + LastNotTriggered *TriggerEvaluation + // The last time the trigger failed to evaluate. + LastFailed *TriggerEvaluation +} + +type TriggerSettings struct { + // Whether this trigger is paused or not. + PauseStatus SchedulePauseStatus + Configuration isTriggerSettings_Configuration + // SQL condition that must be satisfied for the trigger to fire. Can be used in + // combination with other trigger types and runs *after* other trigger types + // conditions are evaluated. + SqlCondition *SqlConditionConfiguration +} + +type isTriggerSettings_Configuration interface { + isTriggerSettings_Configuration() +} + +// TriggerSettings_Configuration_FileArrival selects FileArrival for TriggerSettings.Configuration. +// File arrival trigger settings. +type TriggerSettings_Configuration_FileArrival struct { + FileArrival FileArrivalTriggerConfiguration +} + +func (*TriggerSettings_Configuration_FileArrival) isTriggerSettings_Configuration() {} + +// TriggerSettings_Configuration_Periodic selects Periodic for TriggerSettings.Configuration. +// Periodic trigger settings. +type TriggerSettings_Configuration_Periodic struct { + Periodic PeriodicTriggerConfiguration +} + +func (*TriggerSettings_Configuration_Periodic) isTriggerSettings_Configuration() {} + +// TriggerSettings_Configuration_TableUpdate selects TableUpdate for TriggerSettings.Configuration. +type TriggerSettings_Configuration_TableUpdate struct { + TableUpdate TableTriggerConfiguration +} + +func (*TriggerSettings_Configuration_TableUpdate) isTriggerSettings_Configuration() {} + +// TriggerSettings_Configuration_Model selects Model for TriggerSettings.Configuration. +type TriggerSettings_Configuration_Model struct { + Model ModelTriggerConfiguration +} + +func (*TriggerSettings_Configuration_Model) isTriggerSettings_Configuration() {} + +type TriggerState struct { + // (-- Next ID: 7. --) + TriggerType isTriggerState_TriggerType + // State for SQL condition evaluation, can coexist with other trigger states. + SqlCondition *SqlConditionState + // Whether this trigger is paused or not. For continuous schedules, it can + // differ from the configured pause_status whenever a paused continuous job is + // kickstarted by an operation other than an update, such as a run-now. + PauseStatus SchedulePauseStatus +} + +type isTriggerState_TriggerType interface { + isTriggerState_TriggerType() +} + +// TriggerState_TriggerType_Table selects Table for TriggerState.TriggerType. +type TriggerState_TriggerType_Table struct { + Table TableTriggerState +} + +func (*TriggerState_TriggerType_Table) isTriggerState_TriggerType() {} + +// TriggerState_TriggerType_FileArrival selects FileArrival for TriggerState.TriggerType. +type TriggerState_TriggerType_FileArrival struct { + FileArrival FileArrivalTriggerState +} + +func (*TriggerState_TriggerType_FileArrival) isTriggerState_TriggerType() {} + +type UpdateJobRequest struct { + // The canonical identifier of the job to update. This field is required. + JobId *int64 + // The new settings for the job. + // + // Top-level fields specified in `new_settings` are completely replaced, except + // for arrays which are merged. That is, new and existing entries are completely + // replaced based on the respective key fields, i.e. `task_key` or + // `job_cluster_key`, while previous entries are kept. + // + // Partially updating nested fields is not supported. + // + // Changes to the field `JobSettings.timeout_seconds` are applied to active + // runs. Changes to other fields are applied to future runs only. + NewSettings *JobSettings + // Remove top-level fields in the job settings. Removing nested fields is not + // supported, except for tasks and job clusters (`tasks/task_1`). This field is + // optional. + FieldsToRemove []string +} + +// Job was updated successfully.. +type UpdateJobResponse struct { +} + +type ViewItem struct { + // Content of the view. + Content *string + // Name of the view item. In the case of code view, it would be the notebook’s + // name. In the case of dashboard view, it would be the dashboard’s name. + Name *string + // Type of the view item. + Type ViewType +} + +// A storage location back by UC Volumes.. +type VolumesStorageInfo struct { + // UC Volumes destination, e.g. + // `/Volumes/catalog/schema/vol1/init-scripts/setup-datadog.sh` or + // `dbfs:/Volumes/catalog/schema/vol1/init-scripts/setup-datadog.sh` + Destination *string +} + +type Webhook struct { + Id *string +} + +type WebhookNotifications struct { + // An optional list of system notification IDs to call when the run starts. A + // maximum of 3 destinations can be specified for the `on_start` property. + OnStart []Webhook + // An optional list of system notification IDs to call when the run completes + // successfully. A maximum of 3 destinations can be specified for the + // `on_success` property. + OnSuccess []Webhook + // An optional list of system notification IDs to call when the run fails. A + // maximum of 3 destinations can be specified for the `on_failure` property. + OnFailure []Webhook + // An optional list of system notification IDs to call when the duration of a + // run exceeds the threshold specified for the `RUN_DURATION_SECONDS` metric in + // the `health` field. A maximum of 3 destinations can be specified for the + // `on_duration_warning_threshold_exceeded` property. + OnDurationWarningThresholdExceeded []Webhook + // An optional list of system notification IDs to call when any streaming + // backlog thresholds are exceeded for any stream. Streaming backlog thresholds + // can be set in the `health` field using the following metrics: + // `STREAMING_BACKLOG_BYTES`, `STREAMING_BACKLOG_RECORDS`, + // `STREAMING_BACKLOG_SECONDS`, or `STREAMING_BACKLOG_FILES`. Alerting is based + // on the 10-minute average of these metrics. If the issue persists, + // notifications are resent every 30 minutes. A maximum of 3 destinations can be + // specified for the `on_streaming_backlog_exceeded` property. + OnStreamingBacklogExceeded []Webhook +} + +type WidgetErrorDetail struct { + Message *string +} + +// Cluster Attributes showing for clusters workload types.. +type WorkloadType struct { + // defined what type of clients can use the cluster. E.g. Notebooks, Jobs + Clients *WorkloadType_ClientsTypes +} + +type WorkloadType_ClientsTypes struct { + // With notebooks set, this cluster can be used for notebooks + Notebooks *bool + // With jobs set, the cluster can be used for jobs + Jobs *bool +} + +// A storage location in Workspace Filesystem (WSFS). +type WorkspaceStorageInfo struct { + // wsfs destination, e.g. `workspace:/cluster-init-scripts/setup-datadog.sh` + Destination *string +} diff --git a/jobs/v2/wire.go b/jobs/v2/wire.go new file mode 100755 index 0000000..86c1370 --- /dev/null +++ b/jobs/v2/wire.go @@ -0,0 +1,8174 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package jobs + +import ( + "fmt" +) + +type accessControlRequestWire struct { + UserName *string `json:"user_name,omitempty"` + GroupName *string `json:"group_name,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` + PermissionLevel AccessControlRequest_JobPermission `json:"permission_level,omitempty"` +} + +func accessControlRequestToWire(v *AccessControlRequest) (*accessControlRequestWire, error) { + if v == nil { + return nil, nil + } + var principalNameUserNameWire *string + var principalNameGroupNameWire *string + var principalNameServicePrincipalNameWire *string + switch value := v.PrincipalName.(type) { + case nil: + case *AccessControlRequest_PrincipalName_UserName: + if value != nil { + principalNameUserNameWire = new(value.UserName) + } + case *AccessControlRequest_PrincipalName_GroupName: + if value != nil { + principalNameGroupNameWire = new(value.GroupName) + } + case *AccessControlRequest_PrincipalName_ServicePrincipalName: + if value != nil { + principalNameServicePrincipalNameWire = new(value.ServicePrincipalName) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AccessControlRequest.PrincipalName", value) + } + return &accessControlRequestWire{ + UserName: principalNameUserNameWire, + GroupName: principalNameGroupNameWire, + ServicePrincipalName: principalNameServicePrincipalNameWire, + PermissionLevel: v.PermissionLevel, + }, nil +} + +type adlsgen2InfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func adlsgen2InfoToWire(v *Adlsgen2Info) (*adlsgen2InfoWire, error) { + if v == nil { + return nil, nil + } + return &adlsgen2InfoWire{ + Destination: v.Destination, + }, nil +} + +func adlsgen2InfoFromWire(w *adlsgen2InfoWire) (*Adlsgen2Info, error) { + if w == nil { + return nil, nil + } + return &Adlsgen2Info{ + Destination: w.Destination, + }, nil +} + +type aiRuntimeTaskWire struct { + Experiment *string `json:"experiment,omitempty"` + Deployments []deploymentSpecWire `json:"deployments,omitempty"` + CodeSourcePath *string `json:"code_source_path,omitempty"` + MlflowRun *string `json:"mlflow_run,omitempty"` + MlflowExperimentDirectory *string `json:"mlflow_experiment_directory,omitempty"` + DockerImageUrl *string `json:"docker_image_url,omitempty"` + MlflowArtifactLocation *string `json:"mlflow_artifact_location,omitempty"` +} + +func aiRuntimeTaskToWire(v *AiRuntimeTask) (*aiRuntimeTaskWire, error) { + if v == nil { + return nil, nil + } + deploymentsWireValue, err := convertSlice(v.Deployments, deploymentSpecToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiRuntimeTask.Deployments", err) + } + return &aiRuntimeTaskWire{ + Experiment: v.Experiment, + Deployments: deploymentsWireValue, + CodeSourcePath: v.CodeSourcePath, + MlflowRun: v.MlflowRun, + MlflowExperimentDirectory: v.MlflowExperimentDirectory, + DockerImageUrl: v.DockerImageUrl, + MlflowArtifactLocation: v.MlflowArtifactLocation, + }, nil +} + +func aiRuntimeTaskFromWire(w *aiRuntimeTaskWire) (*AiRuntimeTask, error) { + if w == nil { + return nil, nil + } + deploymentsPublicValue, err := convertSlice(w.Deployments, deploymentSpecFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiRuntimeTask.Deployments", err) + } + return &AiRuntimeTask{ + Experiment: w.Experiment, + Deployments: deploymentsPublicValue, + CodeSourcePath: w.CodeSourcePath, + MlflowRun: w.MlflowRun, + MlflowExperimentDirectory: w.MlflowExperimentDirectory, + DockerImageUrl: w.DockerImageUrl, + MlflowArtifactLocation: w.MlflowArtifactLocation, + }, nil +} + +type aiRuntimeTaskOutputWire struct { + MlflowExperimentId *string `json:"mlflow_experiment_id,omitempty"` + MlflowRunId *string `json:"mlflow_run_id,omitempty"` + StatusMessage *string `json:"status_message,omitempty"` +} + +func aiRuntimeTaskOutputFromWire(w *aiRuntimeTaskOutputWire) (*AiRuntimeTaskOutput, error) { + if w == nil { + return nil, nil + } + return &AiRuntimeTaskOutput{ + MlflowExperimentId: w.MlflowExperimentId, + MlflowRunId: w.MlflowRunId, + StatusMessage: w.StatusMessage, + }, nil +} + +type alertTaskWire struct { + AlertId *string `json:"alert_id,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + WorkspacePath *string `json:"workspace_path,omitempty"` + Subscribers []alertTaskSubscriberWire `json:"subscribers,omitempty"` +} + +func alertTaskToWire(v *AlertTask) (*alertTaskWire, error) { + if v == nil { + return nil, nil + } + subscribersWireValue, err := convertSlice(v.Subscribers, alertTaskSubscriberToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertTask.Subscribers", err) + } + return &alertTaskWire{ + AlertId: v.AlertId, + WarehouseId: v.WarehouseId, + WorkspacePath: v.WorkspacePath, + Subscribers: subscribersWireValue, + }, nil +} + +func alertTaskFromWire(w *alertTaskWire) (*AlertTask, error) { + if w == nil { + return nil, nil + } + subscribersPublicValue, err := convertSlice(w.Subscribers, alertTaskSubscriberFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AlertTask.Subscribers", err) + } + return &AlertTask{ + AlertId: w.AlertId, + WarehouseId: w.WarehouseId, + WorkspacePath: w.WorkspacePath, + Subscribers: subscribersPublicValue, + }, nil +} + +type alertTaskOutputWire struct { + AlertState AlertEvaluationState_AlertEvaluationState `json:"alert_state,omitempty"` +} + +func alertTaskOutputFromWire(w *alertTaskOutputWire) (*AlertTaskOutput, error) { + if w == nil { + return nil, nil + } + return &AlertTaskOutput{ + AlertState: w.AlertState, + }, nil +} + +type alertTaskSubscriberWire struct { + UserName *string `json:"user_name,omitempty"` + DestinationId *string `json:"destination_id,omitempty"` +} + +func alertTaskSubscriberToWire(v *AlertTaskSubscriber) (*alertTaskSubscriberWire, error) { + if v == nil { + return nil, nil + } + var subscriberTypeUserNameWire *string + var subscriberTypeDestinationIdWire *string + switch value := v.SubscriberType.(type) { + case nil: + case *AlertTaskSubscriber_SubscriberType_UserName: + if value != nil { + subscriberTypeUserNameWire = new(value.UserName) + } + case *AlertTaskSubscriber_SubscriberType_DestinationId: + if value != nil { + subscriberTypeDestinationIdWire = new(value.DestinationId) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "AlertTaskSubscriber.SubscriberType", value) + } + return &alertTaskSubscriberWire{ + UserName: subscriberTypeUserNameWire, + DestinationId: subscriberTypeDestinationIdWire, + }, nil +} + +func alertTaskSubscriberFromWire(w *alertTaskSubscriberWire) (*AlertTaskSubscriber, error) { + if w == nil { + return nil, nil + } + subscriberTypeMembers := 0 + if w.UserName != nil { + subscriberTypeMembers++ + } + if w.DestinationId != nil { + subscriberTypeMembers++ + } + if subscriberTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AlertTaskSubscriber.SubscriberType") + } + var subscriberTypeSelection isAlertTaskSubscriber_SubscriberType + switch { + case w.UserName != nil: + subscriberTypeSelection = &AlertTaskSubscriber_SubscriberType_UserName{UserName: *w.UserName} + case w.DestinationId != nil: + subscriberTypeSelection = &AlertTaskSubscriber_SubscriberType_DestinationId{DestinationId: *w.DestinationId} + } + return &AlertTaskSubscriber{ + SubscriberType: subscriberTypeSelection, + }, nil +} + +type autoScaleWire struct { + MinWorkers *int `json:"min_workers,omitempty"` + MaxWorkers *int `json:"max_workers,omitempty"` +} + +func autoScaleToWire(v *AutoScale) (*autoScaleWire, error) { + if v == nil { + return nil, nil + } + return &autoScaleWire{ + MinWorkers: v.MinWorkers, + MaxWorkers: v.MaxWorkers, + }, nil +} + +func autoScaleFromWire(w *autoScaleWire) (*AutoScale, error) { + if w == nil { + return nil, nil + } + return &AutoScale{ + MinWorkers: w.MinWorkers, + MaxWorkers: w.MaxWorkers, + }, nil +} + +type awsAttributesWire struct { + FirstOnDemand *int `json:"first_on_demand,omitempty"` + Availability AwsAvailability `json:"availability,omitempty"` + ZoneId *string `json:"zone_id,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + SpotBidPricePercent *int `json:"spot_bid_price_percent,omitempty"` + EbsVolumeType EbsVolumeType `json:"ebs_volume_type,omitempty"` + EbsVolumeCount *int `json:"ebs_volume_count,omitempty"` + EbsVolumeSize *int `json:"ebs_volume_size,omitempty"` + EbsVolumeIops *int `json:"ebs_volume_iops,omitempty"` + EbsVolumeThroughput *int `json:"ebs_volume_throughput,omitempty"` +} + +func awsAttributesToWire(v *AwsAttributes) (*awsAttributesWire, error) { + if v == nil { + return nil, nil + } + return &awsAttributesWire{ + FirstOnDemand: v.FirstOnDemand, + Availability: v.Availability, + ZoneId: v.ZoneId, + InstanceProfileArn: v.InstanceProfileArn, + SpotBidPricePercent: v.SpotBidPricePercent, + EbsVolumeType: v.EbsVolumeType, + EbsVolumeCount: v.EbsVolumeCount, + EbsVolumeSize: v.EbsVolumeSize, + EbsVolumeIops: v.EbsVolumeIops, + EbsVolumeThroughput: v.EbsVolumeThroughput, + }, nil +} + +func awsAttributesFromWire(w *awsAttributesWire) (*AwsAttributes, error) { + if w == nil { + return nil, nil + } + return &AwsAttributes{ + FirstOnDemand: w.FirstOnDemand, + Availability: w.Availability, + ZoneId: w.ZoneId, + InstanceProfileArn: w.InstanceProfileArn, + SpotBidPricePercent: w.SpotBidPricePercent, + EbsVolumeType: w.EbsVolumeType, + EbsVolumeCount: w.EbsVolumeCount, + EbsVolumeSize: w.EbsVolumeSize, + EbsVolumeIops: w.EbsVolumeIops, + EbsVolumeThroughput: w.EbsVolumeThroughput, + }, nil +} + +type azureAttributesWire struct { + LogAnalyticsInfo *logAnalyticsInfoWire `json:"log_analytics_info,omitempty"` + FirstOnDemand *int `json:"first_on_demand,omitempty"` + Availability AzureAvailability `json:"availability,omitempty"` + SpotBidMaxPrice *float64 `json:"spot_bid_max_price,omitempty"` + CapacityReservationGroup *string `json:"capacity_reservation_group,omitempty"` +} + +func azureAttributesToWire(v *AzureAttributes) (*azureAttributesWire, error) { + if v == nil { + return nil, nil + } + logAnalyticsInfoWireValue, err := logAnalyticsInfoToWire(v.LogAnalyticsInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AzureAttributes.LogAnalyticsInfo", err) + } + return &azureAttributesWire{ + LogAnalyticsInfo: logAnalyticsInfoWireValue, + FirstOnDemand: v.FirstOnDemand, + Availability: v.Availability, + SpotBidMaxPrice: v.SpotBidMaxPrice, + CapacityReservationGroup: v.CapacityReservationGroup, + }, nil +} + +func azureAttributesFromWire(w *azureAttributesWire) (*AzureAttributes, error) { + if w == nil { + return nil, nil + } + logAnalyticsInfoPublicValue, err := logAnalyticsInfoFromWire(w.LogAnalyticsInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AzureAttributes.LogAnalyticsInfo", err) + } + return &AzureAttributes{ + LogAnalyticsInfo: logAnalyticsInfoPublicValue, + FirstOnDemand: w.FirstOnDemand, + Availability: w.Availability, + SpotBidMaxPrice: w.SpotBidMaxPrice, + CapacityReservationGroup: w.CapacityReservationGroup, + }, nil +} + +type baseJobWire struct { + JobId *int64 `json:"job_id,omitempty"` + CreatorUserName *string `json:"creator_user_name,omitempty"` + RunAsUserName *string `json:"run_as_user_name,omitempty"` + Settings *jobSettingsWire `json:"settings,omitempty"` + CreatedTime *int64 `json:"created_time,omitempty"` + TriggerState *triggerStateWire `json:"trigger_state,omitempty"` + HasMore *bool `json:"has_more,omitempty"` + EffectiveBudgetPolicyId *string `json:"effective_budget_policy_id,omitempty"` + EffectiveUsagePolicyId *string `json:"effective_usage_policy_id,omitempty"` + TriggerDetails []triggerDetailsWire `json:"trigger_details,omitempty"` +} + +func baseJobFromWire(w *baseJobWire) (*BaseJob, error) { + if w == nil { + return nil, nil + } + settingsPublicValue, err := jobSettingsFromWire(w.Settings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseJob.Settings", err) + } + triggerStatePublicValue, err := triggerStateFromWire(w.TriggerState) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseJob.TriggerState", err) + } + triggerDetailsPublicValue, err := convertSlice(w.TriggerDetails, triggerDetailsFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseJob.TriggerDetails", err) + } + return &BaseJob{ + JobId: w.JobId, + CreatorUserName: w.CreatorUserName, + RunAsUserName: w.RunAsUserName, + Settings: settingsPublicValue, + CreatedTime: w.CreatedTime, + TriggerState: triggerStatePublicValue, + HasMore: w.HasMore, + EffectiveBudgetPolicyId: w.EffectiveBudgetPolicyId, + EffectiveUsagePolicyId: w.EffectiveUsagePolicyId, + TriggerDetails: triggerDetailsPublicValue, + }, nil +} + +type baseRunWire struct { + JobId *int64 `json:"job_id,omitempty"` + RunId *int64 `json:"run_id,omitempty"` + CreatorUserName *string `json:"creator_user_name,omitempty"` + NumberInJob *int64 `json:"number_in_job,omitempty"` + OriginalAttemptRunId *int64 `json:"original_attempt_run_id,omitempty"` + State *runStateWire `json:"state,omitempty"` + Schedule *cronScheduleWire `json:"schedule,omitempty"` + ClusterSpec *clusterSpecWire `json:"cluster_spec,omitempty"` + ClusterInstance *clusterInstanceWire `json:"cluster_instance,omitempty"` + JobParameters []run_JobLevelParametersWire `json:"job_parameters,omitempty"` + OverridingParameters *runParametersWire `json:"overriding_parameters,omitempty"` + Trigger TriggerType `json:"trigger,omitempty"` + TriggerInfo *runTriggerInfoWire `json:"trigger_info,omitempty"` + RunName *string `json:"run_name,omitempty"` + RunPageUrl *string `json:"run_page_url,omitempty"` + RunType RunType `json:"run_type,omitempty"` + Tasks []runTaskWire `json:"tasks,omitempty"` + Description *string `json:"description,omitempty"` + AttemptNumber *int `json:"attempt_number,omitempty"` + JobClusters []jobClusterWire `json:"job_clusters,omitempty"` + GitSource *gitSourceWire `json:"git_source,omitempty"` + RepairHistory []repairWire `json:"repair_history,omitempty"` + Status *runStatusWire `json:"status,omitempty"` + JobRunId *int64 `json:"job_run_id,omitempty"` + HasMore *bool `json:"has_more,omitempty"` + EffectivePerformanceTarget PerformanceTarget_PerformanceTarget `json:"effective_performance_target,omitempty"` + EffectiveUsagePolicyId *string `json:"effective_usage_policy_id,omitempty"` + DeploymentId *string `json:"deployment_id,omitempty"` + VersionId *string `json:"version_id,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + SetupDuration *int64 `json:"setup_duration,omitempty"` + ExecutionDuration *int64 `json:"execution_duration,omitempty"` + CleanupDuration *int64 `json:"cleanup_duration,omitempty"` + EndTime *int64 `json:"end_time,omitempty"` + RunDuration *int64 `json:"run_duration,omitempty"` + QueueDuration *int64 `json:"queue_duration,omitempty"` +} + +func baseRunFromWire(w *baseRunWire) (*BaseRun, error) { + if w == nil { + return nil, nil + } + statePublicValue, err := runStateFromWire(w.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.State", err) + } + schedulePublicValue, err := cronScheduleFromWire(w.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.Schedule", err) + } + clusterSpecPublicValue, err := clusterSpecFromWire(w.ClusterSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.ClusterSpec", err) + } + clusterInstancePublicValue, err := clusterInstanceFromWire(w.ClusterInstance) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.ClusterInstance", err) + } + jobParametersPublicValue, err := convertSlice(w.JobParameters, run_JobLevelParametersFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.JobParameters", err) + } + overridingParametersPublicValue, err := runParametersFromWire(w.OverridingParameters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.OverridingParameters", err) + } + triggerInfoPublicValue, err := runTriggerInfoFromWire(w.TriggerInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.TriggerInfo", err) + } + tasksPublicValue, err := convertSlice(w.Tasks, runTaskFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.Tasks", err) + } + jobClustersPublicValue, err := convertSlice(w.JobClusters, jobClusterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.JobClusters", err) + } + gitSourcePublicValue, err := gitSourceFromWire(w.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.GitSource", err) + } + repairHistoryPublicValue, err := convertSlice(w.RepairHistory, repairFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.RepairHistory", err) + } + statusPublicValue, err := runStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BaseRun.Status", err) + } + return &BaseRun{ + JobId: w.JobId, + RunId: w.RunId, + CreatorUserName: w.CreatorUserName, + NumberInJob: w.NumberInJob, + OriginalAttemptRunId: w.OriginalAttemptRunId, + State: statePublicValue, + Schedule: schedulePublicValue, + ClusterSpec: clusterSpecPublicValue, + ClusterInstance: clusterInstancePublicValue, + JobParameters: jobParametersPublicValue, + OverridingParameters: overridingParametersPublicValue, + Trigger: w.Trigger, + TriggerInfo: triggerInfoPublicValue, + RunName: w.RunName, + RunPageUrl: w.RunPageUrl, + RunType: w.RunType, + Tasks: tasksPublicValue, + Description: w.Description, + AttemptNumber: w.AttemptNumber, + JobClusters: jobClustersPublicValue, + GitSource: gitSourcePublicValue, + RepairHistory: repairHistoryPublicValue, + Status: statusPublicValue, + JobRunId: w.JobRunId, + HasMore: w.HasMore, + EffectivePerformanceTarget: w.EffectivePerformanceTarget, + EffectiveUsagePolicyId: w.EffectiveUsagePolicyId, + DeploymentId: w.DeploymentId, + VersionId: w.VersionId, + StartTime: w.StartTime, + SetupDuration: w.SetupDuration, + ExecutionDuration: w.ExecutionDuration, + CleanupDuration: w.CleanupDuration, + EndTime: w.EndTime, + RunDuration: w.RunDuration, + QueueDuration: w.QueueDuration, + }, nil +} + +type cancelAllRunsRequestWire struct { + JobId *int64 `json:"job_id,omitempty"` + AllQueuedRuns *bool `json:"all_queued_runs,omitempty"` +} + +func cancelAllRunsRequestToWire(v *CancelAllRunsRequest) (*cancelAllRunsRequestWire, error) { + if v == nil { + return nil, nil + } + return &cancelAllRunsRequestWire{ + JobId: v.JobId, + AllQueuedRuns: v.AllQueuedRuns, + }, nil +} + +type cancelRunRequestWire struct { + RunId *int64 `json:"run_id,omitempty"` +} + +func cancelRunRequestToWire(v *CancelRunRequest) (*cancelRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &cancelRunRequestWire{ + RunId: v.RunId, + }, nil +} + +type cleanRoomTaskRunStateWire struct { + LifeCycleState CleanRoomTaskRunLifeCycleState_CleanRoomTaskRunLifeCycleState `json:"life_cycle_state,omitempty"` + ResultState CleanRoomTaskRunResultState_CleanRoomTaskRunResultState `json:"result_state,omitempty"` +} + +func cleanRoomTaskRunStateFromWire(w *cleanRoomTaskRunStateWire) (*CleanRoomTaskRunState, error) { + if w == nil { + return nil, nil + } + return &CleanRoomTaskRunState{ + LifeCycleState: w.LifeCycleState, + ResultState: w.ResultState, + }, nil +} + +type cleanRoomsNotebookTaskWire struct { + CleanRoomName *string `json:"clean_room_name,omitempty"` + NotebookName *string `json:"notebook_name,omitempty"` + Etag *string `json:"etag,omitempty"` + NotebookBaseParameters map[string]string `json:"notebook_base_parameters,omitempty"` +} + +func cleanRoomsNotebookTaskToWire(v *CleanRoomsNotebookTask) (*cleanRoomsNotebookTaskWire, error) { + if v == nil { + return nil, nil + } + return &cleanRoomsNotebookTaskWire{ + CleanRoomName: v.CleanRoomName, + NotebookName: v.NotebookName, + Etag: v.Etag, + NotebookBaseParameters: v.NotebookBaseParameters, + }, nil +} + +func cleanRoomsNotebookTaskFromWire(w *cleanRoomsNotebookTaskWire) (*CleanRoomsNotebookTask, error) { + if w == nil { + return nil, nil + } + return &CleanRoomsNotebookTask{ + CleanRoomName: w.CleanRoomName, + NotebookName: w.NotebookName, + Etag: w.Etag, + NotebookBaseParameters: w.NotebookBaseParameters, + }, nil +} + +type cleanRoomsNotebookTask_CleanRoomsNotebookTaskOutputWire struct { + CleanRoomJobRunState *cleanRoomTaskRunStateWire `json:"clean_room_job_run_state,omitempty"` + NotebookOutput *notebookTask_NotebookOutputWire `json:"notebook_output,omitempty"` + OutputSchemaInfo *outputSchemaInfoWire `json:"output_schema_info,omitempty"` +} + +func cleanRoomsNotebookTask_CleanRoomsNotebookTaskOutputFromWire(w *cleanRoomsNotebookTask_CleanRoomsNotebookTaskOutputWire) (*CleanRoomsNotebookTask_CleanRoomsNotebookTaskOutput, error) { + if w == nil { + return nil, nil + } + cleanRoomJobRunStatePublicValue, err := cleanRoomTaskRunStateFromWire(w.CleanRoomJobRunState) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomsNotebookTask_CleanRoomsNotebookTaskOutput.CleanRoomJobRunState", err) + } + notebookOutputPublicValue, err := notebookTask_NotebookOutputFromWire(w.NotebookOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomsNotebookTask_CleanRoomsNotebookTaskOutput.NotebookOutput", err) + } + outputSchemaInfoPublicValue, err := outputSchemaInfoFromWire(w.OutputSchemaInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CleanRoomsNotebookTask_CleanRoomsNotebookTaskOutput.OutputSchemaInfo", err) + } + return &CleanRoomsNotebookTask_CleanRoomsNotebookTaskOutput{ + CleanRoomJobRunState: cleanRoomJobRunStatePublicValue, + NotebookOutput: notebookOutputPublicValue, + OutputSchemaInfo: outputSchemaInfoPublicValue, + }, nil +} + +type clusterInstanceWire struct { + ClusterId *string `json:"cluster_id,omitempty"` + SparkContextId *string `json:"spark_context_id,omitempty"` +} + +func clusterInstanceFromWire(w *clusterInstanceWire) (*ClusterInstance, error) { + if w == nil { + return nil, nil + } + return &ClusterInstance{ + ClusterId: w.ClusterId, + SparkContextId: w.SparkContextId, + }, nil +} + +type clusterLogConfWire struct { + Dbfs *dbfsStorageInfoWire `json:"dbfs,omitempty"` + S3 *s3StorageInfoWire `json:"s3,omitempty"` + Volumes *volumesStorageInfoWire `json:"volumes,omitempty"` +} + +func clusterLogConfToWire(v *ClusterLogConf) (*clusterLogConfWire, error) { + if v == nil { + return nil, nil + } + var storageInfoDbfsWire *dbfsStorageInfoWire + var storageInfoS3Wire *s3StorageInfoWire + var storageInfoVolumesWire *volumesStorageInfoWire + switch value := v.StorageInfo.(type) { + case nil: + case *ClusterLogConf_StorageInfo_Dbfs: + if value != nil { + storageInfoDbfsConverted, err := dbfsStorageInfoToWire(&value.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.Dbfs", err) + } + storageInfoDbfsWire = storageInfoDbfsConverted + } + case *ClusterLogConf_StorageInfo_S3: + if value != nil { + storageInfoS3Converted, err := s3StorageInfoToWire(&value.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.S3", err) + } + storageInfoS3Wire = storageInfoS3Converted + } + case *ClusterLogConf_StorageInfo_Volumes: + if value != nil { + storageInfoVolumesConverted, err := volumesStorageInfoToWire(&value.Volumes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.Volumes", err) + } + storageInfoVolumesWire = storageInfoVolumesConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ClusterLogConf.StorageInfo", value) + } + return &clusterLogConfWire{ + Dbfs: storageInfoDbfsWire, + S3: storageInfoS3Wire, + Volumes: storageInfoVolumesWire, + }, nil +} + +func clusterLogConfFromWire(w *clusterLogConfWire) (*ClusterLogConf, error) { + if w == nil { + return nil, nil + } + storageInfoMembers := 0 + if w.Dbfs != nil { + storageInfoMembers++ + } + if w.S3 != nil { + storageInfoMembers++ + } + if w.Volumes != nil { + storageInfoMembers++ + } + if storageInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ClusterLogConf.StorageInfo") + } + var storageInfoSelection isClusterLogConf_StorageInfo + switch { + case w.Dbfs != nil: + storageInfoDbfsConverted, err := dbfsStorageInfoFromWire(w.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.Dbfs", err) + } + storageInfoSelection = &ClusterLogConf_StorageInfo_Dbfs{Dbfs: *storageInfoDbfsConverted} + case w.S3 != nil: + storageInfoS3Converted, err := s3StorageInfoFromWire(w.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.S3", err) + } + storageInfoSelection = &ClusterLogConf_StorageInfo_S3{S3: *storageInfoS3Converted} + case w.Volumes != nil: + storageInfoVolumesConverted, err := volumesStorageInfoFromWire(w.Volumes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterLogConf.StorageInfo.Volumes", err) + } + storageInfoSelection = &ClusterLogConf_StorageInfo_Volumes{Volumes: *storageInfoVolumesConverted} + } + return &ClusterLogConf{ + StorageInfo: storageInfoSelection, + }, nil +} + +type clusterSpecWire struct { + ExistingClusterId *string `json:"existing_cluster_id,omitempty"` + NewCluster *clusterSpec_NewClusterWire `json:"new_cluster,omitempty"` + JobClusterKey *string `json:"job_cluster_key,omitempty"` + Libraries []libraryWire `json:"libraries,omitempty"` +} + +func clusterSpecFromWire(w *clusterSpecWire) (*ClusterSpec, error) { + if w == nil { + return nil, nil + } + specMembers := 0 + if w.ExistingClusterId != nil { + specMembers++ + } + if w.NewCluster != nil { + specMembers++ + } + if w.JobClusterKey != nil { + specMembers++ + } + if specMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ClusterSpec.Spec") + } + librariesPublicValue, err := convertSlice(w.Libraries, libraryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec.Libraries", err) + } + var specSelection isClusterSpec_Spec + switch { + case w.ExistingClusterId != nil: + specSelection = &ClusterSpec_Spec_ExistingClusterId{ExistingClusterId: *w.ExistingClusterId} + case w.NewCluster != nil: + specNewClusterConverted, err := clusterSpec_NewClusterFromWire(w.NewCluster) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec.Spec.NewCluster", err) + } + specSelection = &ClusterSpec_Spec_NewCluster{NewCluster: *specNewClusterConverted} + case w.JobClusterKey != nil: + specSelection = &ClusterSpec_Spec_JobClusterKey{JobClusterKey: *w.JobClusterKey} + } + return &ClusterSpec{ + Libraries: librariesPublicValue, + Spec: specSelection, + }, nil +} + +type clusterSpec_NewClusterWire struct { + ApplyPolicyDefaultValues *bool `json:"apply_policy_default_values,omitempty"` + ClusterName *string `json:"cluster_name,omitempty"` + SparkVersion *string `json:"spark_version,omitempty"` + SparkConf map[string]string `json:"spark_conf,omitempty"` + AwsAttributes *awsAttributesWire `json:"aws_attributes,omitempty"` + AzureAttributes *azureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *gcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + DriverNodeTypeId *string `json:"driver_node_type_id,omitempty"` + WorkerNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"worker_node_type_flexibility,omitempty"` + DriverNodeTypeFlexibility *nodeTypeFlexibilityWire `json:"driver_node_type_flexibility,omitempty"` + SshPublicKeys []string `json:"ssh_public_keys,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + ClusterLogConf *clusterLogConfWire `json:"cluster_log_conf,omitempty"` + SparkEnvVars map[string]string `json:"spark_env_vars,omitempty"` + AutoterminationMinutes *int `json:"autotermination_minutes,omitempty"` + EnableElasticDisk *bool `json:"enable_elastic_disk,omitempty"` + InitScripts []initScriptInfoWire `json:"init_scripts,omitempty"` + DockerImage *dockerImageWire `json:"docker_image,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + SingleUserName *string `json:"single_user_name,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + EnableLocalDiskEncryption *bool `json:"enable_local_disk_encryption,omitempty"` + DriverInstancePoolId *string `json:"driver_instance_pool_id,omitempty"` + WorkloadType *workloadTypeWire `json:"workload_type,omitempty"` + DataSecurityMode DataSecurityMode `json:"data_security_mode,omitempty"` + RuntimeEngine RuntimeEngine `json:"runtime_engine,omitempty"` + Kind ComputeKind `json:"kind,omitempty"` + UseMlRuntime *bool `json:"use_ml_runtime,omitempty"` + IsSingleNode *bool `json:"is_single_node,omitempty"` + RemoteDiskThroughput *int `json:"remote_disk_throughput,omitempty"` + TotalInitialRemoteDiskSize *int `json:"total_initial_remote_disk_size,omitempty"` + DependencyMode DependencyMode `json:"dependency_mode,omitempty"` + NumWorkers *int `json:"num_workers,omitempty"` + Autoscale *autoScaleWire `json:"autoscale,omitempty"` +} + +func clusterSpec_NewClusterToWire(v *ClusterSpec_NewCluster) (*clusterSpec_NewClusterWire, error) { + if v == nil { + return nil, nil + } + awsAttributesWireValue, err := awsAttributesToWire(v.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.AwsAttributes", err) + } + azureAttributesWireValue, err := azureAttributesToWire(v.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.AzureAttributes", err) + } + gcpAttributesWireValue, err := gcpAttributesToWire(v.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.GcpAttributes", err) + } + workerNodeTypeFlexibilityWireValue, err := nodeTypeFlexibilityToWire(v.WorkerNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.WorkerNodeTypeFlexibility", err) + } + driverNodeTypeFlexibilityWireValue, err := nodeTypeFlexibilityToWire(v.DriverNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.DriverNodeTypeFlexibility", err) + } + clusterLogConfWireValue, err := clusterLogConfToWire(v.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.ClusterLogConf", err) + } + initScriptsWireValue, err := convertSlice(v.InitScripts, initScriptInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.InitScripts", err) + } + dockerImageWireValue, err := dockerImageToWire(v.DockerImage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.DockerImage", err) + } + workloadTypeWireValue, err := workloadTypeToWire(v.WorkloadType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.WorkloadType", err) + } + var sizeNumWorkersWire *int + var sizeAutoscaleWire *autoScaleWire + switch value := v.Size.(type) { + case nil: + case *ClusterSpec_NewCluster_Size_NumWorkers: + if value != nil { + sizeNumWorkersWire = new(value.NumWorkers) + } + case *ClusterSpec_NewCluster_Size_Autoscale: + if value != nil { + sizeAutoscaleConverted, err := autoScaleToWire(&value.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.Size.Autoscale", err) + } + sizeAutoscaleWire = sizeAutoscaleConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ClusterSpec_NewCluster.Size", value) + } + return &clusterSpec_NewClusterWire{ + ApplyPolicyDefaultValues: v.ApplyPolicyDefaultValues, + ClusterName: v.ClusterName, + SparkVersion: v.SparkVersion, + SparkConf: v.SparkConf, + AwsAttributes: awsAttributesWireValue, + AzureAttributes: azureAttributesWireValue, + GcpAttributes: gcpAttributesWireValue, + NodeTypeId: v.NodeTypeId, + DriverNodeTypeId: v.DriverNodeTypeId, + WorkerNodeTypeFlexibility: workerNodeTypeFlexibilityWireValue, + DriverNodeTypeFlexibility: driverNodeTypeFlexibilityWireValue, + SshPublicKeys: v.SshPublicKeys, + CustomTags: v.CustomTags, + ClusterLogConf: clusterLogConfWireValue, + SparkEnvVars: v.SparkEnvVars, + AutoterminationMinutes: v.AutoterminationMinutes, + EnableElasticDisk: v.EnableElasticDisk, + InitScripts: initScriptsWireValue, + DockerImage: dockerImageWireValue, + InstancePoolId: v.InstancePoolId, + SingleUserName: v.SingleUserName, + PolicyId: v.PolicyId, + EnableLocalDiskEncryption: v.EnableLocalDiskEncryption, + DriverInstancePoolId: v.DriverInstancePoolId, + WorkloadType: workloadTypeWireValue, + DataSecurityMode: v.DataSecurityMode, + RuntimeEngine: v.RuntimeEngine, + Kind: v.Kind, + UseMlRuntime: v.UseMlRuntime, + IsSingleNode: v.IsSingleNode, + RemoteDiskThroughput: v.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: v.TotalInitialRemoteDiskSize, + DependencyMode: v.DependencyMode, + NumWorkers: sizeNumWorkersWire, + Autoscale: sizeAutoscaleWire, + }, nil +} + +func clusterSpec_NewClusterFromWire(w *clusterSpec_NewClusterWire) (*ClusterSpec_NewCluster, error) { + if w == nil { + return nil, nil + } + sizeMembers := 0 + if w.NumWorkers != nil { + sizeMembers++ + } + if w.Autoscale != nil { + sizeMembers++ + } + if sizeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ClusterSpec_NewCluster.Size") + } + awsAttributesPublicValue, err := awsAttributesFromWire(w.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.AwsAttributes", err) + } + azureAttributesPublicValue, err := azureAttributesFromWire(w.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.AzureAttributes", err) + } + gcpAttributesPublicValue, err := gcpAttributesFromWire(w.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.GcpAttributes", err) + } + workerNodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.WorkerNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.WorkerNodeTypeFlexibility", err) + } + driverNodeTypeFlexibilityPublicValue, err := nodeTypeFlexibilityFromWire(w.DriverNodeTypeFlexibility) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.DriverNodeTypeFlexibility", err) + } + clusterLogConfPublicValue, err := clusterLogConfFromWire(w.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.ClusterLogConf", err) + } + initScriptsPublicValue, err := convertSlice(w.InitScripts, initScriptInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.InitScripts", err) + } + dockerImagePublicValue, err := dockerImageFromWire(w.DockerImage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.DockerImage", err) + } + workloadTypePublicValue, err := workloadTypeFromWire(w.WorkloadType) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.WorkloadType", err) + } + var sizeSelection isClusterSpec_NewCluster_Size + switch { + case w.NumWorkers != nil: + sizeSelection = &ClusterSpec_NewCluster_Size_NumWorkers{NumWorkers: *w.NumWorkers} + case w.Autoscale != nil: + sizeAutoscaleConverted, err := autoScaleFromWire(w.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterSpec_NewCluster.Size.Autoscale", err) + } + sizeSelection = &ClusterSpec_NewCluster_Size_Autoscale{Autoscale: *sizeAutoscaleConverted} + } + return &ClusterSpec_NewCluster{ + ApplyPolicyDefaultValues: w.ApplyPolicyDefaultValues, + ClusterName: w.ClusterName, + SparkVersion: w.SparkVersion, + SparkConf: w.SparkConf, + AwsAttributes: awsAttributesPublicValue, + AzureAttributes: azureAttributesPublicValue, + GcpAttributes: gcpAttributesPublicValue, + NodeTypeId: w.NodeTypeId, + DriverNodeTypeId: w.DriverNodeTypeId, + WorkerNodeTypeFlexibility: workerNodeTypeFlexibilityPublicValue, + DriverNodeTypeFlexibility: driverNodeTypeFlexibilityPublicValue, + SshPublicKeys: w.SshPublicKeys, + CustomTags: w.CustomTags, + ClusterLogConf: clusterLogConfPublicValue, + SparkEnvVars: w.SparkEnvVars, + AutoterminationMinutes: w.AutoterminationMinutes, + EnableElasticDisk: w.EnableElasticDisk, + InitScripts: initScriptsPublicValue, + DockerImage: dockerImagePublicValue, + InstancePoolId: w.InstancePoolId, + SingleUserName: w.SingleUserName, + PolicyId: w.PolicyId, + EnableLocalDiskEncryption: w.EnableLocalDiskEncryption, + DriverInstancePoolId: w.DriverInstancePoolId, + WorkloadType: workloadTypePublicValue, + DataSecurityMode: w.DataSecurityMode, + RuntimeEngine: w.RuntimeEngine, + Kind: w.Kind, + UseMlRuntime: w.UseMlRuntime, + IsSingleNode: w.IsSingleNode, + RemoteDiskThroughput: w.RemoteDiskThroughput, + TotalInitialRemoteDiskSize: w.TotalInitialRemoteDiskSize, + DependencyMode: w.DependencyMode, + Size: sizeSelection, + }, nil +} + +type computeWire struct { + HardwareAccelerator HardwareAcceleratorType `json:"hardware_accelerator,omitempty"` +} + +func computeToWire(v *Compute) (*computeWire, error) { + if v == nil { + return nil, nil + } + return &computeWire{ + HardwareAccelerator: v.HardwareAccelerator, + }, nil +} + +func computeFromWire(w *computeWire) (*Compute, error) { + if w == nil { + return nil, nil + } + return &Compute{ + HardwareAccelerator: w.HardwareAccelerator, + }, nil +} + +type computeConfigWire struct { + NumGpus *int `json:"num_gpus,omitempty"` + GpuNodePoolId *string `json:"gpu_node_pool_id,omitempty"` + GpuType *string `json:"gpu_type,omitempty"` +} + +func computeConfigToWire(v *ComputeConfig) (*computeConfigWire, error) { + if v == nil { + return nil, nil + } + return &computeConfigWire{ + NumGpus: v.NumGpus, + GpuNodePoolId: v.GpuNodePoolId, + GpuType: v.GpuType, + }, nil +} + +func computeConfigFromWire(w *computeConfigWire) (*ComputeConfig, error) { + if w == nil { + return nil, nil + } + return &ComputeConfig{ + NumGpus: w.NumGpus, + GpuNodePoolId: w.GpuNodePoolId, + GpuType: w.GpuType, + }, nil +} + +type computeSpecWire struct { + AcceleratorType ComputeSpec_AcceleratorType `json:"accelerator_type,omitempty"` + AcceleratorCount *int `json:"accelerator_count,omitempty"` +} + +func computeSpecToWire(v *ComputeSpec) (*computeSpecWire, error) { + if v == nil { + return nil, nil + } + return &computeSpecWire{ + AcceleratorType: v.AcceleratorType, + AcceleratorCount: v.AcceleratorCount, + }, nil +} + +func computeSpecFromWire(w *computeSpecWire) (*ComputeSpec, error) { + if w == nil { + return nil, nil + } + return &ComputeSpec{ + AcceleratorType: w.AcceleratorType, + AcceleratorCount: w.AcceleratorCount, + }, nil +} + +type conditionTaskWire struct { + Op ConditionTask_ConditionTaskOperator `json:"op,omitempty"` + Left *string `json:"left,omitempty"` + Right *string `json:"right,omitempty"` + Outcome *string `json:"outcome,omitempty"` +} + +func conditionTaskToWire(v *ConditionTask) (*conditionTaskWire, error) { + if v == nil { + return nil, nil + } + return &conditionTaskWire{ + Op: v.Op, + Left: v.Left, + Right: v.Right, + Outcome: v.Outcome, + }, nil +} + +func conditionTaskFromWire(w *conditionTaskWire) (*ConditionTask, error) { + if w == nil { + return nil, nil + } + return &ConditionTask{ + Op: w.Op, + Left: w.Left, + Right: w.Right, + Outcome: w.Outcome, + }, nil +} + +type continuousSettingsWire struct { + PauseStatus SchedulePauseStatus `json:"pause_status,omitempty"` + TaskRetryMode TaskRetryMode `json:"task_retry_mode,omitempty"` +} + +func continuousSettingsToWire(v *ContinuousSettings) (*continuousSettingsWire, error) { + if v == nil { + return nil, nil + } + return &continuousSettingsWire{ + PauseStatus: v.PauseStatus, + TaskRetryMode: v.TaskRetryMode, + }, nil +} + +func continuousSettingsFromWire(w *continuousSettingsWire) (*ContinuousSettings, error) { + if w == nil { + return nil, nil + } + return &ContinuousSettings{ + PauseStatus: w.PauseStatus, + TaskRetryMode: w.TaskRetryMode, + }, nil +} + +type continuousTriggerConfigurationWire struct { + TaskRetryMode TaskRetryMode `json:"task_retry_mode,omitempty"` +} + +func continuousTriggerConfigurationToWire(v *ContinuousTriggerConfiguration) (*continuousTriggerConfigurationWire, error) { + if v == nil { + return nil, nil + } + return &continuousTriggerConfigurationWire{ + TaskRetryMode: v.TaskRetryMode, + }, nil +} + +func continuousTriggerConfigurationFromWire(w *continuousTriggerConfigurationWire) (*ContinuousTriggerConfiguration, error) { + if w == nil { + return nil, nil + } + return &ContinuousTriggerConfiguration{ + TaskRetryMode: w.TaskRetryMode, + }, nil +} + +type continuousTriggerStateWire struct { + ConsecutiveFailures *int `json:"consecutive_failures,omitempty"` + NextAttemptMs *int64 `json:"next_attempt_ms,omitempty"` + IsBackingOff *bool `json:"is_backing_off,omitempty"` +} + +func continuousTriggerStateFromWire(w *continuousTriggerStateWire) (*ContinuousTriggerState, error) { + if w == nil { + return nil, nil + } + return &ContinuousTriggerState{ + ConsecutiveFailures: w.ConsecutiveFailures, + NextAttemptMs: w.NextAttemptMs, + IsBackingOff: w.IsBackingOff, + }, nil +} + +type createJobRequestWire struct { + AccessControlList []accessControlRequestWire `json:"access_control_list,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + EmailNotifications *jobEmailNotificationsWire `json:"email_notifications,omitempty"` + WebhookNotifications *webhookNotificationsWire `json:"webhook_notifications,omitempty"` + NotificationSettings *notificationSettingsWire `json:"notification_settings,omitempty"` + TimeoutSeconds *int `json:"timeout_seconds,omitempty"` + Health *jobsHealthRulesWire `json:"health,omitempty"` + Schedule *cronScheduleWire `json:"schedule,omitempty"` + Trigger *triggerSettingsWire `json:"trigger,omitempty"` + Continuous *continuousSettingsWire `json:"continuous,omitempty"` + MaxConcurrentRuns *int `json:"max_concurrent_runs,omitempty"` + Tasks []taskSettingsWire `json:"tasks,omitempty"` + JobClusters []jobClusterWire `json:"job_clusters,omitempty"` + GitSource *gitSourceWire `json:"git_source,omitempty"` + Tags map[string]string `json:"tags,omitempty"` + Format Format `json:"format,omitempty"` + Queue *queueSettingsWire `json:"queue,omitempty"` + Parameters []jobLevelParameterWire `json:"parameters,omitempty"` + RunAs *jobRunAsWire `json:"run_as,omitempty"` + EditMode JobEditMode `json:"edit_mode,omitempty"` + Deployment *jobDeploymentWire `json:"deployment,omitempty"` + Environments []jobEnvironmentWire `json:"environments,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + PerformanceTarget PerformanceTarget_PerformanceTarget `json:"performance_target,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + Triggers []triggerConfigurationWire `json:"triggers,omitempty"` + MaxRetries *int `json:"max_retries,omitempty"` + MinRetryIntervalMillis *int `json:"min_retry_interval_millis,omitempty"` + RetryOnTimeout *bool `json:"retry_on_timeout,omitempty"` + DisableAutoOptimization *bool `json:"disable_auto_optimization,omitempty"` +} + +func createJobRequestToWire(v *CreateJobRequest) (*createJobRequestWire, error) { + if v == nil { + return nil, nil + } + accessControlListWireValue, err := convertSlice(v.AccessControlList, accessControlRequestToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.AccessControlList", err) + } + emailNotificationsWireValue, err := jobEmailNotificationsToWire(v.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.EmailNotifications", err) + } + webhookNotificationsWireValue, err := webhookNotificationsToWire(v.WebhookNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.WebhookNotifications", err) + } + notificationSettingsWireValue, err := notificationSettingsToWire(v.NotificationSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.NotificationSettings", err) + } + healthWireValue, err := jobsHealthRulesToWire(v.Health) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.Health", err) + } + scheduleWireValue, err := cronScheduleToWire(v.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.Schedule", err) + } + triggerWireValue, err := triggerSettingsToWire(v.Trigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.Trigger", err) + } + continuousWireValue, err := continuousSettingsToWire(v.Continuous) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.Continuous", err) + } + tasksWireValue, err := convertSlice(v.Tasks, taskSettingsToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.Tasks", err) + } + jobClustersWireValue, err := convertSlice(v.JobClusters, jobClusterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.JobClusters", err) + } + gitSourceWireValue, err := gitSourceToWire(v.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.GitSource", err) + } + queueWireValue, err := queueSettingsToWire(v.Queue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.Queue", err) + } + parametersWireValue, err := convertSlice(v.Parameters, jobLevelParameterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.Parameters", err) + } + runAsWireValue, err := jobRunAsToWire(v.RunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.RunAs", err) + } + deploymentWireValue, err := jobDeploymentToWire(v.Deployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.Deployment", err) + } + environmentsWireValue, err := convertSlice(v.Environments, jobEnvironmentToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.Environments", err) + } + triggersWireValue, err := convertSlice(v.Triggers, triggerConfigurationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateJobRequest.Triggers", err) + } + return &createJobRequestWire{ + AccessControlList: accessControlListWireValue, + Name: v.Name, + Description: v.Description, + EmailNotifications: emailNotificationsWireValue, + WebhookNotifications: webhookNotificationsWireValue, + NotificationSettings: notificationSettingsWireValue, + TimeoutSeconds: v.TimeoutSeconds, + Health: healthWireValue, + Schedule: scheduleWireValue, + Trigger: triggerWireValue, + Continuous: continuousWireValue, + MaxConcurrentRuns: v.MaxConcurrentRuns, + Tasks: tasksWireValue, + JobClusters: jobClustersWireValue, + GitSource: gitSourceWireValue, + Tags: v.Tags, + Format: v.Format, + Queue: queueWireValue, + Parameters: parametersWireValue, + RunAs: runAsWireValue, + EditMode: v.EditMode, + Deployment: deploymentWireValue, + Environments: environmentsWireValue, + BudgetPolicyId: v.BudgetPolicyId, + UsagePolicyId: v.UsagePolicyId, + PerformanceTarget: v.PerformanceTarget, + ParentPath: v.ParentPath, + Triggers: triggersWireValue, + MaxRetries: v.MaxRetries, + MinRetryIntervalMillis: v.MinRetryIntervalMillis, + RetryOnTimeout: v.RetryOnTimeout, + DisableAutoOptimization: v.DisableAutoOptimization, + }, nil +} + +type createJobResponseWire struct { + JobId *int64 `json:"job_id,omitempty"` +} + +func createJobResponseFromWire(w *createJobResponseWire) (*CreateJobResponse, error) { + if w == nil { + return nil, nil + } + return &CreateJobResponse{ + JobId: w.JobId, + }, nil +} + +type cronScheduleWire struct { + QuartzCronExpression *string `json:"quartz_cron_expression,omitempty"` + TimezoneId *string `json:"timezone_id,omitempty"` + PauseStatus SchedulePauseStatus `json:"pause_status,omitempty"` + SqlCondition *sqlConditionConfigurationWire `json:"sql_condition,omitempty"` +} + +func cronScheduleToWire(v *CronSchedule) (*cronScheduleWire, error) { + if v == nil { + return nil, nil + } + sqlConditionWireValue, err := sqlConditionConfigurationToWire(v.SqlCondition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CronSchedule.SqlCondition", err) + } + return &cronScheduleWire{ + QuartzCronExpression: v.QuartzCronExpression, + TimezoneId: v.TimezoneId, + PauseStatus: v.PauseStatus, + SqlCondition: sqlConditionWireValue, + }, nil +} + +func cronScheduleFromWire(w *cronScheduleWire) (*CronSchedule, error) { + if w == nil { + return nil, nil + } + sqlConditionPublicValue, err := sqlConditionConfigurationFromWire(w.SqlCondition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CronSchedule.SqlCondition", err) + } + return &CronSchedule{ + QuartzCronExpression: w.QuartzCronExpression, + TimezoneId: w.TimezoneId, + PauseStatus: w.PauseStatus, + SqlCondition: sqlConditionPublicValue, + }, nil +} + +type cronTriggerConfigurationWire struct { + QuartzCronExpression *string `json:"quartz_cron_expression,omitempty"` + TimezoneId *string `json:"timezone_id,omitempty"` +} + +func cronTriggerConfigurationToWire(v *CronTriggerConfiguration) (*cronTriggerConfigurationWire, error) { + if v == nil { + return nil, nil + } + return &cronTriggerConfigurationWire{ + QuartzCronExpression: v.QuartzCronExpression, + TimezoneId: v.TimezoneId, + }, nil +} + +func cronTriggerConfigurationFromWire(w *cronTriggerConfigurationWire) (*CronTriggerConfiguration, error) { + if w == nil { + return nil, nil + } + return &CronTriggerConfiguration{ + QuartzCronExpression: w.QuartzCronExpression, + TimezoneId: w.TimezoneId, + }, nil +} + +type dashboardPageSnapshotWire struct { + PageDisplayName *string `json:"page_display_name,omitempty"` + WidgetErrorDetails []widgetErrorDetailWire `json:"widget_error_details,omitempty"` +} + +func dashboardPageSnapshotFromWire(w *dashboardPageSnapshotWire) (*DashboardPageSnapshot, error) { + if w == nil { + return nil, nil + } + widgetErrorDetailsPublicValue, err := convertSlice(w.WidgetErrorDetails, widgetErrorDetailFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DashboardPageSnapshot.WidgetErrorDetails", err) + } + return &DashboardPageSnapshot{ + PageDisplayName: w.PageDisplayName, + WidgetErrorDetails: widgetErrorDetailsPublicValue, + }, nil +} + +type dashboardTaskWire struct { + Subscription *subscriptionWire `json:"subscription,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + DashboardId *string `json:"dashboard_id,omitempty"` + Filters map[string]string `json:"filters,omitempty"` +} + +func dashboardTaskToWire(v *DashboardTask) (*dashboardTaskWire, error) { + if v == nil { + return nil, nil + } + subscriptionWireValue, err := subscriptionToWire(v.Subscription) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DashboardTask.Subscription", err) + } + return &dashboardTaskWire{ + Subscription: subscriptionWireValue, + WarehouseId: v.WarehouseId, + DashboardId: v.DashboardId, + Filters: v.Filters, + }, nil +} + +func dashboardTaskFromWire(w *dashboardTaskWire) (*DashboardTask, error) { + if w == nil { + return nil, nil + } + subscriptionPublicValue, err := subscriptionFromWire(w.Subscription) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DashboardTask.Subscription", err) + } + return &DashboardTask{ + Subscription: subscriptionPublicValue, + WarehouseId: w.WarehouseId, + DashboardId: w.DashboardId, + Filters: w.Filters, + }, nil +} + +type dashboardTaskOutputWire struct { + PageSnapshots []dashboardPageSnapshotWire `json:"page_snapshots,omitempty"` +} + +func dashboardTaskOutputFromWire(w *dashboardTaskOutputWire) (*DashboardTaskOutput, error) { + if w == nil { + return nil, nil + } + pageSnapshotsPublicValue, err := convertSlice(w.PageSnapshots, dashboardPageSnapshotFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DashboardTaskOutput.PageSnapshots", err) + } + return &DashboardTaskOutput{ + PageSnapshots: pageSnapshotsPublicValue, + }, nil +} + +type dbfsStorageInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func dbfsStorageInfoToWire(v *DbfsStorageInfo) (*dbfsStorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &dbfsStorageInfoWire{ + Destination: v.Destination, + }, nil +} + +func dbfsStorageInfoFromWire(w *dbfsStorageInfoWire) (*DbfsStorageInfo, error) { + if w == nil { + return nil, nil + } + return &DbfsStorageInfo{ + Destination: w.Destination, + }, nil +} + +type dbtCloudJobRunStepWire struct { + Index *int `json:"index,omitempty"` + Name *string `json:"name,omitempty"` + Status DbtPlatformRunStatus `json:"status,omitempty"` + Logs *string `json:"logs,omitempty"` +} + +func dbtCloudJobRunStepFromWire(w *dbtCloudJobRunStepWire) (*DbtCloudJobRunStep, error) { + if w == nil { + return nil, nil + } + return &DbtCloudJobRunStep{ + Index: w.Index, + Name: w.Name, + Status: w.Status, + Logs: w.Logs, + }, nil +} + +type dbtCloudTaskWire struct { + DbtCloudJobId *int64 `json:"dbt_cloud_job_id,omitempty"` + ConnectionResourceName *string `json:"connection_resource_name,omitempty"` +} + +func dbtCloudTaskToWire(v *DbtCloudTask) (*dbtCloudTaskWire, error) { + if v == nil { + return nil, nil + } + return &dbtCloudTaskWire{ + DbtCloudJobId: v.DbtCloudJobId, + ConnectionResourceName: v.ConnectionResourceName, + }, nil +} + +func dbtCloudTaskFromWire(w *dbtCloudTaskWire) (*DbtCloudTask, error) { + if w == nil { + return nil, nil + } + return &DbtCloudTask{ + DbtCloudJobId: w.DbtCloudJobId, + ConnectionResourceName: w.ConnectionResourceName, + }, nil +} + +type dbtCloudTaskOutputWire struct { + DbtCloudJobRunId *int64 `json:"dbt_cloud_job_run_id,omitempty"` + DbtCloudJobRunUrl *string `json:"dbt_cloud_job_run_url,omitempty"` + DbtCloudJobRunOutput []dbtCloudJobRunStepWire `json:"dbt_cloud_job_run_output,omitempty"` +} + +func dbtCloudTaskOutputFromWire(w *dbtCloudTaskOutputWire) (*DbtCloudTaskOutput, error) { + if w == nil { + return nil, nil + } + dbtCloudJobRunOutputPublicValue, err := convertSlice(w.DbtCloudJobRunOutput, dbtCloudJobRunStepFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DbtCloudTaskOutput.DbtCloudJobRunOutput", err) + } + return &DbtCloudTaskOutput{ + DbtCloudJobRunId: w.DbtCloudJobRunId, + DbtCloudJobRunUrl: w.DbtCloudJobRunUrl, + DbtCloudJobRunOutput: dbtCloudJobRunOutputPublicValue, + }, nil +} + +type dbtPlatformJobRunStepWire struct { + Index *int `json:"index,omitempty"` + Name *string `json:"name,omitempty"` + Status DbtPlatformRunStatus `json:"status,omitempty"` + Logs *string `json:"logs,omitempty"` + NameTruncated *bool `json:"name_truncated,omitempty"` + LogsTruncated *bool `json:"logs_truncated,omitempty"` +} + +func dbtPlatformJobRunStepFromWire(w *dbtPlatformJobRunStepWire) (*DbtPlatformJobRunStep, error) { + if w == nil { + return nil, nil + } + return &DbtPlatformJobRunStep{ + Index: w.Index, + Name: w.Name, + Status: w.Status, + Logs: w.Logs, + NameTruncated: w.NameTruncated, + LogsTruncated: w.LogsTruncated, + }, nil +} + +type dbtPlatformTaskWire struct { + DbtPlatformJobId *string `json:"dbt_platform_job_id,omitempty"` + ConnectionResourceName *string `json:"connection_resource_name,omitempty"` +} + +func dbtPlatformTaskToWire(v *DbtPlatformTask) (*dbtPlatformTaskWire, error) { + if v == nil { + return nil, nil + } + return &dbtPlatformTaskWire{ + DbtPlatformJobId: v.DbtPlatformJobId, + ConnectionResourceName: v.ConnectionResourceName, + }, nil +} + +func dbtPlatformTaskFromWire(w *dbtPlatformTaskWire) (*DbtPlatformTask, error) { + if w == nil { + return nil, nil + } + return &DbtPlatformTask{ + DbtPlatformJobId: w.DbtPlatformJobId, + ConnectionResourceName: w.ConnectionResourceName, + }, nil +} + +type dbtPlatformTaskOutputWire struct { + DbtPlatformJobRunId *string `json:"dbt_platform_job_run_id,omitempty"` + DbtPlatformJobRunUrl *string `json:"dbt_platform_job_run_url,omitempty"` + DbtPlatformJobRunOutput []dbtPlatformJobRunStepWire `json:"dbt_platform_job_run_output,omitempty"` + StepsTruncated *bool `json:"steps_truncated,omitempty"` +} + +func dbtPlatformTaskOutputFromWire(w *dbtPlatformTaskOutputWire) (*DbtPlatformTaskOutput, error) { + if w == nil { + return nil, nil + } + dbtPlatformJobRunOutputPublicValue, err := convertSlice(w.DbtPlatformJobRunOutput, dbtPlatformJobRunStepFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DbtPlatformTaskOutput.DbtPlatformJobRunOutput", err) + } + return &DbtPlatformTaskOutput{ + DbtPlatformJobRunId: w.DbtPlatformJobRunId, + DbtPlatformJobRunUrl: w.DbtPlatformJobRunUrl, + DbtPlatformJobRunOutput: dbtPlatformJobRunOutputPublicValue, + StepsTruncated: w.StepsTruncated, + }, nil +} + +type dbtTaskWire struct { + ProjectDirectory *string `json:"project_directory,omitempty"` + Commands []string `json:"commands,omitempty"` + Schema *string `json:"schema,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + ProfilesDirectory *string `json:"profiles_directory,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Source Source `json:"source,omitempty"` +} + +func dbtTaskToWire(v *DbtTask) (*dbtTaskWire, error) { + if v == nil { + return nil, nil + } + return &dbtTaskWire{ + ProjectDirectory: v.ProjectDirectory, + Commands: v.Commands, + Schema: v.Schema, + WarehouseId: v.WarehouseId, + ProfilesDirectory: v.ProfilesDirectory, + Catalog: v.Catalog, + Source: v.Source, + }, nil +} + +func dbtTaskFromWire(w *dbtTaskWire) (*DbtTask, error) { + if w == nil { + return nil, nil + } + return &DbtTask{ + ProjectDirectory: w.ProjectDirectory, + Commands: w.Commands, + Schema: w.Schema, + WarehouseId: w.WarehouseId, + ProfilesDirectory: w.ProfilesDirectory, + Catalog: w.Catalog, + Source: w.Source, + }, nil +} + +type dbtTask_DbtTaskOutputWire struct { + ArtifactsLink *string `json:"artifacts_link,omitempty"` + ArtifactsHeaders map[string]string `json:"artifacts_headers,omitempty"` +} + +func dbtTask_DbtTaskOutputFromWire(w *dbtTask_DbtTaskOutputWire) (*DbtTask_DbtTaskOutput, error) { + if w == nil { + return nil, nil + } + return &DbtTask_DbtTaskOutput{ + ArtifactsLink: w.ArtifactsLink, + ArtifactsHeaders: w.ArtifactsHeaders, + }, nil +} + +type deleteJobRequestWire struct { + JobId *int64 `json:"job_id,omitempty"` +} + +func deleteJobRequestToWire(v *DeleteJobRequest) (*deleteJobRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteJobRequestWire{ + JobId: v.JobId, + }, nil +} + +type deleteRunRequestWire struct { + RunId *int64 `json:"run_id,omitempty"` +} + +func deleteRunRequestToWire(v *DeleteRunRequest) (*deleteRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteRunRequestWire{ + RunId: v.RunId, + }, nil +} + +type deploymentSpecWire struct { + CommandPath *string `json:"command_path,omitempty"` + Compute *computeSpecWire `json:"compute,omitempty"` + Name *string `json:"name,omitempty"` +} + +func deploymentSpecToWire(v *DeploymentSpec) (*deploymentSpecWire, error) { + if v == nil { + return nil, nil + } + computeWireValue, err := computeSpecToWire(v.Compute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeploymentSpec.Compute", err) + } + return &deploymentSpecWire{ + CommandPath: v.CommandPath, + Compute: computeWireValue, + Name: v.Name, + }, nil +} + +func deploymentSpecFromWire(w *deploymentSpecWire) (*DeploymentSpec, error) { + if w == nil { + return nil, nil + } + computePublicValue, err := computeSpecFromWire(w.Compute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeploymentSpec.Compute", err) + } + return &DeploymentSpec{ + CommandPath: w.CommandPath, + Compute: computePublicValue, + Name: w.Name, + }, nil +} + +type dockerBasicAuthWire struct { + Username *string `json:"username,omitempty"` + Password *string `json:"password,omitempty"` +} + +func dockerBasicAuthToWire(v *DockerBasicAuth) (*dockerBasicAuthWire, error) { + if v == nil { + return nil, nil + } + return &dockerBasicAuthWire{ + Username: v.Username, + Password: v.Password, + }, nil +} + +func dockerBasicAuthFromWire(w *dockerBasicAuthWire) (*DockerBasicAuth, error) { + if w == nil { + return nil, nil + } + return &DockerBasicAuth{ + Username: w.Username, + Password: w.Password, + }, nil +} + +type dockerImageWire struct { + Url *string `json:"url,omitempty"` + BasicAuth *dockerBasicAuthWire `json:"basic_auth,omitempty"` +} + +func dockerImageToWire(v *DockerImage) (*dockerImageWire, error) { + if v == nil { + return nil, nil + } + var credsOneofBasicAuthWire *dockerBasicAuthWire + switch value := v.CredsOneof.(type) { + case nil: + case *DockerImage_CredsOneof_BasicAuth: + if value != nil { + credsOneofBasicAuthConverted, err := dockerBasicAuthToWire(&value.BasicAuth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DockerImage.CredsOneof.BasicAuth", err) + } + credsOneofBasicAuthWire = credsOneofBasicAuthConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "DockerImage.CredsOneof", value) + } + return &dockerImageWire{ + Url: v.Url, + BasicAuth: credsOneofBasicAuthWire, + }, nil +} + +func dockerImageFromWire(w *dockerImageWire) (*DockerImage, error) { + if w == nil { + return nil, nil + } + credsOneofMembers := 0 + if w.BasicAuth != nil { + credsOneofMembers++ + } + if credsOneofMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "DockerImage.CredsOneof") + } + var credsOneofSelection isDockerImage_CredsOneof + switch { + case w.BasicAuth != nil: + credsOneofBasicAuthConverted, err := dockerBasicAuthFromWire(w.BasicAuth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DockerImage.CredsOneof.BasicAuth", err) + } + credsOneofSelection = &DockerImage_CredsOneof_BasicAuth{BasicAuth: *credsOneofBasicAuthConverted} + } + return &DockerImage{ + Url: w.Url, + CredsOneof: credsOneofSelection, + }, nil +} + +type enforcePolicyComplianceForJobWire struct { + JobId *int64 `json:"job_id,omitempty"` + ValidateOnly *bool `json:"validate_only,omitempty"` +} + +func enforcePolicyComplianceForJobToWire(v *EnforcePolicyComplianceForJob) (*enforcePolicyComplianceForJobWire, error) { + if v == nil { + return nil, nil + } + return &enforcePolicyComplianceForJobWire{ + JobId: v.JobId, + ValidateOnly: v.ValidateOnly, + }, nil +} + +type enforcePolicyComplianceResponseWire struct { + HasChanges *bool `json:"has_changes,omitempty"` + JobClusterChanges []enforcePolicyComplianceResponse_JobClusterSettingsChangeWire `json:"job_cluster_changes,omitempty"` + Settings *jobSettingsWire `json:"settings,omitempty"` +} + +func enforcePolicyComplianceResponseFromWire(w *enforcePolicyComplianceResponseWire) (*EnforcePolicyComplianceResponse, error) { + if w == nil { + return nil, nil + } + jobClusterChangesPublicValue, err := convertSlice(w.JobClusterChanges, enforcePolicyComplianceResponse_JobClusterSettingsChangeFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceResponse.JobClusterChanges", err) + } + settingsPublicValue, err := jobSettingsFromWire(w.Settings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnforcePolicyComplianceResponse.Settings", err) + } + return &EnforcePolicyComplianceResponse{ + HasChanges: w.HasChanges, + JobClusterChanges: jobClusterChangesPublicValue, + Settings: settingsPublicValue, + }, nil +} + +type enforcePolicyComplianceResponse_JobClusterSettingsChangeWire struct { + Field *string `json:"field,omitempty"` + PreviousValue *string `json:"previous_value,omitempty"` + NewValue *string `json:"new_value,omitempty"` +} + +func enforcePolicyComplianceResponse_JobClusterSettingsChangeFromWire(w *enforcePolicyComplianceResponse_JobClusterSettingsChangeWire) (*EnforcePolicyComplianceResponse_JobClusterSettingsChange, error) { + if w == nil { + return nil, nil + } + return &EnforcePolicyComplianceResponse_JobClusterSettingsChange{ + Field: w.Field, + PreviousValue: w.PreviousValue, + NewValue: w.NewValue, + }, nil +} + +type environmentWire struct { + Client *string `json:"client,omitempty"` + Dependencies []string `json:"dependencies,omitempty"` + BaseEnvironment *string `json:"base_environment,omitempty"` + EnvironmentVersion *string `json:"environment_version,omitempty"` + JavaDependencies []string `json:"java_dependencies,omitempty"` +} + +func environmentToWire(v *Environment) (*environmentWire, error) { + if v == nil { + return nil, nil + } + return &environmentWire{ + Client: v.Client, + Dependencies: v.Dependencies, + BaseEnvironment: v.BaseEnvironment, + EnvironmentVersion: v.EnvironmentVersion, + JavaDependencies: v.JavaDependencies, + }, nil +} + +func environmentFromWire(w *environmentWire) (*Environment, error) { + if w == nil { + return nil, nil + } + return &Environment{ + Client: w.Client, + Dependencies: w.Dependencies, + BaseEnvironment: w.BaseEnvironment, + EnvironmentVersion: w.EnvironmentVersion, + JavaDependencies: w.JavaDependencies, + }, nil +} + +type exportRunRequestWire struct { + RunId *int64 `json:"run_id,omitempty"` + ViewsToExport ViewsToExport `json:"views_to_export,omitempty"` +} + +func exportRunRequestToWire(v *ExportRunRequest) (*exportRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &exportRunRequestWire{ + RunId: v.RunId, + ViewsToExport: v.ViewsToExport, + }, nil +} + +type exportRunResponseWire struct { + Views []viewItemWire `json:"views,omitempty"` +} + +func exportRunResponseFromWire(w *exportRunResponseWire) (*ExportRunResponse, error) { + if w == nil { + return nil, nil + } + viewsPublicValue, err := convertSlice(w.Views, viewItemFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExportRunResponse.Views", err) + } + return &ExportRunResponse{ + Views: viewsPublicValue, + }, nil +} + +type fileArrivalTriggerConfigurationWire struct { + Url *string `json:"url,omitempty"` + MinTimeBetweenTriggersSeconds *int `json:"min_time_between_triggers_seconds,omitempty"` + WaitAfterLastChangeSeconds *int `json:"wait_after_last_change_seconds,omitempty"` +} + +func fileArrivalTriggerConfigurationToWire(v *FileArrivalTriggerConfiguration) (*fileArrivalTriggerConfigurationWire, error) { + if v == nil { + return nil, nil + } + return &fileArrivalTriggerConfigurationWire{ + Url: v.Url, + MinTimeBetweenTriggersSeconds: v.MinTimeBetweenTriggersSeconds, + WaitAfterLastChangeSeconds: v.WaitAfterLastChangeSeconds, + }, nil +} + +func fileArrivalTriggerConfigurationFromWire(w *fileArrivalTriggerConfigurationWire) (*FileArrivalTriggerConfiguration, error) { + if w == nil { + return nil, nil + } + return &FileArrivalTriggerConfiguration{ + Url: w.Url, + MinTimeBetweenTriggersSeconds: w.MinTimeBetweenTriggersSeconds, + WaitAfterLastChangeSeconds: w.WaitAfterLastChangeSeconds, + }, nil +} + +type fileArrivalTriggerStateWire struct { + UsingFileEvents *bool `json:"using_file_events,omitempty"` +} + +func fileArrivalTriggerStateFromWire(w *fileArrivalTriggerStateWire) (*FileArrivalTriggerState, error) { + if w == nil { + return nil, nil + } + return &FileArrivalTriggerState{ + UsingFileEvents: w.UsingFileEvents, + }, nil +} + +type forEachTaskWire struct { + Inputs *string `json:"inputs,omitempty"` + Concurrency *int `json:"concurrency,omitempty"` + Task *taskSettingsWire `json:"task,omitempty"` +} + +func forEachTaskToWire(v *ForEachTask) (*forEachTaskWire, error) { + if v == nil { + return nil, nil + } + taskWireValue, err := taskSettingsToWire(v.Task) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ForEachTask.Task", err) + } + return &forEachTaskWire{ + Inputs: v.Inputs, + Concurrency: v.Concurrency, + Task: taskWireValue, + }, nil +} + +func forEachTaskFromWire(w *forEachTaskWire) (*ForEachTask, error) { + if w == nil { + return nil, nil + } + taskPublicValue, err := taskSettingsFromWire(w.Task) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ForEachTask.Task", err) + } + return &ForEachTask{ + Inputs: w.Inputs, + Concurrency: w.Concurrency, + Task: taskPublicValue, + }, nil +} + +type gcpAttributesWire struct { + UsePreemptibleExecutors *bool `json:"use_preemptible_executors,omitempty"` + GoogleServiceAccount *string `json:"google_service_account,omitempty"` + BootDiskSize *int `json:"boot_disk_size,omitempty"` + Availability GcpAvailability `json:"availability,omitempty"` + ZoneId *string `json:"zone_id,omitempty"` + LocalSsdCount *int `json:"local_ssd_count,omitempty"` + FirstOnDemand *int `json:"first_on_demand,omitempty"` + ConfidentialComputeType ConfidentialComputeType `json:"confidential_compute_type,omitempty"` +} + +func gcpAttributesToWire(v *GcpAttributes) (*gcpAttributesWire, error) { + if v == nil { + return nil, nil + } + return &gcpAttributesWire{ + UsePreemptibleExecutors: v.UsePreemptibleExecutors, + GoogleServiceAccount: v.GoogleServiceAccount, + BootDiskSize: v.BootDiskSize, + Availability: v.Availability, + ZoneId: v.ZoneId, + LocalSsdCount: v.LocalSsdCount, + FirstOnDemand: v.FirstOnDemand, + ConfidentialComputeType: v.ConfidentialComputeType, + }, nil +} + +func gcpAttributesFromWire(w *gcpAttributesWire) (*GcpAttributes, error) { + if w == nil { + return nil, nil + } + return &GcpAttributes{ + UsePreemptibleExecutors: w.UsePreemptibleExecutors, + GoogleServiceAccount: w.GoogleServiceAccount, + BootDiskSize: w.BootDiskSize, + Availability: w.Availability, + ZoneId: w.ZoneId, + LocalSsdCount: w.LocalSsdCount, + FirstOnDemand: w.FirstOnDemand, + ConfidentialComputeType: w.ConfidentialComputeType, + }, nil +} + +type gcsStorageInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func gcsStorageInfoToWire(v *GcsStorageInfo) (*gcsStorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &gcsStorageInfoWire{ + Destination: v.Destination, + }, nil +} + +func gcsStorageInfoFromWire(w *gcsStorageInfoWire) (*GcsStorageInfo, error) { + if w == nil { + return nil, nil + } + return &GcsStorageInfo{ + Destination: w.Destination, + }, nil +} + +type genAiComputeTaskWire struct { + DlRuntimeImage *string `json:"dl_runtime_image,omitempty"` + Compute *computeConfigWire `json:"compute,omitempty"` + Command *string `json:"command,omitempty"` + Source Source `json:"source,omitempty"` + TrainingScriptPath *string `json:"training_script_path,omitempty"` + YamlParametersFilePath *string `json:"yaml_parameters_file_path,omitempty"` + YamlParameters *string `json:"yaml_parameters,omitempty"` + MlflowExperimentName *string `json:"mlflow_experiment_name,omitempty"` +} + +func genAiComputeTaskToWire(v *GenAiComputeTask) (*genAiComputeTaskWire, error) { + if v == nil { + return nil, nil + } + computeWireValue, err := computeConfigToWire(v.Compute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenAiComputeTask.Compute", err) + } + return &genAiComputeTaskWire{ + DlRuntimeImage: v.DlRuntimeImage, + Compute: computeWireValue, + Command: v.Command, + Source: v.Source, + TrainingScriptPath: v.TrainingScriptPath, + YamlParametersFilePath: v.YamlParametersFilePath, + YamlParameters: v.YamlParameters, + MlflowExperimentName: v.MlflowExperimentName, + }, nil +} + +func genAiComputeTaskFromWire(w *genAiComputeTaskWire) (*GenAiComputeTask, error) { + if w == nil { + return nil, nil + } + computePublicValue, err := computeConfigFromWire(w.Compute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenAiComputeTask.Compute", err) + } + return &GenAiComputeTask{ + DlRuntimeImage: w.DlRuntimeImage, + Compute: computePublicValue, + Command: w.Command, + Source: w.Source, + TrainingScriptPath: w.TrainingScriptPath, + YamlParametersFilePath: w.YamlParametersFilePath, + YamlParameters: w.YamlParameters, + MlflowExperimentName: w.MlflowExperimentName, + }, nil +} + +type getJobRequestWire struct { + JobId *int64 `json:"job_id,omitempty"` + IncludeTriggerState *bool `json:"include_trigger_state,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func getJobRequestToWire(v *GetJobRequest) (*getJobRequestWire, error) { + if v == nil { + return nil, nil + } + return &getJobRequestWire{ + JobId: v.JobId, + IncludeTriggerState: v.IncludeTriggerState, + PageToken: v.PageToken, + }, nil +} + +type getJobResponseWire struct { + NextPageToken *string `json:"next_page_token,omitempty"` + JobId *int64 `json:"job_id,omitempty"` + CreatorUserName *string `json:"creator_user_name,omitempty"` + RunAsUserName *string `json:"run_as_user_name,omitempty"` + Settings *jobSettingsWire `json:"settings,omitempty"` + CreatedTime *int64 `json:"created_time,omitempty"` + TriggerState *triggerStateWire `json:"trigger_state,omitempty"` + HasMore *bool `json:"has_more,omitempty"` + EffectiveBudgetPolicyId *string `json:"effective_budget_policy_id,omitempty"` + EffectiveUsagePolicyId *string `json:"effective_usage_policy_id,omitempty"` + TriggerDetails []triggerDetailsWire `json:"trigger_details,omitempty"` +} + +func getJobResponseFromWire(w *getJobResponseWire) (*GetJobResponse, error) { + if w == nil { + return nil, nil + } + settingsPublicValue, err := jobSettingsFromWire(w.Settings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetJobResponse.Settings", err) + } + triggerStatePublicValue, err := triggerStateFromWire(w.TriggerState) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetJobResponse.TriggerState", err) + } + triggerDetailsPublicValue, err := convertSlice(w.TriggerDetails, triggerDetailsFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetJobResponse.TriggerDetails", err) + } + return &GetJobResponse{ + NextPageToken: w.NextPageToken, + JobId: w.JobId, + CreatorUserName: w.CreatorUserName, + RunAsUserName: w.RunAsUserName, + Settings: settingsPublicValue, + CreatedTime: w.CreatedTime, + TriggerState: triggerStatePublicValue, + HasMore: w.HasMore, + EffectiveBudgetPolicyId: w.EffectiveBudgetPolicyId, + EffectiveUsagePolicyId: w.EffectiveUsagePolicyId, + TriggerDetails: triggerDetailsPublicValue, + }, nil +} + +type getPolicyComplianceForJobRequestWire struct { + JobId *int64 `json:"job_id,omitempty"` +} + +func getPolicyComplianceForJobRequestToWire(v *GetPolicyComplianceForJobRequest) (*getPolicyComplianceForJobRequestWire, error) { + if v == nil { + return nil, nil + } + return &getPolicyComplianceForJobRequestWire{ + JobId: v.JobId, + }, nil +} + +type getPolicyComplianceForJobResponseWire struct { + IsCompliant *bool `json:"is_compliant,omitempty"` + Violations map[string]string `json:"violations,omitempty"` +} + +func getPolicyComplianceForJobResponseFromWire(w *getPolicyComplianceForJobResponseWire) (*GetPolicyComplianceForJobResponse, error) { + if w == nil { + return nil, nil + } + return &GetPolicyComplianceForJobResponse{ + IsCompliant: w.IsCompliant, + Violations: w.Violations, + }, nil +} + +type getRunOutputRequestWire struct { + RunId *int64 `json:"run_id,omitempty"` +} + +func getRunOutputRequestToWire(v *GetRunOutputRequest) (*getRunOutputRequestWire, error) { + if v == nil { + return nil, nil + } + return &getRunOutputRequestWire{ + RunId: v.RunId, + }, nil +} + +type getRunOutputResponseWire struct { + Metadata *runWire `json:"metadata,omitempty"` + Error *string `json:"error,omitempty"` + Info *string `json:"info,omitempty"` + NotebookOutput *notebookTask_NotebookOutputWire `json:"notebook_output,omitempty"` + SqlOutput *sqlTask_SqlOutputWire `json:"sql_output,omitempty"` + DbtOutput *dbtTask_DbtTaskOutputWire `json:"dbt_output,omitempty"` + RunJobOutput *runJobTask_RunJobTaskOutputWire `json:"run_job_output,omitempty"` + CleanRoomsNotebookOutput *cleanRoomsNotebookTask_CleanRoomsNotebookTaskOutputWire `json:"clean_rooms_notebook_output,omitempty"` + DashboardOutput *dashboardTaskOutputWire `json:"dashboard_output,omitempty"` + DbtCloudOutput *dbtCloudTaskOutputWire `json:"dbt_cloud_output,omitempty"` + DbtPlatformOutput *dbtPlatformTaskOutputWire `json:"dbt_platform_output,omitempty"` + AlertOutput *alertTaskOutputWire `json:"alert_output,omitempty"` + AiRuntimeTaskOutput *aiRuntimeTaskOutputWire `json:"ai_runtime_task_output,omitempty"` + Logs *string `json:"logs,omitempty"` + LogsTruncated *bool `json:"logs_truncated,omitempty"` + ErrorTrace *string `json:"error_trace,omitempty"` +} + +func getRunOutputResponseFromWire(w *getRunOutputResponseWire) (*GetRunOutputResponse, error) { + if w == nil { + return nil, nil + } + resultMembers := 0 + if w.NotebookOutput != nil { + resultMembers++ + } + if w.SqlOutput != nil { + resultMembers++ + } + if w.DbtOutput != nil { + resultMembers++ + } + if w.RunJobOutput != nil { + resultMembers++ + } + if w.CleanRoomsNotebookOutput != nil { + resultMembers++ + } + if w.DashboardOutput != nil { + resultMembers++ + } + if w.DbtCloudOutput != nil { + resultMembers++ + } + if w.DbtPlatformOutput != nil { + resultMembers++ + } + if w.AlertOutput != nil { + resultMembers++ + } + if w.AiRuntimeTaskOutput != nil { + resultMembers++ + } + if resultMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "GetRunOutputResponse.Result") + } + metadataPublicValue, err := runFromWire(w.Metadata) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Metadata", err) + } + var resultSelection isGetRunOutputResponse_Result + switch { + case w.NotebookOutput != nil: + resultNotebookOutputConverted, err := notebookTask_NotebookOutputFromWire(w.NotebookOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Result.NotebookOutput", err) + } + resultSelection = &GetRunOutputResponse_Result_NotebookOutput{NotebookOutput: *resultNotebookOutputConverted} + case w.SqlOutput != nil: + resultSqlOutputConverted, err := sqlTask_SqlOutputFromWire(w.SqlOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Result.SqlOutput", err) + } + resultSelection = &GetRunOutputResponse_Result_SqlOutput{SqlOutput: *resultSqlOutputConverted} + case w.DbtOutput != nil: + resultDbtOutputConverted, err := dbtTask_DbtTaskOutputFromWire(w.DbtOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Result.DbtOutput", err) + } + resultSelection = &GetRunOutputResponse_Result_DbtOutput{DbtOutput: *resultDbtOutputConverted} + case w.RunJobOutput != nil: + resultRunJobOutputConverted, err := runJobTask_RunJobTaskOutputFromWire(w.RunJobOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Result.RunJobOutput", err) + } + resultSelection = &GetRunOutputResponse_Result_RunJobOutput{RunJobOutput: *resultRunJobOutputConverted} + case w.CleanRoomsNotebookOutput != nil: + resultCleanRoomsNotebookOutputConverted, err := cleanRoomsNotebookTask_CleanRoomsNotebookTaskOutputFromWire(w.CleanRoomsNotebookOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Result.CleanRoomsNotebookOutput", err) + } + resultSelection = &GetRunOutputResponse_Result_CleanRoomsNotebookOutput{CleanRoomsNotebookOutput: *resultCleanRoomsNotebookOutputConverted} + case w.DashboardOutput != nil: + resultDashboardOutputConverted, err := dashboardTaskOutputFromWire(w.DashboardOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Result.DashboardOutput", err) + } + resultSelection = &GetRunOutputResponse_Result_DashboardOutput{DashboardOutput: *resultDashboardOutputConverted} + case w.DbtCloudOutput != nil: + resultDbtCloudOutputConverted, err := dbtCloudTaskOutputFromWire(w.DbtCloudOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Result.DbtCloudOutput", err) + } + resultSelection = &GetRunOutputResponse_Result_DbtCloudOutput{DbtCloudOutput: *resultDbtCloudOutputConverted} + case w.DbtPlatformOutput != nil: + resultDbtPlatformOutputConverted, err := dbtPlatformTaskOutputFromWire(w.DbtPlatformOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Result.DbtPlatformOutput", err) + } + resultSelection = &GetRunOutputResponse_Result_DbtPlatformOutput{DbtPlatformOutput: *resultDbtPlatformOutputConverted} + case w.AlertOutput != nil: + resultAlertOutputConverted, err := alertTaskOutputFromWire(w.AlertOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Result.AlertOutput", err) + } + resultSelection = &GetRunOutputResponse_Result_AlertOutput{AlertOutput: *resultAlertOutputConverted} + case w.AiRuntimeTaskOutput != nil: + resultAiRuntimeTaskOutputConverted, err := aiRuntimeTaskOutputFromWire(w.AiRuntimeTaskOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunOutputResponse.Result.AiRuntimeTaskOutput", err) + } + resultSelection = &GetRunOutputResponse_Result_AiRuntimeTaskOutput{AiRuntimeTaskOutput: *resultAiRuntimeTaskOutputConverted} + } + return &GetRunOutputResponse{ + Metadata: metadataPublicValue, + Error: w.Error, + Info: w.Info, + Logs: w.Logs, + LogsTruncated: w.LogsTruncated, + ErrorTrace: w.ErrorTrace, + Result: resultSelection, + }, nil +} + +type getRunRequestWire struct { + RunId *int64 `json:"run_id,omitempty"` + IncludeHistory *bool `json:"include_history,omitempty"` + IncludeResolvedValues *bool `json:"include_resolved_values,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func getRunRequestToWire(v *GetRunRequest) (*getRunRequestWire, error) { + if v == nil { + return nil, nil + } + return &getRunRequestWire{ + RunId: v.RunId, + IncludeHistory: v.IncludeHistory, + IncludeResolvedValues: v.IncludeResolvedValues, + PageToken: v.PageToken, + }, nil +} + +type getRunResponseWire struct { + NextPageToken *string `json:"next_page_token,omitempty"` + JobId *int64 `json:"job_id,omitempty"` + RunId *int64 `json:"run_id,omitempty"` + CreatorUserName *string `json:"creator_user_name,omitempty"` + NumberInJob *int64 `json:"number_in_job,omitempty"` + OriginalAttemptRunId *int64 `json:"original_attempt_run_id,omitempty"` + State *runStateWire `json:"state,omitempty"` + Schedule *cronScheduleWire `json:"schedule,omitempty"` + ClusterSpec *clusterSpecWire `json:"cluster_spec,omitempty"` + ClusterInstance *clusterInstanceWire `json:"cluster_instance,omitempty"` + JobParameters []run_JobLevelParametersWire `json:"job_parameters,omitempty"` + OverridingParameters *runParametersWire `json:"overriding_parameters,omitempty"` + Trigger TriggerType `json:"trigger,omitempty"` + TriggerInfo *runTriggerInfoWire `json:"trigger_info,omitempty"` + RunName *string `json:"run_name,omitempty"` + RunPageUrl *string `json:"run_page_url,omitempty"` + RunType RunType `json:"run_type,omitempty"` + Tasks []runTaskWire `json:"tasks,omitempty"` + Description *string `json:"description,omitempty"` + AttemptNumber *int `json:"attempt_number,omitempty"` + JobClusters []jobClusterWire `json:"job_clusters,omitempty"` + GitSource *gitSourceWire `json:"git_source,omitempty"` + RepairHistory []repairWire `json:"repair_history,omitempty"` + Status *runStatusWire `json:"status,omitempty"` + JobRunId *int64 `json:"job_run_id,omitempty"` + HasMore *bool `json:"has_more,omitempty"` + EffectivePerformanceTarget PerformanceTarget_PerformanceTarget `json:"effective_performance_target,omitempty"` + EffectiveUsagePolicyId *string `json:"effective_usage_policy_id,omitempty"` + DeploymentId *string `json:"deployment_id,omitempty"` + VersionId *string `json:"version_id,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + SetupDuration *int64 `json:"setup_duration,omitempty"` + ExecutionDuration *int64 `json:"execution_duration,omitempty"` + CleanupDuration *int64 `json:"cleanup_duration,omitempty"` + EndTime *int64 `json:"end_time,omitempty"` + RunDuration *int64 `json:"run_duration,omitempty"` + QueueDuration *int64 `json:"queue_duration,omitempty"` +} + +func getRunResponseFromWire(w *getRunResponseWire) (*GetRunResponse, error) { + if w == nil { + return nil, nil + } + statePublicValue, err := runStateFromWire(w.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.State", err) + } + schedulePublicValue, err := cronScheduleFromWire(w.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.Schedule", err) + } + clusterSpecPublicValue, err := clusterSpecFromWire(w.ClusterSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.ClusterSpec", err) + } + clusterInstancePublicValue, err := clusterInstanceFromWire(w.ClusterInstance) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.ClusterInstance", err) + } + jobParametersPublicValue, err := convertSlice(w.JobParameters, run_JobLevelParametersFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.JobParameters", err) + } + overridingParametersPublicValue, err := runParametersFromWire(w.OverridingParameters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.OverridingParameters", err) + } + triggerInfoPublicValue, err := runTriggerInfoFromWire(w.TriggerInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.TriggerInfo", err) + } + tasksPublicValue, err := convertSlice(w.Tasks, runTaskFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.Tasks", err) + } + jobClustersPublicValue, err := convertSlice(w.JobClusters, jobClusterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.JobClusters", err) + } + gitSourcePublicValue, err := gitSourceFromWire(w.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.GitSource", err) + } + repairHistoryPublicValue, err := convertSlice(w.RepairHistory, repairFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.RepairHistory", err) + } + statusPublicValue, err := runStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRunResponse.Status", err) + } + return &GetRunResponse{ + NextPageToken: w.NextPageToken, + JobId: w.JobId, + RunId: w.RunId, + CreatorUserName: w.CreatorUserName, + NumberInJob: w.NumberInJob, + OriginalAttemptRunId: w.OriginalAttemptRunId, + State: statePublicValue, + Schedule: schedulePublicValue, + ClusterSpec: clusterSpecPublicValue, + ClusterInstance: clusterInstancePublicValue, + JobParameters: jobParametersPublicValue, + OverridingParameters: overridingParametersPublicValue, + Trigger: w.Trigger, + TriggerInfo: triggerInfoPublicValue, + RunName: w.RunName, + RunPageUrl: w.RunPageUrl, + RunType: w.RunType, + Tasks: tasksPublicValue, + Description: w.Description, + AttemptNumber: w.AttemptNumber, + JobClusters: jobClustersPublicValue, + GitSource: gitSourcePublicValue, + RepairHistory: repairHistoryPublicValue, + Status: statusPublicValue, + JobRunId: w.JobRunId, + HasMore: w.HasMore, + EffectivePerformanceTarget: w.EffectivePerformanceTarget, + EffectiveUsagePolicyId: w.EffectiveUsagePolicyId, + DeploymentId: w.DeploymentId, + VersionId: w.VersionId, + StartTime: w.StartTime, + SetupDuration: w.SetupDuration, + ExecutionDuration: w.ExecutionDuration, + CleanupDuration: w.CleanupDuration, + EndTime: w.EndTime, + RunDuration: w.RunDuration, + QueueDuration: w.QueueDuration, + }, nil +} + +type gitMetadataSnapshotWire struct { + UsedCommit *string `json:"used_commit,omitempty"` +} + +func gitMetadataSnapshotToWire(v *GitMetadataSnapshot) (*gitMetadataSnapshotWire, error) { + if v == nil { + return nil, nil + } + return &gitMetadataSnapshotWire{ + UsedCommit: v.UsedCommit, + }, nil +} + +func gitMetadataSnapshotFromWire(w *gitMetadataSnapshotWire) (*GitMetadataSnapshot, error) { + if w == nil { + return nil, nil + } + return &GitMetadataSnapshot{ + UsedCommit: w.UsedCommit, + }, nil +} + +type gitSourceWire struct { + GitUrl *string `json:"git_url,omitempty"` + GitProvider *string `json:"git_provider,omitempty"` + GitBranch *string `json:"git_branch,omitempty"` + GitTag *string `json:"git_tag,omitempty"` + GitCommit *string `json:"git_commit,omitempty"` + GitSnapshot *gitMetadataSnapshotWire `json:"git_snapshot,omitempty"` + JobSource *jobSourceWire `json:"job_source,omitempty"` + SparseCheckout *sparseCheckoutWire `json:"sparse_checkout,omitempty"` +} + +func gitSourceToWire(v *GitSource) (*gitSourceWire, error) { + if v == nil { + return nil, nil + } + gitSnapshotWireValue, err := gitMetadataSnapshotToWire(v.GitSnapshot) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GitSource.GitSnapshot", err) + } + jobSourceWireValue, err := jobSourceToWire(v.JobSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GitSource.JobSource", err) + } + sparseCheckoutWireValue, err := sparseCheckoutToWire(v.SparseCheckout) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GitSource.SparseCheckout", err) + } + var gitReferenceGitBranchWire *string + var gitReferenceGitTagWire *string + var gitReferenceGitCommitWire *string + switch value := v.GitReference.(type) { + case nil: + case *GitSource_GitReference_GitBranch: + if value != nil { + gitReferenceGitBranchWire = new(value.GitBranch) + } + case *GitSource_GitReference_GitTag: + if value != nil { + gitReferenceGitTagWire = new(value.GitTag) + } + case *GitSource_GitReference_GitCommit: + if value != nil { + gitReferenceGitCommitWire = new(value.GitCommit) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "GitSource.GitReference", value) + } + return &gitSourceWire{ + GitUrl: v.GitUrl, + GitProvider: v.GitProvider, + GitBranch: gitReferenceGitBranchWire, + GitTag: gitReferenceGitTagWire, + GitCommit: gitReferenceGitCommitWire, + GitSnapshot: gitSnapshotWireValue, + JobSource: jobSourceWireValue, + SparseCheckout: sparseCheckoutWireValue, + }, nil +} + +func gitSourceFromWire(w *gitSourceWire) (*GitSource, error) { + if w == nil { + return nil, nil + } + gitReferenceMembers := 0 + if w.GitBranch != nil { + gitReferenceMembers++ + } + if w.GitTag != nil { + gitReferenceMembers++ + } + if w.GitCommit != nil { + gitReferenceMembers++ + } + if gitReferenceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "GitSource.GitReference") + } + gitSnapshotPublicValue, err := gitMetadataSnapshotFromWire(w.GitSnapshot) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GitSource.GitSnapshot", err) + } + jobSourcePublicValue, err := jobSourceFromWire(w.JobSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GitSource.JobSource", err) + } + sparseCheckoutPublicValue, err := sparseCheckoutFromWire(w.SparseCheckout) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GitSource.SparseCheckout", err) + } + var gitReferenceSelection isGitSource_GitReference + switch { + case w.GitBranch != nil: + gitReferenceSelection = &GitSource_GitReference_GitBranch{GitBranch: *w.GitBranch} + case w.GitTag != nil: + gitReferenceSelection = &GitSource_GitReference_GitTag{GitTag: *w.GitTag} + case w.GitCommit != nil: + gitReferenceSelection = &GitSource_GitReference_GitCommit{GitCommit: *w.GitCommit} + } + return &GitSource{ + GitUrl: w.GitUrl, + GitProvider: w.GitProvider, + GitSnapshot: gitSnapshotPublicValue, + JobSource: jobSourcePublicValue, + SparseCheckout: sparseCheckoutPublicValue, + GitReference: gitReferenceSelection, + }, nil +} + +type initScriptInfoWire struct { + Dbfs *dbfsStorageInfoWire `json:"dbfs,omitempty"` + S3 *s3StorageInfoWire `json:"s3,omitempty"` + File *localFileInfoWire `json:"file,omitempty"` + Gcs *gcsStorageInfoWire `json:"gcs,omitempty"` + Abfss *adlsgen2InfoWire `json:"abfss,omitempty"` + Workspace *workspaceStorageInfoWire `json:"workspace,omitempty"` + Volumes *volumesStorageInfoWire `json:"volumes,omitempty"` +} + +func initScriptInfoToWire(v *InitScriptInfo) (*initScriptInfoWire, error) { + if v == nil { + return nil, nil + } + var storageInfoDbfsWire *dbfsStorageInfoWire + var storageInfoS3Wire *s3StorageInfoWire + var storageInfoFileWire *localFileInfoWire + var storageInfoGcsWire *gcsStorageInfoWire + var storageInfoAbfssWire *adlsgen2InfoWire + var storageInfoWorkspaceWire *workspaceStorageInfoWire + var storageInfoVolumesWire *volumesStorageInfoWire + switch value := v.StorageInfo.(type) { + case nil: + case *InitScriptInfo_StorageInfo_Dbfs: + if value != nil { + storageInfoDbfsConverted, err := dbfsStorageInfoToWire(&value.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Dbfs", err) + } + storageInfoDbfsWire = storageInfoDbfsConverted + } + case *InitScriptInfo_StorageInfo_S3: + if value != nil { + storageInfoS3Converted, err := s3StorageInfoToWire(&value.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.S3", err) + } + storageInfoS3Wire = storageInfoS3Converted + } + case *InitScriptInfo_StorageInfo_File: + if value != nil { + storageInfoFileConverted, err := localFileInfoToWire(&value.File) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.File", err) + } + storageInfoFileWire = storageInfoFileConverted + } + case *InitScriptInfo_StorageInfo_Gcs: + if value != nil { + storageInfoGcsConverted, err := gcsStorageInfoToWire(&value.Gcs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Gcs", err) + } + storageInfoGcsWire = storageInfoGcsConverted + } + case *InitScriptInfo_StorageInfo_Abfss: + if value != nil { + storageInfoAbfssConverted, err := adlsgen2InfoToWire(&value.Abfss) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Abfss", err) + } + storageInfoAbfssWire = storageInfoAbfssConverted + } + case *InitScriptInfo_StorageInfo_Workspace: + if value != nil { + storageInfoWorkspaceConverted, err := workspaceStorageInfoToWire(&value.Workspace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Workspace", err) + } + storageInfoWorkspaceWire = storageInfoWorkspaceConverted + } + case *InitScriptInfo_StorageInfo_Volumes: + if value != nil { + storageInfoVolumesConverted, err := volumesStorageInfoToWire(&value.Volumes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Volumes", err) + } + storageInfoVolumesWire = storageInfoVolumesConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "InitScriptInfo.StorageInfo", value) + } + return &initScriptInfoWire{ + Dbfs: storageInfoDbfsWire, + S3: storageInfoS3Wire, + File: storageInfoFileWire, + Gcs: storageInfoGcsWire, + Abfss: storageInfoAbfssWire, + Workspace: storageInfoWorkspaceWire, + Volumes: storageInfoVolumesWire, + }, nil +} + +func initScriptInfoFromWire(w *initScriptInfoWire) (*InitScriptInfo, error) { + if w == nil { + return nil, nil + } + storageInfoMembers := 0 + if w.Dbfs != nil { + storageInfoMembers++ + } + if w.S3 != nil { + storageInfoMembers++ + } + if w.File != nil { + storageInfoMembers++ + } + if w.Gcs != nil { + storageInfoMembers++ + } + if w.Abfss != nil { + storageInfoMembers++ + } + if w.Workspace != nil { + storageInfoMembers++ + } + if w.Volumes != nil { + storageInfoMembers++ + } + if storageInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "InitScriptInfo.StorageInfo") + } + var storageInfoSelection isInitScriptInfo_StorageInfo + switch { + case w.Dbfs != nil: + storageInfoDbfsConverted, err := dbfsStorageInfoFromWire(w.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Dbfs", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_Dbfs{Dbfs: *storageInfoDbfsConverted} + case w.S3 != nil: + storageInfoS3Converted, err := s3StorageInfoFromWire(w.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.S3", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_S3{S3: *storageInfoS3Converted} + case w.File != nil: + storageInfoFileConverted, err := localFileInfoFromWire(w.File) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.File", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_File{File: *storageInfoFileConverted} + case w.Gcs != nil: + storageInfoGcsConverted, err := gcsStorageInfoFromWire(w.Gcs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Gcs", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_Gcs{Gcs: *storageInfoGcsConverted} + case w.Abfss != nil: + storageInfoAbfssConverted, err := adlsgen2InfoFromWire(w.Abfss) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Abfss", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_Abfss{Abfss: *storageInfoAbfssConverted} + case w.Workspace != nil: + storageInfoWorkspaceConverted, err := workspaceStorageInfoFromWire(w.Workspace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Workspace", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_Workspace{Workspace: *storageInfoWorkspaceConverted} + case w.Volumes != nil: + storageInfoVolumesConverted, err := volumesStorageInfoFromWire(w.Volumes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitScriptInfo.StorageInfo.Volumes", err) + } + storageInfoSelection = &InitScriptInfo_StorageInfo_Volumes{Volumes: *storageInfoVolumesConverted} + } + return &InitScriptInfo{ + StorageInfo: storageInfoSelection, + }, nil +} + +type jobClusterWire struct { + JobClusterKey *string `json:"job_cluster_key,omitempty"` + NewCluster *clusterSpec_NewClusterWire `json:"new_cluster,omitempty"` + ServerlessComputeId *string `json:"serverless_compute_id,omitempty"` +} + +func jobClusterToWire(v *JobCluster) (*jobClusterWire, error) { + if v == nil { + return nil, nil + } + newClusterWireValue, err := clusterSpec_NewClusterToWire(v.NewCluster) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobCluster.NewCluster", err) + } + return &jobClusterWire{ + JobClusterKey: v.JobClusterKey, + NewCluster: newClusterWireValue, + ServerlessComputeId: v.ServerlessComputeId, + }, nil +} + +func jobClusterFromWire(w *jobClusterWire) (*JobCluster, error) { + if w == nil { + return nil, nil + } + newClusterPublicValue, err := clusterSpec_NewClusterFromWire(w.NewCluster) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobCluster.NewCluster", err) + } + return &JobCluster{ + JobClusterKey: w.JobClusterKey, + NewCluster: newClusterPublicValue, + ServerlessComputeId: w.ServerlessComputeId, + }, nil +} + +type jobDeploymentWire struct { + Kind JobDeployment_DeploymentKind `json:"kind,omitempty"` + MetadataFilePath *string `json:"metadata_file_path,omitempty"` + DeploymentId *string `json:"deployment_id,omitempty"` + VersionId *string `json:"version_id,omitempty"` +} + +func jobDeploymentToWire(v *JobDeployment) (*jobDeploymentWire, error) { + if v == nil { + return nil, nil + } + return &jobDeploymentWire{ + Kind: v.Kind, + MetadataFilePath: v.MetadataFilePath, + DeploymentId: v.DeploymentId, + VersionId: v.VersionId, + }, nil +} + +func jobDeploymentFromWire(w *jobDeploymentWire) (*JobDeployment, error) { + if w == nil { + return nil, nil + } + return &JobDeployment{ + Kind: w.Kind, + MetadataFilePath: w.MetadataFilePath, + DeploymentId: w.DeploymentId, + VersionId: w.VersionId, + }, nil +} + +type jobEmailNotificationsWire struct { + OnStart []string `json:"on_start,omitempty"` + OnSuccess []string `json:"on_success,omitempty"` + OnFailure []string `json:"on_failure,omitempty"` + OnDurationWarningThresholdExceeded []string `json:"on_duration_warning_threshold_exceeded,omitempty"` + OnStreamingBacklogExceeded []string `json:"on_streaming_backlog_exceeded,omitempty"` + NoAlertForSkippedRuns *bool `json:"no_alert_for_skipped_runs,omitempty"` +} + +func jobEmailNotificationsToWire(v *JobEmailNotifications) (*jobEmailNotificationsWire, error) { + if v == nil { + return nil, nil + } + return &jobEmailNotificationsWire{ + OnStart: v.OnStart, + OnSuccess: v.OnSuccess, + OnFailure: v.OnFailure, + OnDurationWarningThresholdExceeded: v.OnDurationWarningThresholdExceeded, + OnStreamingBacklogExceeded: v.OnStreamingBacklogExceeded, + NoAlertForSkippedRuns: v.NoAlertForSkippedRuns, + }, nil +} + +func jobEmailNotificationsFromWire(w *jobEmailNotificationsWire) (*JobEmailNotifications, error) { + if w == nil { + return nil, nil + } + return &JobEmailNotifications{ + OnStart: w.OnStart, + OnSuccess: w.OnSuccess, + OnFailure: w.OnFailure, + OnDurationWarningThresholdExceeded: w.OnDurationWarningThresholdExceeded, + OnStreamingBacklogExceeded: w.OnStreamingBacklogExceeded, + NoAlertForSkippedRuns: w.NoAlertForSkippedRuns, + }, nil +} + +type jobEnvironmentWire struct { + EnvironmentKey *string `json:"environment_key,omitempty"` + Spec *environmentWire `json:"spec,omitempty"` +} + +func jobEnvironmentToWire(v *JobEnvironment) (*jobEnvironmentWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := environmentToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobEnvironment.Spec", err) + } + return &jobEnvironmentWire{ + EnvironmentKey: v.EnvironmentKey, + Spec: specWireValue, + }, nil +} + +func jobEnvironmentFromWire(w *jobEnvironmentWire) (*JobEnvironment, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := environmentFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobEnvironment.Spec", err) + } + return &JobEnvironment{ + EnvironmentKey: w.EnvironmentKey, + Spec: specPublicValue, + }, nil +} + +type jobLevelParameterWire struct { + Name *string `json:"name,omitempty"` + Default *string `json:"default,omitempty"` +} + +func jobLevelParameterToWire(v *JobLevelParameter) (*jobLevelParameterWire, error) { + if v == nil { + return nil, nil + } + return &jobLevelParameterWire{ + Name: v.Name, + Default: v.Default, + }, nil +} + +func jobLevelParameterFromWire(w *jobLevelParameterWire) (*JobLevelParameter, error) { + if w == nil { + return nil, nil + } + return &JobLevelParameter{ + Name: w.Name, + Default: w.Default, + }, nil +} + +type jobRunAsWire struct { + UserName *string `json:"user_name,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` + GroupName *string `json:"group_name,omitempty"` +} + +func jobRunAsToWire(v *JobRunAs) (*jobRunAsWire, error) { + if v == nil { + return nil, nil + } + var identityUserNameWire *string + var identityServicePrincipalNameWire *string + var identityGroupNameWire *string + switch value := v.Identity.(type) { + case nil: + case *JobRunAs_Identity_UserName: + if value != nil { + identityUserNameWire = new(value.UserName) + } + case *JobRunAs_Identity_ServicePrincipalName: + if value != nil { + identityServicePrincipalNameWire = new(value.ServicePrincipalName) + } + case *JobRunAs_Identity_GroupName: + if value != nil { + identityGroupNameWire = new(value.GroupName) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "JobRunAs.Identity", value) + } + return &jobRunAsWire{ + UserName: identityUserNameWire, + ServicePrincipalName: identityServicePrincipalNameWire, + GroupName: identityGroupNameWire, + }, nil +} + +func jobRunAsFromWire(w *jobRunAsWire) (*JobRunAs, error) { + if w == nil { + return nil, nil + } + identityMembers := 0 + if w.UserName != nil { + identityMembers++ + } + if w.ServicePrincipalName != nil { + identityMembers++ + } + if w.GroupName != nil { + identityMembers++ + } + if identityMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "JobRunAs.Identity") + } + var identitySelection isJobRunAs_Identity + switch { + case w.UserName != nil: + identitySelection = &JobRunAs_Identity_UserName{UserName: *w.UserName} + case w.ServicePrincipalName != nil: + identitySelection = &JobRunAs_Identity_ServicePrincipalName{ServicePrincipalName: *w.ServicePrincipalName} + case w.GroupName != nil: + identitySelection = &JobRunAs_Identity_GroupName{GroupName: *w.GroupName} + } + return &JobRunAs{ + Identity: identitySelection, + }, nil +} + +type jobSettingsWire struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + EmailNotifications *jobEmailNotificationsWire `json:"email_notifications,omitempty"` + WebhookNotifications *webhookNotificationsWire `json:"webhook_notifications,omitempty"` + NotificationSettings *notificationSettingsWire `json:"notification_settings,omitempty"` + TimeoutSeconds *int `json:"timeout_seconds,omitempty"` + Health *jobsHealthRulesWire `json:"health,omitempty"` + Schedule *cronScheduleWire `json:"schedule,omitempty"` + Trigger *triggerSettingsWire `json:"trigger,omitempty"` + Continuous *continuousSettingsWire `json:"continuous,omitempty"` + MaxConcurrentRuns *int `json:"max_concurrent_runs,omitempty"` + Tasks []taskSettingsWire `json:"tasks,omitempty"` + JobClusters []jobClusterWire `json:"job_clusters,omitempty"` + GitSource *gitSourceWire `json:"git_source,omitempty"` + Tags map[string]string `json:"tags,omitempty"` + Format Format `json:"format,omitempty"` + Queue *queueSettingsWire `json:"queue,omitempty"` + Parameters []jobLevelParameterWire `json:"parameters,omitempty"` + RunAs *jobRunAsWire `json:"run_as,omitempty"` + EditMode JobEditMode `json:"edit_mode,omitempty"` + Deployment *jobDeploymentWire `json:"deployment,omitempty"` + Environments []jobEnvironmentWire `json:"environments,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + PerformanceTarget PerformanceTarget_PerformanceTarget `json:"performance_target,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + Triggers []triggerConfigurationWire `json:"triggers,omitempty"` + MaxRetries *int `json:"max_retries,omitempty"` + MinRetryIntervalMillis *int `json:"min_retry_interval_millis,omitempty"` + RetryOnTimeout *bool `json:"retry_on_timeout,omitempty"` + DisableAutoOptimization *bool `json:"disable_auto_optimization,omitempty"` +} + +func jobSettingsToWire(v *JobSettings) (*jobSettingsWire, error) { + if v == nil { + return nil, nil + } + emailNotificationsWireValue, err := jobEmailNotificationsToWire(v.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.EmailNotifications", err) + } + webhookNotificationsWireValue, err := webhookNotificationsToWire(v.WebhookNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.WebhookNotifications", err) + } + notificationSettingsWireValue, err := notificationSettingsToWire(v.NotificationSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.NotificationSettings", err) + } + healthWireValue, err := jobsHealthRulesToWire(v.Health) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Health", err) + } + scheduleWireValue, err := cronScheduleToWire(v.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Schedule", err) + } + triggerWireValue, err := triggerSettingsToWire(v.Trigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Trigger", err) + } + continuousWireValue, err := continuousSettingsToWire(v.Continuous) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Continuous", err) + } + tasksWireValue, err := convertSlice(v.Tasks, taskSettingsToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Tasks", err) + } + jobClustersWireValue, err := convertSlice(v.JobClusters, jobClusterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.JobClusters", err) + } + gitSourceWireValue, err := gitSourceToWire(v.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.GitSource", err) + } + queueWireValue, err := queueSettingsToWire(v.Queue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Queue", err) + } + parametersWireValue, err := convertSlice(v.Parameters, jobLevelParameterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Parameters", err) + } + runAsWireValue, err := jobRunAsToWire(v.RunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.RunAs", err) + } + deploymentWireValue, err := jobDeploymentToWire(v.Deployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Deployment", err) + } + environmentsWireValue, err := convertSlice(v.Environments, jobEnvironmentToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Environments", err) + } + triggersWireValue, err := convertSlice(v.Triggers, triggerConfigurationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Triggers", err) + } + return &jobSettingsWire{ + Name: v.Name, + Description: v.Description, + EmailNotifications: emailNotificationsWireValue, + WebhookNotifications: webhookNotificationsWireValue, + NotificationSettings: notificationSettingsWireValue, + TimeoutSeconds: v.TimeoutSeconds, + Health: healthWireValue, + Schedule: scheduleWireValue, + Trigger: triggerWireValue, + Continuous: continuousWireValue, + MaxConcurrentRuns: v.MaxConcurrentRuns, + Tasks: tasksWireValue, + JobClusters: jobClustersWireValue, + GitSource: gitSourceWireValue, + Tags: v.Tags, + Format: v.Format, + Queue: queueWireValue, + Parameters: parametersWireValue, + RunAs: runAsWireValue, + EditMode: v.EditMode, + Deployment: deploymentWireValue, + Environments: environmentsWireValue, + BudgetPolicyId: v.BudgetPolicyId, + UsagePolicyId: v.UsagePolicyId, + PerformanceTarget: v.PerformanceTarget, + ParentPath: v.ParentPath, + Triggers: triggersWireValue, + MaxRetries: v.MaxRetries, + MinRetryIntervalMillis: v.MinRetryIntervalMillis, + RetryOnTimeout: v.RetryOnTimeout, + DisableAutoOptimization: v.DisableAutoOptimization, + }, nil +} + +func jobSettingsFromWire(w *jobSettingsWire) (*JobSettings, error) { + if w == nil { + return nil, nil + } + emailNotificationsPublicValue, err := jobEmailNotificationsFromWire(w.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.EmailNotifications", err) + } + webhookNotificationsPublicValue, err := webhookNotificationsFromWire(w.WebhookNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.WebhookNotifications", err) + } + notificationSettingsPublicValue, err := notificationSettingsFromWire(w.NotificationSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.NotificationSettings", err) + } + healthPublicValue, err := jobsHealthRulesFromWire(w.Health) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Health", err) + } + schedulePublicValue, err := cronScheduleFromWire(w.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Schedule", err) + } + triggerPublicValue, err := triggerSettingsFromWire(w.Trigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Trigger", err) + } + continuousPublicValue, err := continuousSettingsFromWire(w.Continuous) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Continuous", err) + } + tasksPublicValue, err := convertSlice(w.Tasks, taskSettingsFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Tasks", err) + } + jobClustersPublicValue, err := convertSlice(w.JobClusters, jobClusterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.JobClusters", err) + } + gitSourcePublicValue, err := gitSourceFromWire(w.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.GitSource", err) + } + queuePublicValue, err := queueSettingsFromWire(w.Queue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Queue", err) + } + parametersPublicValue, err := convertSlice(w.Parameters, jobLevelParameterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Parameters", err) + } + runAsPublicValue, err := jobRunAsFromWire(w.RunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.RunAs", err) + } + deploymentPublicValue, err := jobDeploymentFromWire(w.Deployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Deployment", err) + } + environmentsPublicValue, err := convertSlice(w.Environments, jobEnvironmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Environments", err) + } + triggersPublicValue, err := convertSlice(w.Triggers, triggerConfigurationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobSettings.Triggers", err) + } + return &JobSettings{ + Name: w.Name, + Description: w.Description, + EmailNotifications: emailNotificationsPublicValue, + WebhookNotifications: webhookNotificationsPublicValue, + NotificationSettings: notificationSettingsPublicValue, + TimeoutSeconds: w.TimeoutSeconds, + Health: healthPublicValue, + Schedule: schedulePublicValue, + Trigger: triggerPublicValue, + Continuous: continuousPublicValue, + MaxConcurrentRuns: w.MaxConcurrentRuns, + Tasks: tasksPublicValue, + JobClusters: jobClustersPublicValue, + GitSource: gitSourcePublicValue, + Tags: w.Tags, + Format: w.Format, + Queue: queuePublicValue, + Parameters: parametersPublicValue, + RunAs: runAsPublicValue, + EditMode: w.EditMode, + Deployment: deploymentPublicValue, + Environments: environmentsPublicValue, + BudgetPolicyId: w.BudgetPolicyId, + UsagePolicyId: w.UsagePolicyId, + PerformanceTarget: w.PerformanceTarget, + ParentPath: w.ParentPath, + Triggers: triggersPublicValue, + MaxRetries: w.MaxRetries, + MinRetryIntervalMillis: w.MinRetryIntervalMillis, + RetryOnTimeout: w.RetryOnTimeout, + DisableAutoOptimization: w.DisableAutoOptimization, + }, nil +} + +type jobSourceWire struct { + JobConfigPath *string `json:"job_config_path,omitempty"` + ImportFromGitBranch *string `json:"import_from_git_branch,omitempty"` + DirtyState JobSource_DirtyState `json:"dirty_state,omitempty"` +} + +func jobSourceToWire(v *JobSource) (*jobSourceWire, error) { + if v == nil { + return nil, nil + } + var importFromGitReferenceImportFromGitBranchWire *string + switch value := v.ImportFromGitReference.(type) { + case nil: + case *JobSource_ImportFromGitReference_ImportFromGitBranch: + if value != nil { + importFromGitReferenceImportFromGitBranchWire = new(value.ImportFromGitBranch) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "JobSource.ImportFromGitReference", value) + } + return &jobSourceWire{ + JobConfigPath: v.JobConfigPath, + ImportFromGitBranch: importFromGitReferenceImportFromGitBranchWire, + DirtyState: v.DirtyState, + }, nil +} + +func jobSourceFromWire(w *jobSourceWire) (*JobSource, error) { + if w == nil { + return nil, nil + } + importFromGitReferenceMembers := 0 + if w.ImportFromGitBranch != nil { + importFromGitReferenceMembers++ + } + if importFromGitReferenceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "JobSource.ImportFromGitReference") + } + var importFromGitReferenceSelection isJobSource_ImportFromGitReference + switch { + case w.ImportFromGitBranch != nil: + importFromGitReferenceSelection = &JobSource_ImportFromGitReference_ImportFromGitBranch{ImportFromGitBranch: *w.ImportFromGitBranch} + } + return &JobSource{ + JobConfigPath: w.JobConfigPath, + DirtyState: w.DirtyState, + ImportFromGitReference: importFromGitReferenceSelection, + }, nil +} + +type jobsHealthRuleWire struct { + Metric JobsHealthMetric `json:"metric,omitempty"` + Op JobsHealthOperator `json:"op,omitempty"` + Value *int64 `json:"value,omitempty"` +} + +func jobsHealthRuleToWire(v *JobsHealthRule) (*jobsHealthRuleWire, error) { + if v == nil { + return nil, nil + } + return &jobsHealthRuleWire{ + Metric: v.Metric, + Op: v.Op, + Value: v.Value, + }, nil +} + +func jobsHealthRuleFromWire(w *jobsHealthRuleWire) (*JobsHealthRule, error) { + if w == nil { + return nil, nil + } + return &JobsHealthRule{ + Metric: w.Metric, + Op: w.Op, + Value: w.Value, + }, nil +} + +type jobsHealthRulesWire struct { + Rules []jobsHealthRuleWire `json:"rules,omitempty"` +} + +func jobsHealthRulesToWire(v *JobsHealthRules) (*jobsHealthRulesWire, error) { + if v == nil { + return nil, nil + } + rulesWireValue, err := convertSlice(v.Rules, jobsHealthRuleToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobsHealthRules.Rules", err) + } + return &jobsHealthRulesWire{ + Rules: rulesWireValue, + }, nil +} + +func jobsHealthRulesFromWire(w *jobsHealthRulesWire) (*JobsHealthRules, error) { + if w == nil { + return nil, nil + } + rulesPublicValue, err := convertSlice(w.Rules, jobsHealthRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "JobsHealthRules.Rules", err) + } + return &JobsHealthRules{ + Rules: rulesPublicValue, + }, nil +} + +type libraryWire struct { + Jar *string `json:"jar,omitempty"` + Egg *string `json:"egg,omitempty"` + Pypi *pythonPyPiLibraryWire `json:"pypi,omitempty"` + Maven *mavenLibraryWire `json:"maven,omitempty"` + Cran *rCranLibraryWire `json:"cran,omitempty"` + Whl *string `json:"whl,omitempty"` + Requirements *string `json:"requirements,omitempty"` +} + +func libraryToWire(v *Library) (*libraryWire, error) { + if v == nil { + return nil, nil + } + var libJarWire *string + var libEggWire *string + var libPypiWire *pythonPyPiLibraryWire + var libMavenWire *mavenLibraryWire + var libCranWire *rCranLibraryWire + var libWhlWire *string + var libRequirementsWire *string + switch value := v.Lib.(type) { + case nil: + case *Library_Lib_Jar: + if value != nil { + libJarWire = new(value.Jar) + } + case *Library_Lib_Egg: + if value != nil { + libEggWire = new(value.Egg) + } + case *Library_Lib_Pypi: + if value != nil { + libPypiConverted, err := pythonPyPiLibraryToWire(&value.Pypi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Pypi", err) + } + libPypiWire = libPypiConverted + } + case *Library_Lib_Maven: + if value != nil { + libMavenConverted, err := mavenLibraryToWire(&value.Maven) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Maven", err) + } + libMavenWire = libMavenConverted + } + case *Library_Lib_Cran: + if value != nil { + libCranConverted, err := rCranLibraryToWire(&value.Cran) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Cran", err) + } + libCranWire = libCranConverted + } + case *Library_Lib_Whl: + if value != nil { + libWhlWire = new(value.Whl) + } + case *Library_Lib_Requirements: + if value != nil { + libRequirementsWire = new(value.Requirements) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Library.Lib", value) + } + return &libraryWire{ + Jar: libJarWire, + Egg: libEggWire, + Pypi: libPypiWire, + Maven: libMavenWire, + Cran: libCranWire, + Whl: libWhlWire, + Requirements: libRequirementsWire, + }, nil +} + +func libraryFromWire(w *libraryWire) (*Library, error) { + if w == nil { + return nil, nil + } + libMembers := 0 + if w.Jar != nil { + libMembers++ + } + if w.Egg != nil { + libMembers++ + } + if w.Pypi != nil { + libMembers++ + } + if w.Maven != nil { + libMembers++ + } + if w.Cran != nil { + libMembers++ + } + if w.Whl != nil { + libMembers++ + } + if w.Requirements != nil { + libMembers++ + } + if libMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Library.Lib") + } + var libSelection isLibrary_Lib + switch { + case w.Jar != nil: + libSelection = &Library_Lib_Jar{Jar: *w.Jar} + case w.Egg != nil: + libSelection = &Library_Lib_Egg{Egg: *w.Egg} + case w.Pypi != nil: + libPypiConverted, err := pythonPyPiLibraryFromWire(w.Pypi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Pypi", err) + } + libSelection = &Library_Lib_Pypi{Pypi: *libPypiConverted} + case w.Maven != nil: + libMavenConverted, err := mavenLibraryFromWire(w.Maven) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Maven", err) + } + libSelection = &Library_Lib_Maven{Maven: *libMavenConverted} + case w.Cran != nil: + libCranConverted, err := rCranLibraryFromWire(w.Cran) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Library.Lib.Cran", err) + } + libSelection = &Library_Lib_Cran{Cran: *libCranConverted} + case w.Whl != nil: + libSelection = &Library_Lib_Whl{Whl: *w.Whl} + case w.Requirements != nil: + libSelection = &Library_Lib_Requirements{Requirements: *w.Requirements} + } + return &Library{ + Lib: libSelection, + }, nil +} + +type listJobComplianceForPolicyWire struct { + PolicyId *string `json:"policy_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listJobComplianceForPolicyToWire(v *ListJobComplianceForPolicy) (*listJobComplianceForPolicyWire, error) { + if v == nil { + return nil, nil + } + return &listJobComplianceForPolicyWire{ + PolicyId: v.PolicyId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listJobComplianceForPolicy_JobComplianceWire struct { + JobId *int64 `json:"job_id,omitempty"` + IsCompliant *bool `json:"is_compliant,omitempty"` + Violations map[string]string `json:"violations,omitempty"` +} + +func listJobComplianceForPolicy_JobComplianceFromWire(w *listJobComplianceForPolicy_JobComplianceWire) (*ListJobComplianceForPolicy_JobCompliance, error) { + if w == nil { + return nil, nil + } + return &ListJobComplianceForPolicy_JobCompliance{ + JobId: w.JobId, + IsCompliant: w.IsCompliant, + Violations: w.Violations, + }, nil +} + +type listJobComplianceResponseWire struct { + Jobs []listJobComplianceForPolicy_JobComplianceWire `json:"jobs,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` + PrevPageToken *string `json:"prev_page_token,omitempty"` +} + +func listJobComplianceResponseFromWire(w *listJobComplianceResponseWire) (*ListJobComplianceResponse, error) { + if w == nil { + return nil, nil + } + jobsPublicValue, err := convertSlice(w.Jobs, listJobComplianceForPolicy_JobComplianceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListJobComplianceResponse.Jobs", err) + } + return &ListJobComplianceResponse{ + Jobs: jobsPublicValue, + NextPageToken: w.NextPageToken, + PrevPageToken: w.PrevPageToken, + }, nil +} + +type listJobsRequestWire struct { + Offset *int `json:"offset,omitempty"` + Limit *int `json:"limit,omitempty"` + ExpandTasks *bool `json:"expand_tasks,omitempty"` + Name *string `json:"name,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listJobsRequestToWire(v *ListJobsRequest) (*listJobsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listJobsRequestWire{ + Offset: v.Offset, + Limit: v.Limit, + ExpandTasks: v.ExpandTasks, + Name: v.Name, + PageToken: v.PageToken, + }, nil +} + +type listJobsResponseWire struct { + Jobs []baseJobWire `json:"jobs,omitempty"` + HasMore *bool `json:"has_more,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` + PrevPageToken *string `json:"prev_page_token,omitempty"` +} + +func listJobsResponseFromWire(w *listJobsResponseWire) (*ListJobsResponse, error) { + if w == nil { + return nil, nil + } + jobsPublicValue, err := convertSlice(w.Jobs, baseJobFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListJobsResponse.Jobs", err) + } + return &ListJobsResponse{ + Jobs: jobsPublicValue, + HasMore: w.HasMore, + NextPageToken: w.NextPageToken, + PrevPageToken: w.PrevPageToken, + }, nil +} + +type listRunsRequestWire struct { + JobId *int64 `json:"job_id,omitempty"` + ActiveOnly *bool `json:"active_only,omitempty"` + CompletedOnly *bool `json:"completed_only,omitempty"` + Offset *int `json:"offset,omitempty"` + Limit *int `json:"limit,omitempty"` + RunType RunType `json:"run_type,omitempty"` + ExpandTasks *bool `json:"expand_tasks,omitempty"` + StartTimeFrom *int64 `json:"start_time_from,omitempty"` + StartTimeTo *int64 `json:"start_time_to,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listRunsRequestToWire(v *ListRunsRequest) (*listRunsRequestWire, error) { + if v == nil { + return nil, nil + } + var stateConstraintActiveOnlyWire *bool + var stateConstraintCompletedOnlyWire *bool + switch value := v.StateConstraint.(type) { + case nil: + case *ListRunsRequest_StateConstraint_ActiveOnly: + if value != nil { + stateConstraintActiveOnlyWire = new(value.ActiveOnly) + } + case *ListRunsRequest_StateConstraint_CompletedOnly: + if value != nil { + stateConstraintCompletedOnlyWire = new(value.CompletedOnly) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ListRunsRequest.StateConstraint", value) + } + return &listRunsRequestWire{ + JobId: v.JobId, + ActiveOnly: stateConstraintActiveOnlyWire, + CompletedOnly: stateConstraintCompletedOnlyWire, + Offset: v.Offset, + Limit: v.Limit, + RunType: v.RunType, + ExpandTasks: v.ExpandTasks, + StartTimeFrom: v.StartTimeFrom, + StartTimeTo: v.StartTimeTo, + PageToken: v.PageToken, + }, nil +} + +type listRunsResponseWire struct { + Runs []baseRunWire `json:"runs,omitempty"` + HasMore *bool `json:"has_more,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` + PrevPageToken *string `json:"prev_page_token,omitempty"` +} + +func listRunsResponseFromWire(w *listRunsResponseWire) (*ListRunsResponse, error) { + if w == nil { + return nil, nil + } + runsPublicValue, err := convertSlice(w.Runs, baseRunFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListRunsResponse.Runs", err) + } + return &ListRunsResponse{ + Runs: runsPublicValue, + HasMore: w.HasMore, + NextPageToken: w.NextPageToken, + PrevPageToken: w.PrevPageToken, + }, nil +} + +type localFileInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func localFileInfoToWire(v *LocalFileInfo) (*localFileInfoWire, error) { + if v == nil { + return nil, nil + } + return &localFileInfoWire{ + Destination: v.Destination, + }, nil +} + +func localFileInfoFromWire(w *localFileInfoWire) (*LocalFileInfo, error) { + if w == nil { + return nil, nil + } + return &LocalFileInfo{ + Destination: w.Destination, + }, nil +} + +type logAnalyticsInfoWire struct { + LogAnalyticsWorkspaceId *string `json:"log_analytics_workspace_id,omitempty"` + LogAnalyticsPrimaryKey *string `json:"log_analytics_primary_key,omitempty"` +} + +func logAnalyticsInfoToWire(v *LogAnalyticsInfo) (*logAnalyticsInfoWire, error) { + if v == nil { + return nil, nil + } + return &logAnalyticsInfoWire{ + LogAnalyticsWorkspaceId: v.LogAnalyticsWorkspaceId, + LogAnalyticsPrimaryKey: v.LogAnalyticsPrimaryKey, + }, nil +} + +func logAnalyticsInfoFromWire(w *logAnalyticsInfoWire) (*LogAnalyticsInfo, error) { + if w == nil { + return nil, nil + } + return &LogAnalyticsInfo{ + LogAnalyticsWorkspaceId: w.LogAnalyticsWorkspaceId, + LogAnalyticsPrimaryKey: w.LogAnalyticsPrimaryKey, + }, nil +} + +type mavenLibraryWire struct { + Coordinates *string `json:"coordinates,omitempty"` + Repo *string `json:"repo,omitempty"` + Exclusions []string `json:"exclusions,omitempty"` +} + +func mavenLibraryToWire(v *MavenLibrary) (*mavenLibraryWire, error) { + if v == nil { + return nil, nil + } + return &mavenLibraryWire{ + Coordinates: v.Coordinates, + Repo: v.Repo, + Exclusions: v.Exclusions, + }, nil +} + +func mavenLibraryFromWire(w *mavenLibraryWire) (*MavenLibrary, error) { + if w == nil { + return nil, nil + } + return &MavenLibrary{ + Coordinates: w.Coordinates, + Repo: w.Repo, + Exclusions: w.Exclusions, + }, nil +} + +type modelTriggerConfigurationWire struct { + SecurableName *string `json:"securable_name,omitempty"` + Aliases []string `json:"aliases,omitempty"` + Condition ModelTriggerConfiguration_ModelTriggerCondition `json:"condition,omitempty"` + MinTimeBetweenTriggersSeconds *int `json:"min_time_between_triggers_seconds,omitempty"` + WaitAfterLastChangeSeconds *int `json:"wait_after_last_change_seconds,omitempty"` +} + +func modelTriggerConfigurationToWire(v *ModelTriggerConfiguration) (*modelTriggerConfigurationWire, error) { + if v == nil { + return nil, nil + } + return &modelTriggerConfigurationWire{ + SecurableName: v.SecurableName, + Aliases: v.Aliases, + Condition: v.Condition, + MinTimeBetweenTriggersSeconds: v.MinTimeBetweenTriggersSeconds, + WaitAfterLastChangeSeconds: v.WaitAfterLastChangeSeconds, + }, nil +} + +func modelTriggerConfigurationFromWire(w *modelTriggerConfigurationWire) (*ModelTriggerConfiguration, error) { + if w == nil { + return nil, nil + } + return &ModelTriggerConfiguration{ + SecurableName: w.SecurableName, + Aliases: w.Aliases, + Condition: w.Condition, + MinTimeBetweenTriggersSeconds: w.MinTimeBetweenTriggersSeconds, + WaitAfterLastChangeSeconds: w.WaitAfterLastChangeSeconds, + }, nil +} + +type modelTriggerStateWire struct { +} + +func modelTriggerStateFromWire(w *modelTriggerStateWire) (*ModelTriggerState, error) { + if w == nil { + return nil, nil + } + return &ModelTriggerState{}, nil +} + +type nodeTypeFlexibilityWire struct { + AlternateNodeTypeIds []string `json:"alternate_node_type_ids,omitempty"` +} + +func nodeTypeFlexibilityToWire(v *NodeTypeFlexibility) (*nodeTypeFlexibilityWire, error) { + if v == nil { + return nil, nil + } + return &nodeTypeFlexibilityWire{ + AlternateNodeTypeIds: v.AlternateNodeTypeIds, + }, nil +} + +func nodeTypeFlexibilityFromWire(w *nodeTypeFlexibilityWire) (*NodeTypeFlexibility, error) { + if w == nil { + return nil, nil + } + return &NodeTypeFlexibility{ + AlternateNodeTypeIds: w.AlternateNodeTypeIds, + }, nil +} + +type notebookTaskWire struct { + NotebookPath *string `json:"notebook_path,omitempty"` + BaseParameters map[string]string `json:"base_parameters,omitempty"` + Source Source `json:"source,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` +} + +func notebookTaskToWire(v *NotebookTask) (*notebookTaskWire, error) { + if v == nil { + return nil, nil + } + return ¬ebookTaskWire{ + NotebookPath: v.NotebookPath, + BaseParameters: v.BaseParameters, + Source: v.Source, + WarehouseId: v.WarehouseId, + }, nil +} + +func notebookTaskFromWire(w *notebookTaskWire) (*NotebookTask, error) { + if w == nil { + return nil, nil + } + return &NotebookTask{ + NotebookPath: w.NotebookPath, + BaseParameters: w.BaseParameters, + Source: w.Source, + WarehouseId: w.WarehouseId, + }, nil +} + +type notebookTask_NotebookOutputWire struct { + Result *string `json:"result,omitempty"` + Truncated *bool `json:"truncated,omitempty"` +} + +func notebookTask_NotebookOutputFromWire(w *notebookTask_NotebookOutputWire) (*NotebookTask_NotebookOutput, error) { + if w == nil { + return nil, nil + } + return &NotebookTask_NotebookOutput{ + Result: w.Result, + Truncated: w.Truncated, + }, nil +} + +type notificationSettingsWire struct { + NoAlertForSkippedRuns *bool `json:"no_alert_for_skipped_runs,omitempty"` + NoAlertForCanceledRuns *bool `json:"no_alert_for_canceled_runs,omitempty"` + AlertOnLastAttempt *bool `json:"alert_on_last_attempt,omitempty"` +} + +func notificationSettingsToWire(v *NotificationSettings) (*notificationSettingsWire, error) { + if v == nil { + return nil, nil + } + return ¬ificationSettingsWire{ + NoAlertForSkippedRuns: v.NoAlertForSkippedRuns, + NoAlertForCanceledRuns: v.NoAlertForCanceledRuns, + AlertOnLastAttempt: v.AlertOnLastAttempt, + }, nil +} + +func notificationSettingsFromWire(w *notificationSettingsWire) (*NotificationSettings, error) { + if w == nil { + return nil, nil + } + return &NotificationSettings{ + NoAlertForSkippedRuns: w.NoAlertForSkippedRuns, + NoAlertForCanceledRuns: w.NoAlertForCanceledRuns, + AlertOnLastAttempt: w.AlertOnLastAttempt, + }, nil +} + +type outputSchemaInfoWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + ExpirationTime *int64 `json:"expiration_time,omitempty"` +} + +func outputSchemaInfoFromWire(w *outputSchemaInfoWire) (*OutputSchemaInfo, error) { + if w == nil { + return nil, nil + } + return &OutputSchemaInfo{ + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + ExpirationTime: w.ExpirationTime, + }, nil +} + +type perTriggerStateWire struct { + Periodic *periodicTriggerStateWire `json:"periodic,omitempty"` + Schedule *scheduleTriggerStateWire `json:"schedule,omitempty"` + Continuous *continuousTriggerStateWire `json:"continuous,omitempty"` + FileArrival *fileArrivalTriggerStateWire `json:"file_arrival,omitempty"` + TableUpdate *tableTriggerStateWire `json:"table_update,omitempty"` + Model *modelTriggerStateWire `json:"model,omitempty"` + SqlCondition *sqlConditionStateWire `json:"sql_condition,omitempty"` + PauseStatus SchedulePauseStatus `json:"pause_status,omitempty"` +} + +func perTriggerStateFromWire(w *perTriggerStateWire) (*PerTriggerState, error) { + if w == nil { + return nil, nil + } + triggerTypeMembers := 0 + if w.Periodic != nil { + triggerTypeMembers++ + } + if w.Schedule != nil { + triggerTypeMembers++ + } + if w.Continuous != nil { + triggerTypeMembers++ + } + if w.FileArrival != nil { + triggerTypeMembers++ + } + if w.TableUpdate != nil { + triggerTypeMembers++ + } + if w.Model != nil { + triggerTypeMembers++ + } + if triggerTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PerTriggerState.TriggerType") + } + sqlConditionPublicValue, err := sqlConditionStateFromWire(w.SqlCondition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PerTriggerState.SqlCondition", err) + } + var triggerTypeSelection isPerTriggerState_TriggerType + switch { + case w.Periodic != nil: + triggerTypePeriodicConverted, err := periodicTriggerStateFromWire(w.Periodic) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PerTriggerState.TriggerType.Periodic", err) + } + triggerTypeSelection = &PerTriggerState_TriggerType_Periodic{Periodic: *triggerTypePeriodicConverted} + case w.Schedule != nil: + triggerTypeScheduleConverted, err := scheduleTriggerStateFromWire(w.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PerTriggerState.TriggerType.Schedule", err) + } + triggerTypeSelection = &PerTriggerState_TriggerType_Schedule{Schedule: *triggerTypeScheduleConverted} + case w.Continuous != nil: + triggerTypeContinuousConverted, err := continuousTriggerStateFromWire(w.Continuous) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PerTriggerState.TriggerType.Continuous", err) + } + triggerTypeSelection = &PerTriggerState_TriggerType_Continuous{Continuous: *triggerTypeContinuousConverted} + case w.FileArrival != nil: + triggerTypeFileArrivalConverted, err := fileArrivalTriggerStateFromWire(w.FileArrival) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PerTriggerState.TriggerType.FileArrival", err) + } + triggerTypeSelection = &PerTriggerState_TriggerType_FileArrival{FileArrival: *triggerTypeFileArrivalConverted} + case w.TableUpdate != nil: + triggerTypeTableUpdateConverted, err := tableTriggerStateFromWire(w.TableUpdate) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PerTriggerState.TriggerType.TableUpdate", err) + } + triggerTypeSelection = &PerTriggerState_TriggerType_TableUpdate{TableUpdate: *triggerTypeTableUpdateConverted} + case w.Model != nil: + triggerTypeModelConverted, err := modelTriggerStateFromWire(w.Model) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PerTriggerState.TriggerType.Model", err) + } + triggerTypeSelection = &PerTriggerState_TriggerType_Model{Model: *triggerTypeModelConverted} + } + return &PerTriggerState{ + SqlCondition: sqlConditionPublicValue, + PauseStatus: w.PauseStatus, + TriggerType: triggerTypeSelection, + }, nil +} + +type periodicTriggerConfigurationWire struct { + Interval *int `json:"interval,omitempty"` + Unit PeriodicTriggerConfiguration_TimeUnit `json:"unit,omitempty"` +} + +func periodicTriggerConfigurationToWire(v *PeriodicTriggerConfiguration) (*periodicTriggerConfigurationWire, error) { + if v == nil { + return nil, nil + } + return &periodicTriggerConfigurationWire{ + Interval: v.Interval, + Unit: v.Unit, + }, nil +} + +func periodicTriggerConfigurationFromWire(w *periodicTriggerConfigurationWire) (*PeriodicTriggerConfiguration, error) { + if w == nil { + return nil, nil + } + return &PeriodicTriggerConfiguration{ + Interval: w.Interval, + Unit: w.Unit, + }, nil +} + +type periodicTriggerStateWire struct { + NextRunTime *int64 `json:"next_run_time,omitempty"` +} + +func periodicTriggerStateFromWire(w *periodicTriggerStateWire) (*PeriodicTriggerState, error) { + if w == nil { + return nil, nil + } + return &PeriodicTriggerState{ + NextRunTime: w.NextRunTime, + }, nil +} + +type pipelineParametersWire struct { + FullRefresh *bool `json:"full_refresh,omitempty"` + RefreshSelection []string `json:"refresh_selection,omitempty"` + FullRefreshSelection []string `json:"full_refresh_selection,omitempty"` + ResetCheckpointSelection []string `json:"reset_checkpoint_selection,omitempty"` + RefreshFlowSelection []string `json:"refresh_flow_selection,omitempty"` +} + +func pipelineParametersToWire(v *PipelineParameters) (*pipelineParametersWire, error) { + if v == nil { + return nil, nil + } + return &pipelineParametersWire{ + FullRefresh: v.FullRefresh, + RefreshSelection: v.RefreshSelection, + FullRefreshSelection: v.FullRefreshSelection, + ResetCheckpointSelection: v.ResetCheckpointSelection, + RefreshFlowSelection: v.RefreshFlowSelection, + }, nil +} + +func pipelineParametersFromWire(w *pipelineParametersWire) (*PipelineParameters, error) { + if w == nil { + return nil, nil + } + return &PipelineParameters{ + FullRefresh: w.FullRefresh, + RefreshSelection: w.RefreshSelection, + FullRefreshSelection: w.FullRefreshSelection, + ResetCheckpointSelection: w.ResetCheckpointSelection, + RefreshFlowSelection: w.RefreshFlowSelection, + }, nil +} + +type pipelineTaskWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + PipelineTaskParameters map[string]string `json:"parameters,omitempty"` + FullRefresh *bool `json:"full_refresh,omitempty"` + RefreshSelection []string `json:"refresh_selection,omitempty"` + FullRefreshSelection []string `json:"full_refresh_selection,omitempty"` + ResetCheckpointSelection []string `json:"reset_checkpoint_selection,omitempty"` + RefreshFlowSelection []string `json:"refresh_flow_selection,omitempty"` +} + +func pipelineTaskToWire(v *PipelineTask) (*pipelineTaskWire, error) { + if v == nil { + return nil, nil + } + return &pipelineTaskWire{ + PipelineId: v.PipelineId, + PipelineTaskParameters: v.PipelineTaskParameters, + FullRefresh: v.FullRefresh, + RefreshSelection: v.RefreshSelection, + FullRefreshSelection: v.FullRefreshSelection, + ResetCheckpointSelection: v.ResetCheckpointSelection, + RefreshFlowSelection: v.RefreshFlowSelection, + }, nil +} + +func pipelineTaskFromWire(w *pipelineTaskWire) (*PipelineTask, error) { + if w == nil { + return nil, nil + } + return &PipelineTask{ + PipelineId: w.PipelineId, + PipelineTaskParameters: w.PipelineTaskParameters, + FullRefresh: w.FullRefresh, + RefreshSelection: w.RefreshSelection, + FullRefreshSelection: w.FullRefreshSelection, + ResetCheckpointSelection: w.ResetCheckpointSelection, + RefreshFlowSelection: w.RefreshFlowSelection, + }, nil +} + +type powerBiModelWire struct { + WorkspaceName *string `json:"workspace_name,omitempty"` + ModelName *string `json:"model_name,omitempty"` + StorageMode StorageMode `json:"storage_mode,omitempty"` + AuthenticationMethod AuthenticationMethod `json:"authentication_method,omitempty"` + OverwriteExisting *bool `json:"overwrite_existing,omitempty"` +} + +func powerBiModelToWire(v *PowerBiModel) (*powerBiModelWire, error) { + if v == nil { + return nil, nil + } + return &powerBiModelWire{ + WorkspaceName: v.WorkspaceName, + ModelName: v.ModelName, + StorageMode: v.StorageMode, + AuthenticationMethod: v.AuthenticationMethod, + OverwriteExisting: v.OverwriteExisting, + }, nil +} + +func powerBiModelFromWire(w *powerBiModelWire) (*PowerBiModel, error) { + if w == nil { + return nil, nil + } + return &PowerBiModel{ + WorkspaceName: w.WorkspaceName, + ModelName: w.ModelName, + StorageMode: w.StorageMode, + AuthenticationMethod: w.AuthenticationMethod, + OverwriteExisting: w.OverwriteExisting, + }, nil +} + +type powerBiTableWire struct { + Name *string `json:"name,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Schema *string `json:"schema,omitempty"` + StorageMode StorageMode `json:"storage_mode,omitempty"` +} + +func powerBiTableToWire(v *PowerBiTable) (*powerBiTableWire, error) { + if v == nil { + return nil, nil + } + return &powerBiTableWire{ + Name: v.Name, + Catalog: v.Catalog, + Schema: v.Schema, + StorageMode: v.StorageMode, + }, nil +} + +func powerBiTableFromWire(w *powerBiTableWire) (*PowerBiTable, error) { + if w == nil { + return nil, nil + } + return &PowerBiTable{ + Name: w.Name, + Catalog: w.Catalog, + Schema: w.Schema, + StorageMode: w.StorageMode, + }, nil +} + +type powerBiTaskWire struct { + Tables []powerBiTableWire `json:"tables,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + PowerBiModel *powerBiModelWire `json:"power_bi_model,omitempty"` + ConnectionResourceName *string `json:"connection_resource_name,omitempty"` + RefreshAfterUpdate *bool `json:"refresh_after_update,omitempty"` +} + +func powerBiTaskToWire(v *PowerBiTask) (*powerBiTaskWire, error) { + if v == nil { + return nil, nil + } + tablesWireValue, err := convertSlice(v.Tables, powerBiTableToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PowerBiTask.Tables", err) + } + powerBiModelWireValue, err := powerBiModelToWire(v.PowerBiModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PowerBiTask.PowerBiModel", err) + } + return &powerBiTaskWire{ + Tables: tablesWireValue, + WarehouseId: v.WarehouseId, + PowerBiModel: powerBiModelWireValue, + ConnectionResourceName: v.ConnectionResourceName, + RefreshAfterUpdate: v.RefreshAfterUpdate, + }, nil +} + +func powerBiTaskFromWire(w *powerBiTaskWire) (*PowerBiTask, error) { + if w == nil { + return nil, nil + } + tablesPublicValue, err := convertSlice(w.Tables, powerBiTableFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PowerBiTask.Tables", err) + } + powerBiModelPublicValue, err := powerBiModelFromWire(w.PowerBiModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PowerBiTask.PowerBiModel", err) + } + return &PowerBiTask{ + Tables: tablesPublicValue, + WarehouseId: w.WarehouseId, + PowerBiModel: powerBiModelPublicValue, + ConnectionResourceName: w.ConnectionResourceName, + RefreshAfterUpdate: w.RefreshAfterUpdate, + }, nil +} + +type pythonOperatorTaskWire struct { + Parameters []pythonOperatorTask_ParameterWire `json:"parameters,omitempty"` + Main *string `json:"main,omitempty"` +} + +func pythonOperatorTaskToWire(v *PythonOperatorTask) (*pythonOperatorTaskWire, error) { + if v == nil { + return nil, nil + } + parametersWireValue, err := convertSlice(v.Parameters, pythonOperatorTask_ParameterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PythonOperatorTask.Parameters", err) + } + return &pythonOperatorTaskWire{ + Parameters: parametersWireValue, + Main: v.Main, + }, nil +} + +func pythonOperatorTaskFromWire(w *pythonOperatorTaskWire) (*PythonOperatorTask, error) { + if w == nil { + return nil, nil + } + parametersPublicValue, err := convertSlice(w.Parameters, pythonOperatorTask_ParameterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PythonOperatorTask.Parameters", err) + } + return &PythonOperatorTask{ + Parameters: parametersPublicValue, + Main: w.Main, + }, nil +} + +type pythonOperatorTask_ParameterWire struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` +} + +func pythonOperatorTask_ParameterToWire(v *PythonOperatorTask_Parameter) (*pythonOperatorTask_ParameterWire, error) { + if v == nil { + return nil, nil + } + return &pythonOperatorTask_ParameterWire{ + Name: v.Name, + Value: v.Value, + }, nil +} + +func pythonOperatorTask_ParameterFromWire(w *pythonOperatorTask_ParameterWire) (*PythonOperatorTask_Parameter, error) { + if w == nil { + return nil, nil + } + return &PythonOperatorTask_Parameter{ + Name: w.Name, + Value: w.Value, + }, nil +} + +type pythonPyPiLibraryWire struct { + Package *string `json:"package,omitempty"` + Repo *string `json:"repo,omitempty"` +} + +func pythonPyPiLibraryToWire(v *PythonPyPiLibrary) (*pythonPyPiLibraryWire, error) { + if v == nil { + return nil, nil + } + return &pythonPyPiLibraryWire{ + Package: v.Package, + Repo: v.Repo, + }, nil +} + +func pythonPyPiLibraryFromWire(w *pythonPyPiLibraryWire) (*PythonPyPiLibrary, error) { + if w == nil { + return nil, nil + } + return &PythonPyPiLibrary{ + Package: w.Package, + Repo: w.Repo, + }, nil +} + +type pythonWheelTaskWire struct { + PackageName *string `json:"package_name,omitempty"` + EntryPoint *string `json:"entry_point,omitempty"` + Parameters []string `json:"parameters,omitempty"` + NamedParameters map[string]string `json:"named_parameters,omitempty"` +} + +func pythonWheelTaskToWire(v *PythonWheelTask) (*pythonWheelTaskWire, error) { + if v == nil { + return nil, nil + } + return &pythonWheelTaskWire{ + PackageName: v.PackageName, + EntryPoint: v.EntryPoint, + Parameters: v.Parameters, + NamedParameters: v.NamedParameters, + }, nil +} + +func pythonWheelTaskFromWire(w *pythonWheelTaskWire) (*PythonWheelTask, error) { + if w == nil { + return nil, nil + } + return &PythonWheelTask{ + PackageName: w.PackageName, + EntryPoint: w.EntryPoint, + Parameters: w.Parameters, + NamedParameters: w.NamedParameters, + }, nil +} + +type queueDetailsWire struct { + Code QueueDetailsCode_Code `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +func queueDetailsFromWire(w *queueDetailsWire) (*QueueDetails, error) { + if w == nil { + return nil, nil + } + return &QueueDetails{ + Code: w.Code, + Message: w.Message, + }, nil +} + +type queueSettingsWire struct { + Enabled *bool `json:"enabled,omitempty"` +} + +func queueSettingsToWire(v *QueueSettings) (*queueSettingsWire, error) { + if v == nil { + return nil, nil + } + return &queueSettingsWire{ + Enabled: v.Enabled, + }, nil +} + +func queueSettingsFromWire(w *queueSettingsWire) (*QueueSettings, error) { + if w == nil { + return nil, nil + } + return &QueueSettings{ + Enabled: w.Enabled, + }, nil +} + +type rCranLibraryWire struct { + Package *string `json:"package,omitempty"` + Repo *string `json:"repo,omitempty"` +} + +func rCranLibraryToWire(v *RCranLibrary) (*rCranLibraryWire, error) { + if v == nil { + return nil, nil + } + return &rCranLibraryWire{ + Package: v.Package, + Repo: v.Repo, + }, nil +} + +func rCranLibraryFromWire(w *rCranLibraryWire) (*RCranLibrary, error) { + if w == nil { + return nil, nil + } + return &RCranLibrary{ + Package: w.Package, + Repo: w.Repo, + }, nil +} + +type repairWire struct { + Type RepairType `json:"type,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + EndTime *int64 `json:"end_time,omitempty"` + State *runStateWire `json:"state,omitempty"` + Id *int64 `json:"id,omitempty"` + TaskRunIds []int64 `json:"task_run_ids,omitempty"` + Status *runStatusWire `json:"status,omitempty"` + EffectivePerformanceTarget PerformanceTarget_PerformanceTarget `json:"effective_performance_target,omitempty"` +} + +func repairFromWire(w *repairWire) (*Repair, error) { + if w == nil { + return nil, nil + } + statePublicValue, err := runStateFromWire(w.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Repair.State", err) + } + statusPublicValue, err := runStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Repair.Status", err) + } + return &Repair{ + Type: w.Type, + StartTime: w.StartTime, + EndTime: w.EndTime, + State: statePublicValue, + Id: w.Id, + TaskRunIds: w.TaskRunIds, + Status: statusPublicValue, + EffectivePerformanceTarget: w.EffectivePerformanceTarget, + }, nil +} + +type repairRunRequestWire struct { + RunId *int64 `json:"run_id,omitempty"` + LatestRepairId *int64 `json:"latest_repair_id,omitempty"` + RerunTasks []string `json:"rerun_tasks,omitempty"` + JobParameters map[string]string `json:"job_parameters,omitempty"` + RerunAllFailedTasks *bool `json:"rerun_all_failed_tasks,omitempty"` + RerunDependentTasks *bool `json:"rerun_dependent_tasks,omitempty"` + PerformanceTarget PerformanceTarget_PerformanceTarget `json:"performance_target,omitempty"` + PipelineParams *pipelineParametersWire `json:"pipeline_params,omitempty"` + JarParams []string `json:"jar_params,omitempty"` + NotebookParams map[string]string `json:"notebook_params,omitempty"` + PythonParams []string `json:"python_params,omitempty"` + SparkSubmitParams []string `json:"spark_submit_params,omitempty"` + PythonNamedParams map[string]string `json:"python_named_params,omitempty"` + SqlParams map[string]string `json:"sql_params,omitempty"` + DbtCommands []string `json:"dbt_commands,omitempty"` +} + +func repairRunRequestToWire(v *RepairRunRequest) (*repairRunRequestWire, error) { + if v == nil { + return nil, nil + } + pipelineParamsWireValue, err := pipelineParametersToWire(v.PipelineParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RepairRunRequest.PipelineParams", err) + } + return &repairRunRequestWire{ + RunId: v.RunId, + LatestRepairId: v.LatestRepairId, + RerunTasks: v.RerunTasks, + JobParameters: v.JobParameters, + RerunAllFailedTasks: v.RerunAllFailedTasks, + RerunDependentTasks: v.RerunDependentTasks, + PerformanceTarget: v.PerformanceTarget, + PipelineParams: pipelineParamsWireValue, + JarParams: v.JarParams, + NotebookParams: v.NotebookParams, + PythonParams: v.PythonParams, + SparkSubmitParams: v.SparkSubmitParams, + PythonNamedParams: v.PythonNamedParams, + SqlParams: v.SqlParams, + DbtCommands: v.DbtCommands, + }, nil +} + +type repairRunResponseWire struct { + RepairId *int64 `json:"repair_id,omitempty"` +} + +func repairRunResponseFromWire(w *repairRunResponseWire) (*RepairRunResponse, error) { + if w == nil { + return nil, nil + } + return &RepairRunResponse{ + RepairId: w.RepairId, + }, nil +} + +type resetJobRequestWire struct { + JobId *int64 `json:"job_id,omitempty"` + NewSettings *jobSettingsWire `json:"new_settings,omitempty"` +} + +func resetJobRequestToWire(v *ResetJobRequest) (*resetJobRequestWire, error) { + if v == nil { + return nil, nil + } + newSettingsWireValue, err := jobSettingsToWire(v.NewSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResetJobRequest.NewSettings", err) + } + return &resetJobRequestWire{ + JobId: v.JobId, + NewSettings: newSettingsWireValue, + }, nil +} + +type resolvedValuesWire struct { + NotebookTask *resolvedValues_NotebookTaskResolvedValuesWire `json:"notebook_task,omitempty"` + SparkJarTask *resolvedValues_SparkJarTaskResolvedValuesWire `json:"spark_jar_task,omitempty"` + SparkPythonTask *resolvedValues_SparkPythonTaskResolvedValuesWire `json:"spark_python_task,omitempty"` + SparkSubmitTask *resolvedValues_SparkSubmitTaskResolvedValuesWire `json:"spark_submit_task,omitempty"` + PythonWheelTask *resolvedValues_PythonWheelTaskResolvedValuesWire `json:"python_wheel_task,omitempty"` + DbtTask *resolvedValues_DbtTaskResolvedValuesWire `json:"dbt_task,omitempty"` + SqlTask *resolvedValues_SqlTaskResolvedValuesWire `json:"sql_task,omitempty"` + RunJobTask *resolvedValues_RunJobTaskResolvedValuesWire `json:"run_job_task,omitempty"` + ConditionTask *resolvedValues_ConditionTaskResolvedValuesWire `json:"condition_task,omitempty"` + SimulationTask *resolvedValues_SimulationTaskResolvedValuesWire `json:"simulation_task,omitempty"` + PipelineTask *resolvedValues_PipelineTaskResolvedValuesWire `json:"pipeline_task,omitempty"` + AiRuntimeTask *resolvedValues_AiRuntimeTaskResolvedValuesWire `json:"ai_runtime_task,omitempty"` +} + +func resolvedValuesFromWire(w *resolvedValuesWire) (*ResolvedValues, error) { + if w == nil { + return nil, nil + } + resolvedMembers := 0 + if w.NotebookTask != nil { + resolvedMembers++ + } + if w.SparkJarTask != nil { + resolvedMembers++ + } + if w.SparkPythonTask != nil { + resolvedMembers++ + } + if w.SparkSubmitTask != nil { + resolvedMembers++ + } + if w.PythonWheelTask != nil { + resolvedMembers++ + } + if w.DbtTask != nil { + resolvedMembers++ + } + if w.SqlTask != nil { + resolvedMembers++ + } + if w.RunJobTask != nil { + resolvedMembers++ + } + if w.ConditionTask != nil { + resolvedMembers++ + } + if w.SimulationTask != nil { + resolvedMembers++ + } + if w.PipelineTask != nil { + resolvedMembers++ + } + if w.AiRuntimeTask != nil { + resolvedMembers++ + } + if resolvedMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ResolvedValues.Resolved") + } + var resolvedSelection isResolvedValues_Resolved + switch { + case w.NotebookTask != nil: + resolvedNotebookTaskConverted, err := resolvedValues_NotebookTaskResolvedValuesFromWire(w.NotebookTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.NotebookTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_NotebookTask{NotebookTask: *resolvedNotebookTaskConverted} + case w.SparkJarTask != nil: + resolvedSparkJarTaskConverted, err := resolvedValues_SparkJarTaskResolvedValuesFromWire(w.SparkJarTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.SparkJarTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_SparkJarTask{SparkJarTask: *resolvedSparkJarTaskConverted} + case w.SparkPythonTask != nil: + resolvedSparkPythonTaskConverted, err := resolvedValues_SparkPythonTaskResolvedValuesFromWire(w.SparkPythonTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.SparkPythonTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_SparkPythonTask{SparkPythonTask: *resolvedSparkPythonTaskConverted} + case w.SparkSubmitTask != nil: + resolvedSparkSubmitTaskConverted, err := resolvedValues_SparkSubmitTaskResolvedValuesFromWire(w.SparkSubmitTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.SparkSubmitTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_SparkSubmitTask{SparkSubmitTask: *resolvedSparkSubmitTaskConverted} + case w.PythonWheelTask != nil: + resolvedPythonWheelTaskConverted, err := resolvedValues_PythonWheelTaskResolvedValuesFromWire(w.PythonWheelTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.PythonWheelTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_PythonWheelTask{PythonWheelTask: *resolvedPythonWheelTaskConverted} + case w.DbtTask != nil: + resolvedDbtTaskConverted, err := resolvedValues_DbtTaskResolvedValuesFromWire(w.DbtTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.DbtTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_DbtTask{DbtTask: *resolvedDbtTaskConverted} + case w.SqlTask != nil: + resolvedSqlTaskConverted, err := resolvedValues_SqlTaskResolvedValuesFromWire(w.SqlTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.SqlTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_SqlTask{SqlTask: *resolvedSqlTaskConverted} + case w.RunJobTask != nil: + resolvedRunJobTaskConverted, err := resolvedValues_RunJobTaskResolvedValuesFromWire(w.RunJobTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.RunJobTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_RunJobTask{RunJobTask: *resolvedRunJobTaskConverted} + case w.ConditionTask != nil: + resolvedConditionTaskConverted, err := resolvedValues_ConditionTaskResolvedValuesFromWire(w.ConditionTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.ConditionTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_ConditionTask{ConditionTask: *resolvedConditionTaskConverted} + case w.SimulationTask != nil: + resolvedSimulationTaskConverted, err := resolvedValues_SimulationTaskResolvedValuesFromWire(w.SimulationTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.SimulationTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_SimulationTask{SimulationTask: *resolvedSimulationTaskConverted} + case w.PipelineTask != nil: + resolvedPipelineTaskConverted, err := resolvedValues_PipelineTaskResolvedValuesFromWire(w.PipelineTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.PipelineTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_PipelineTask{PipelineTask: *resolvedPipelineTaskConverted} + case w.AiRuntimeTask != nil: + resolvedAiRuntimeTaskConverted, err := resolvedValues_AiRuntimeTaskResolvedValuesFromWire(w.AiRuntimeTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResolvedValues.Resolved.AiRuntimeTask", err) + } + resolvedSelection = &ResolvedValues_Resolved_AiRuntimeTask{AiRuntimeTask: *resolvedAiRuntimeTaskConverted} + } + return &ResolvedValues{ + Resolved: resolvedSelection, + }, nil +} + +type resolvedValues_AiRuntimeTaskResolvedValuesWire struct { +} + +func resolvedValues_AiRuntimeTaskResolvedValuesFromWire(w *resolvedValues_AiRuntimeTaskResolvedValuesWire) (*ResolvedValues_AiRuntimeTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_AiRuntimeTaskResolvedValues{}, nil +} + +type resolvedValues_ConditionTaskResolvedValuesWire struct { + Left *string `json:"left,omitempty"` + Right *string `json:"right,omitempty"` +} + +func resolvedValues_ConditionTaskResolvedValuesFromWire(w *resolvedValues_ConditionTaskResolvedValuesWire) (*ResolvedValues_ConditionTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_ConditionTaskResolvedValues{ + Left: w.Left, + Right: w.Right, + }, nil +} + +type resolvedValues_DbtTaskResolvedValuesWire struct { + Commands []string `json:"commands,omitempty"` +} + +func resolvedValues_DbtTaskResolvedValuesFromWire(w *resolvedValues_DbtTaskResolvedValuesWire) (*ResolvedValues_DbtTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_DbtTaskResolvedValues{ + Commands: w.Commands, + }, nil +} + +type resolvedValues_NotebookTaskResolvedValuesWire struct { + BaseParameters map[string]string `json:"base_parameters,omitempty"` +} + +func resolvedValues_NotebookTaskResolvedValuesFromWire(w *resolvedValues_NotebookTaskResolvedValuesWire) (*ResolvedValues_NotebookTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_NotebookTaskResolvedValues{ + BaseParameters: w.BaseParameters, + }, nil +} + +type resolvedValues_PipelineTaskResolvedValuesWire struct { + PipelineTaskParameters map[string]string `json:"parameters,omitempty"` +} + +func resolvedValues_PipelineTaskResolvedValuesFromWire(w *resolvedValues_PipelineTaskResolvedValuesWire) (*ResolvedValues_PipelineTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_PipelineTaskResolvedValues{ + PipelineTaskParameters: w.PipelineTaskParameters, + }, nil +} + +type resolvedValues_PythonWheelTaskResolvedValuesWire struct { + Parameters []string `json:"parameters,omitempty"` + NamedParameters map[string]string `json:"named_parameters,omitempty"` +} + +func resolvedValues_PythonWheelTaskResolvedValuesFromWire(w *resolvedValues_PythonWheelTaskResolvedValuesWire) (*ResolvedValues_PythonWheelTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_PythonWheelTaskResolvedValues{ + Parameters: w.Parameters, + NamedParameters: w.NamedParameters, + }, nil +} + +type resolvedValues_RunJobTaskResolvedValuesWire struct { + Parameters map[string]string `json:"parameters,omitempty"` + JobParameters map[string]string `json:"job_parameters,omitempty"` +} + +func resolvedValues_RunJobTaskResolvedValuesFromWire(w *resolvedValues_RunJobTaskResolvedValuesWire) (*ResolvedValues_RunJobTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_RunJobTaskResolvedValues{ + Parameters: w.Parameters, + JobParameters: w.JobParameters, + }, nil +} + +type resolvedValues_SimulationTaskResolvedValuesWire struct { + Parameters map[string]string `json:"parameters,omitempty"` +} + +func resolvedValues_SimulationTaskResolvedValuesFromWire(w *resolvedValues_SimulationTaskResolvedValuesWire) (*ResolvedValues_SimulationTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_SimulationTaskResolvedValues{ + Parameters: w.Parameters, + }, nil +} + +type resolvedValues_SparkJarTaskResolvedValuesWire struct { + Parameters []string `json:"parameters,omitempty"` +} + +func resolvedValues_SparkJarTaskResolvedValuesFromWire(w *resolvedValues_SparkJarTaskResolvedValuesWire) (*ResolvedValues_SparkJarTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_SparkJarTaskResolvedValues{ + Parameters: w.Parameters, + }, nil +} + +type resolvedValues_SparkPythonTaskResolvedValuesWire struct { +} + +func resolvedValues_SparkPythonTaskResolvedValuesFromWire(w *resolvedValues_SparkPythonTaskResolvedValuesWire) (*ResolvedValues_SparkPythonTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_SparkPythonTaskResolvedValues{}, nil +} + +type resolvedValues_SparkSubmitTaskResolvedValuesWire struct { +} + +func resolvedValues_SparkSubmitTaskResolvedValuesFromWire(w *resolvedValues_SparkSubmitTaskResolvedValuesWire) (*ResolvedValues_SparkSubmitTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_SparkSubmitTaskResolvedValues{}, nil +} + +type resolvedValues_SqlTaskResolvedValuesWire struct { + Parameters map[string]string `json:"parameters,omitempty"` +} + +func resolvedValues_SqlTaskResolvedValuesFromWire(w *resolvedValues_SqlTaskResolvedValuesWire) (*ResolvedValues_SqlTaskResolvedValues, error) { + if w == nil { + return nil, nil + } + return &ResolvedValues_SqlTaskResolvedValues{ + Parameters: w.Parameters, + }, nil +} + +type runWire struct { + JobId *int64 `json:"job_id,omitempty"` + RunId *int64 `json:"run_id,omitempty"` + CreatorUserName *string `json:"creator_user_name,omitempty"` + NumberInJob *int64 `json:"number_in_job,omitempty"` + OriginalAttemptRunId *int64 `json:"original_attempt_run_id,omitempty"` + State *runStateWire `json:"state,omitempty"` + Schedule *cronScheduleWire `json:"schedule,omitempty"` + ClusterSpec *clusterSpecWire `json:"cluster_spec,omitempty"` + ClusterInstance *clusterInstanceWire `json:"cluster_instance,omitempty"` + JobParameters []run_JobLevelParametersWire `json:"job_parameters,omitempty"` + OverridingParameters *runParametersWire `json:"overriding_parameters,omitempty"` + Trigger TriggerType `json:"trigger,omitempty"` + TriggerInfo *runTriggerInfoWire `json:"trigger_info,omitempty"` + RunName *string `json:"run_name,omitempty"` + RunPageUrl *string `json:"run_page_url,omitempty"` + RunType RunType `json:"run_type,omitempty"` + Tasks []runTaskWire `json:"tasks,omitempty"` + Description *string `json:"description,omitempty"` + AttemptNumber *int `json:"attempt_number,omitempty"` + JobClusters []jobClusterWire `json:"job_clusters,omitempty"` + GitSource *gitSourceWire `json:"git_source,omitempty"` + RepairHistory []repairWire `json:"repair_history,omitempty"` + Status *runStatusWire `json:"status,omitempty"` + JobRunId *int64 `json:"job_run_id,omitempty"` + HasMore *bool `json:"has_more,omitempty"` + EffectivePerformanceTarget PerformanceTarget_PerformanceTarget `json:"effective_performance_target,omitempty"` + EffectiveUsagePolicyId *string `json:"effective_usage_policy_id,omitempty"` + DeploymentId *string `json:"deployment_id,omitempty"` + VersionId *string `json:"version_id,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + SetupDuration *int64 `json:"setup_duration,omitempty"` + ExecutionDuration *int64 `json:"execution_duration,omitempty"` + CleanupDuration *int64 `json:"cleanup_duration,omitempty"` + EndTime *int64 `json:"end_time,omitempty"` + RunDuration *int64 `json:"run_duration,omitempty"` + QueueDuration *int64 `json:"queue_duration,omitempty"` +} + +func runFromWire(w *runWire) (*Run, error) { + if w == nil { + return nil, nil + } + statePublicValue, err := runStateFromWire(w.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.State", err) + } + schedulePublicValue, err := cronScheduleFromWire(w.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.Schedule", err) + } + clusterSpecPublicValue, err := clusterSpecFromWire(w.ClusterSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.ClusterSpec", err) + } + clusterInstancePublicValue, err := clusterInstanceFromWire(w.ClusterInstance) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.ClusterInstance", err) + } + jobParametersPublicValue, err := convertSlice(w.JobParameters, run_JobLevelParametersFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.JobParameters", err) + } + overridingParametersPublicValue, err := runParametersFromWire(w.OverridingParameters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.OverridingParameters", err) + } + triggerInfoPublicValue, err := runTriggerInfoFromWire(w.TriggerInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.TriggerInfo", err) + } + tasksPublicValue, err := convertSlice(w.Tasks, runTaskFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.Tasks", err) + } + jobClustersPublicValue, err := convertSlice(w.JobClusters, jobClusterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.JobClusters", err) + } + gitSourcePublicValue, err := gitSourceFromWire(w.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.GitSource", err) + } + repairHistoryPublicValue, err := convertSlice(w.RepairHistory, repairFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.RepairHistory", err) + } + statusPublicValue, err := runStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Run.Status", err) + } + return &Run{ + JobId: w.JobId, + RunId: w.RunId, + CreatorUserName: w.CreatorUserName, + NumberInJob: w.NumberInJob, + OriginalAttemptRunId: w.OriginalAttemptRunId, + State: statePublicValue, + Schedule: schedulePublicValue, + ClusterSpec: clusterSpecPublicValue, + ClusterInstance: clusterInstancePublicValue, + JobParameters: jobParametersPublicValue, + OverridingParameters: overridingParametersPublicValue, + Trigger: w.Trigger, + TriggerInfo: triggerInfoPublicValue, + RunName: w.RunName, + RunPageUrl: w.RunPageUrl, + RunType: w.RunType, + Tasks: tasksPublicValue, + Description: w.Description, + AttemptNumber: w.AttemptNumber, + JobClusters: jobClustersPublicValue, + GitSource: gitSourcePublicValue, + RepairHistory: repairHistoryPublicValue, + Status: statusPublicValue, + JobRunId: w.JobRunId, + HasMore: w.HasMore, + EffectivePerformanceTarget: w.EffectivePerformanceTarget, + EffectiveUsagePolicyId: w.EffectiveUsagePolicyId, + DeploymentId: w.DeploymentId, + VersionId: w.VersionId, + StartTime: w.StartTime, + SetupDuration: w.SetupDuration, + ExecutionDuration: w.ExecutionDuration, + CleanupDuration: w.CleanupDuration, + EndTime: w.EndTime, + RunDuration: w.RunDuration, + QueueDuration: w.QueueDuration, + }, nil +} + +type run_JobLevelParametersWire struct { + Name *string `json:"name,omitempty"` + Default *string `json:"default,omitempty"` + Value *string `json:"value,omitempty"` +} + +func run_JobLevelParametersFromWire(w *run_JobLevelParametersWire) (*Run_JobLevelParameters, error) { + if w == nil { + return nil, nil + } + return &Run_JobLevelParameters{ + Name: w.Name, + Default: w.Default, + Value: w.Value, + }, nil +} + +type runJobTaskWire struct { + JobId *int64 `json:"job_id,omitempty"` + JobParameters map[string]string `json:"job_parameters,omitempty"` + PipelineParams *pipelineParametersWire `json:"pipeline_params,omitempty"` + JarParams []string `json:"jar_params,omitempty"` + NotebookParams map[string]string `json:"notebook_params,omitempty"` + PythonParams []string `json:"python_params,omitempty"` + SparkSubmitParams []string `json:"spark_submit_params,omitempty"` + PythonNamedParams map[string]string `json:"python_named_params,omitempty"` + SqlParams map[string]string `json:"sql_params,omitempty"` + DbtCommands []string `json:"dbt_commands,omitempty"` +} + +func runJobTaskToWire(v *RunJobTask) (*runJobTaskWire, error) { + if v == nil { + return nil, nil + } + pipelineParamsWireValue, err := pipelineParametersToWire(v.PipelineParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunJobTask.PipelineParams", err) + } + return &runJobTaskWire{ + JobId: v.JobId, + JobParameters: v.JobParameters, + PipelineParams: pipelineParamsWireValue, + JarParams: v.JarParams, + NotebookParams: v.NotebookParams, + PythonParams: v.PythonParams, + SparkSubmitParams: v.SparkSubmitParams, + PythonNamedParams: v.PythonNamedParams, + SqlParams: v.SqlParams, + DbtCommands: v.DbtCommands, + }, nil +} + +func runJobTaskFromWire(w *runJobTaskWire) (*RunJobTask, error) { + if w == nil { + return nil, nil + } + pipelineParamsPublicValue, err := pipelineParametersFromWire(w.PipelineParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunJobTask.PipelineParams", err) + } + return &RunJobTask{ + JobId: w.JobId, + JobParameters: w.JobParameters, + PipelineParams: pipelineParamsPublicValue, + JarParams: w.JarParams, + NotebookParams: w.NotebookParams, + PythonParams: w.PythonParams, + SparkSubmitParams: w.SparkSubmitParams, + PythonNamedParams: w.PythonNamedParams, + SqlParams: w.SqlParams, + DbtCommands: w.DbtCommands, + }, nil +} + +type runJobTask_RunJobTaskOutputWire struct { + RunId *int64 `json:"run_id,omitempty"` +} + +func runJobTask_RunJobTaskOutputFromWire(w *runJobTask_RunJobTaskOutputWire) (*RunJobTask_RunJobTaskOutput, error) { + if w == nil { + return nil, nil + } + return &RunJobTask_RunJobTaskOutput{ + RunId: w.RunId, + }, nil +} + +type runNowRequestWire struct { + JobId *int64 `json:"job_id,omitempty"` + JobParameters map[string]string `json:"job_parameters,omitempty"` + IdempotencyToken *string `json:"idempotency_token,omitempty"` + Queue *queueSettingsWire `json:"queue,omitempty"` + Only []string `json:"only,omitempty"` + PerformanceTarget PerformanceTarget_PerformanceTarget `json:"performance_target,omitempty"` + PipelineParams *pipelineParametersWire `json:"pipeline_params,omitempty"` + JarParams []string `json:"jar_params,omitempty"` + NotebookParams map[string]string `json:"notebook_params,omitempty"` + PythonParams []string `json:"python_params,omitempty"` + SparkSubmitParams []string `json:"spark_submit_params,omitempty"` + PythonNamedParams map[string]string `json:"python_named_params,omitempty"` + SqlParams map[string]string `json:"sql_params,omitempty"` + DbtCommands []string `json:"dbt_commands,omitempty"` +} + +func runNowRequestToWire(v *RunNowRequest) (*runNowRequestWire, error) { + if v == nil { + return nil, nil + } + queueWireValue, err := queueSettingsToWire(v.Queue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunNowRequest.Queue", err) + } + pipelineParamsWireValue, err := pipelineParametersToWire(v.PipelineParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunNowRequest.PipelineParams", err) + } + return &runNowRequestWire{ + JobId: v.JobId, + JobParameters: v.JobParameters, + IdempotencyToken: v.IdempotencyToken, + Queue: queueWireValue, + Only: v.Only, + PerformanceTarget: v.PerformanceTarget, + PipelineParams: pipelineParamsWireValue, + JarParams: v.JarParams, + NotebookParams: v.NotebookParams, + PythonParams: v.PythonParams, + SparkSubmitParams: v.SparkSubmitParams, + PythonNamedParams: v.PythonNamedParams, + SqlParams: v.SqlParams, + DbtCommands: v.DbtCommands, + }, nil +} + +type runNowResponseWire struct { + RunId *int64 `json:"run_id,omitempty"` + NumberInJob *int64 `json:"number_in_job,omitempty"` +} + +func runNowResponseFromWire(w *runNowResponseWire) (*RunNowResponse, error) { + if w == nil { + return nil, nil + } + return &RunNowResponse{ + RunId: w.RunId, + NumberInJob: w.NumberInJob, + }, nil +} + +type runParametersWire struct { + PipelineParams *pipelineParametersWire `json:"pipeline_params,omitempty"` + JarParams []string `json:"jar_params,omitempty"` + NotebookParams map[string]string `json:"notebook_params,omitempty"` + PythonParams []string `json:"python_params,omitempty"` + SparkSubmitParams []string `json:"spark_submit_params,omitempty"` + PythonNamedParams map[string]string `json:"python_named_params,omitempty"` + SqlParams map[string]string `json:"sql_params,omitempty"` + DbtCommands []string `json:"dbt_commands,omitempty"` +} + +func runParametersFromWire(w *runParametersWire) (*RunParameters, error) { + if w == nil { + return nil, nil + } + pipelineParamsPublicValue, err := pipelineParametersFromWire(w.PipelineParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunParameters.PipelineParams", err) + } + return &RunParameters{ + PipelineParams: pipelineParamsPublicValue, + JarParams: w.JarParams, + NotebookParams: w.NotebookParams, + PythonParams: w.PythonParams, + SparkSubmitParams: w.SparkSubmitParams, + PythonNamedParams: w.PythonNamedParams, + SqlParams: w.SqlParams, + DbtCommands: w.DbtCommands, + }, nil +} + +type runStateWire struct { + LifeCycleState RunLifeCycleState_RunLifeCycleState `json:"life_cycle_state,omitempty"` + ResultState RunResultState_RunResultState `json:"result_state,omitempty"` + StateMessage *string `json:"state_message,omitempty"` + UserCancelledOrTimedout *bool `json:"user_cancelled_or_timedout,omitempty"` + QueueReason *string `json:"queue_reason,omitempty"` +} + +func runStateFromWire(w *runStateWire) (*RunState, error) { + if w == nil { + return nil, nil + } + return &RunState{ + LifeCycleState: w.LifeCycleState, + ResultState: w.ResultState, + StateMessage: w.StateMessage, + UserCancelledOrTimedout: w.UserCancelledOrTimedout, + QueueReason: w.QueueReason, + }, nil +} + +type runStatusWire struct { + State RunLifecycleStateV2_State `json:"state,omitempty"` + TerminationDetails *terminationDetailsWire `json:"termination_details,omitempty"` + QueueDetails *queueDetailsWire `json:"queue_details,omitempty"` +} + +func runStatusFromWire(w *runStatusWire) (*RunStatus, error) { + if w == nil { + return nil, nil + } + terminationDetailsPublicValue, err := terminationDetailsFromWire(w.TerminationDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunStatus.TerminationDetails", err) + } + queueDetailsPublicValue, err := queueDetailsFromWire(w.QueueDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunStatus.QueueDetails", err) + } + return &RunStatus{ + State: w.State, + TerminationDetails: terminationDetailsPublicValue, + QueueDetails: queueDetailsPublicValue, + }, nil +} + +type runTaskWire struct { + RunId *int64 `json:"run_id,omitempty"` + State *runStateWire `json:"state,omitempty"` + RunPageUrl *string `json:"run_page_url,omitempty"` + ClusterInstance *clusterInstanceWire `json:"cluster_instance,omitempty"` + AttemptNumber *int `json:"attempt_number,omitempty"` + GitSource *gitSourceWire `json:"git_source,omitempty"` + ResolvedValues *resolvedValuesWire `json:"resolved_values,omitempty"` + Status *runStatusWire `json:"status,omitempty"` + EffectivePerformanceTarget PerformanceTarget_PerformanceTarget `json:"effective_performance_target,omitempty"` + EffectiveServerlessComputeId *string `json:"effective_serverless_compute_id,omitempty"` + TaskKey *string `json:"task_key,omitempty"` + Description *string `json:"description,omitempty"` + DependsOn []taskDependencyWire `json:"depends_on,omitempty"` + RunIf TaskDependencyType `json:"run_if,omitempty"` + TimeoutSeconds *int `json:"timeout_seconds,omitempty"` + EmailNotifications *jobEmailNotificationsWire `json:"email_notifications,omitempty"` + Health *jobsHealthRulesWire `json:"health,omitempty"` + NotificationSettings *notificationSettingsWire `json:"notification_settings,omitempty"` + WebhookNotifications *webhookNotificationsWire `json:"webhook_notifications,omitempty"` + EnvironmentKey *string `json:"environment_key,omitempty"` + Disabled *bool `json:"disabled,omitempty"` + Compute *computeWire `json:"compute,omitempty"` + NotebookTask *notebookTaskWire `json:"notebook_task,omitempty"` + SparkJarTask *sparkJarTaskWire `json:"spark_jar_task,omitempty"` + SparkPythonTask *sparkPythonTaskWire `json:"spark_python_task,omitempty"` + SparkSubmitTask *sparkSubmitTaskWire `json:"spark_submit_task,omitempty"` + PipelineTask *pipelineTaskWire `json:"pipeline_task,omitempty"` + PythonWheelTask *pythonWheelTaskWire `json:"python_wheel_task,omitempty"` + DbtTask *dbtTaskWire `json:"dbt_task,omitempty"` + SqlTask *sqlTaskWire `json:"sql_task,omitempty"` + RunJobTask *runJobTaskWire `json:"run_job_task,omitempty"` + ConditionTask *conditionTaskWire `json:"condition_task,omitempty"` + ForEachTask *forEachTaskWire `json:"for_each_task,omitempty"` + CleanRoomsNotebookTask *cleanRoomsNotebookTaskWire `json:"clean_rooms_notebook_task,omitempty"` + GenAiComputeTask *genAiComputeTaskWire `json:"gen_ai_compute_task,omitempty"` + AlertTask *alertTaskWire `json:"alert_task,omitempty"` + PowerBiTask *powerBiTaskWire `json:"power_bi_task,omitempty"` + DashboardTask *dashboardTaskWire `json:"dashboard_task,omitempty"` + DbtCloudTask *dbtCloudTaskWire `json:"dbt_cloud_task,omitempty"` + DbtPlatformTask *dbtPlatformTaskWire `json:"dbt_platform_task,omitempty"` + PythonOperatorTask *pythonOperatorTaskWire `json:"python_operator_task,omitempty"` + AiRuntimeTask *aiRuntimeTaskWire `json:"ai_runtime_task,omitempty"` + ExistingClusterId *string `json:"existing_cluster_id,omitempty"` + NewCluster *clusterSpec_NewClusterWire `json:"new_cluster,omitempty"` + JobClusterKey *string `json:"job_cluster_key,omitempty"` + Libraries []libraryWire `json:"libraries,omitempty"` + MaxRetries *int `json:"max_retries,omitempty"` + MinRetryIntervalMillis *int `json:"min_retry_interval_millis,omitempty"` + RetryOnTimeout *bool `json:"retry_on_timeout,omitempty"` + DisableAutoOptimization *bool `json:"disable_auto_optimization,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + SetupDuration *int64 `json:"setup_duration,omitempty"` + ExecutionDuration *int64 `json:"execution_duration,omitempty"` + CleanupDuration *int64 `json:"cleanup_duration,omitempty"` + EndTime *int64 `json:"end_time,omitempty"` + RunDuration *int64 `json:"run_duration,omitempty"` + QueueDuration *int64 `json:"queue_duration,omitempty"` +} + +func runTaskFromWire(w *runTaskWire) (*RunTask, error) { + if w == nil { + return nil, nil + } + environmentRefMembers := 0 + if w.EnvironmentKey != nil { + environmentRefMembers++ + } + if environmentRefMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "RunTask.EnvironmentRef") + } + taskMembers := 0 + if w.NotebookTask != nil { + taskMembers++ + } + if w.SparkJarTask != nil { + taskMembers++ + } + if w.SparkPythonTask != nil { + taskMembers++ + } + if w.SparkSubmitTask != nil { + taskMembers++ + } + if w.PipelineTask != nil { + taskMembers++ + } + if w.PythonWheelTask != nil { + taskMembers++ + } + if w.DbtTask != nil { + taskMembers++ + } + if w.SqlTask != nil { + taskMembers++ + } + if w.RunJobTask != nil { + taskMembers++ + } + if w.ConditionTask != nil { + taskMembers++ + } + if w.ForEachTask != nil { + taskMembers++ + } + if w.CleanRoomsNotebookTask != nil { + taskMembers++ + } + if w.GenAiComputeTask != nil { + taskMembers++ + } + if w.AlertTask != nil { + taskMembers++ + } + if w.PowerBiTask != nil { + taskMembers++ + } + if w.DashboardTask != nil { + taskMembers++ + } + if w.DbtCloudTask != nil { + taskMembers++ + } + if w.DbtPlatformTask != nil { + taskMembers++ + } + if w.PythonOperatorTask != nil { + taskMembers++ + } + if w.AiRuntimeTask != nil { + taskMembers++ + } + if taskMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "RunTask.Task") + } + specMembers := 0 + if w.ExistingClusterId != nil { + specMembers++ + } + if w.NewCluster != nil { + specMembers++ + } + if w.JobClusterKey != nil { + specMembers++ + } + if specMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "RunTask.Spec") + } + statePublicValue, err := runStateFromWire(w.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.State", err) + } + clusterInstancePublicValue, err := clusterInstanceFromWire(w.ClusterInstance) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.ClusterInstance", err) + } + gitSourcePublicValue, err := gitSourceFromWire(w.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.GitSource", err) + } + resolvedValuesPublicValue, err := resolvedValuesFromWire(w.ResolvedValues) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.ResolvedValues", err) + } + statusPublicValue, err := runStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Status", err) + } + dependsOnPublicValue, err := convertSlice(w.DependsOn, taskDependencyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.DependsOn", err) + } + emailNotificationsPublicValue, err := jobEmailNotificationsFromWire(w.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.EmailNotifications", err) + } + healthPublicValue, err := jobsHealthRulesFromWire(w.Health) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Health", err) + } + notificationSettingsPublicValue, err := notificationSettingsFromWire(w.NotificationSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.NotificationSettings", err) + } + webhookNotificationsPublicValue, err := webhookNotificationsFromWire(w.WebhookNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.WebhookNotifications", err) + } + computePublicValue, err := computeFromWire(w.Compute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Compute", err) + } + librariesPublicValue, err := convertSlice(w.Libraries, libraryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Libraries", err) + } + var environmentRefSelection isRunTask_EnvironmentRef + switch { + case w.EnvironmentKey != nil: + environmentRefSelection = &RunTask_EnvironmentRef_EnvironmentKey{EnvironmentKey: *w.EnvironmentKey} + } + var taskSelection isRunTask_Task + switch { + case w.NotebookTask != nil: + taskNotebookTaskConverted, err := notebookTaskFromWire(w.NotebookTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.NotebookTask", err) + } + taskSelection = &RunTask_Task_NotebookTask{NotebookTask: *taskNotebookTaskConverted} + case w.SparkJarTask != nil: + taskSparkJarTaskConverted, err := sparkJarTaskFromWire(w.SparkJarTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.SparkJarTask", err) + } + taskSelection = &RunTask_Task_SparkJarTask{SparkJarTask: *taskSparkJarTaskConverted} + case w.SparkPythonTask != nil: + taskSparkPythonTaskConverted, err := sparkPythonTaskFromWire(w.SparkPythonTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.SparkPythonTask", err) + } + taskSelection = &RunTask_Task_SparkPythonTask{SparkPythonTask: *taskSparkPythonTaskConverted} + case w.SparkSubmitTask != nil: + taskSparkSubmitTaskConverted, err := sparkSubmitTaskFromWire(w.SparkSubmitTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.SparkSubmitTask", err) + } + taskSelection = &RunTask_Task_SparkSubmitTask{SparkSubmitTask: *taskSparkSubmitTaskConverted} + case w.PipelineTask != nil: + taskPipelineTaskConverted, err := pipelineTaskFromWire(w.PipelineTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.PipelineTask", err) + } + taskSelection = &RunTask_Task_PipelineTask{PipelineTask: *taskPipelineTaskConverted} + case w.PythonWheelTask != nil: + taskPythonWheelTaskConverted, err := pythonWheelTaskFromWire(w.PythonWheelTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.PythonWheelTask", err) + } + taskSelection = &RunTask_Task_PythonWheelTask{PythonWheelTask: *taskPythonWheelTaskConverted} + case w.DbtTask != nil: + taskDbtTaskConverted, err := dbtTaskFromWire(w.DbtTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.DbtTask", err) + } + taskSelection = &RunTask_Task_DbtTask{DbtTask: *taskDbtTaskConverted} + case w.SqlTask != nil: + taskSqlTaskConverted, err := sqlTaskFromWire(w.SqlTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.SqlTask", err) + } + taskSelection = &RunTask_Task_SqlTask{SqlTask: *taskSqlTaskConverted} + case w.RunJobTask != nil: + taskRunJobTaskConverted, err := runJobTaskFromWire(w.RunJobTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.RunJobTask", err) + } + taskSelection = &RunTask_Task_RunJobTask{RunJobTask: *taskRunJobTaskConverted} + case w.ConditionTask != nil: + taskConditionTaskConverted, err := conditionTaskFromWire(w.ConditionTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.ConditionTask", err) + } + taskSelection = &RunTask_Task_ConditionTask{ConditionTask: *taskConditionTaskConverted} + case w.ForEachTask != nil: + taskForEachTaskConverted, err := forEachTaskFromWire(w.ForEachTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.ForEachTask", err) + } + taskSelection = &RunTask_Task_ForEachTask{ForEachTask: *taskForEachTaskConverted} + case w.CleanRoomsNotebookTask != nil: + taskCleanRoomsNotebookTaskConverted, err := cleanRoomsNotebookTaskFromWire(w.CleanRoomsNotebookTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.CleanRoomsNotebookTask", err) + } + taskSelection = &RunTask_Task_CleanRoomsNotebookTask{CleanRoomsNotebookTask: *taskCleanRoomsNotebookTaskConverted} + case w.GenAiComputeTask != nil: + taskGenAiComputeTaskConverted, err := genAiComputeTaskFromWire(w.GenAiComputeTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.GenAiComputeTask", err) + } + taskSelection = &RunTask_Task_GenAiComputeTask{GenAiComputeTask: *taskGenAiComputeTaskConverted} + case w.AlertTask != nil: + taskAlertTaskConverted, err := alertTaskFromWire(w.AlertTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.AlertTask", err) + } + taskSelection = &RunTask_Task_AlertTask{AlertTask: *taskAlertTaskConverted} + case w.PowerBiTask != nil: + taskPowerBiTaskConverted, err := powerBiTaskFromWire(w.PowerBiTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.PowerBiTask", err) + } + taskSelection = &RunTask_Task_PowerBiTask{PowerBiTask: *taskPowerBiTaskConverted} + case w.DashboardTask != nil: + taskDashboardTaskConverted, err := dashboardTaskFromWire(w.DashboardTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.DashboardTask", err) + } + taskSelection = &RunTask_Task_DashboardTask{DashboardTask: *taskDashboardTaskConverted} + case w.DbtCloudTask != nil: + taskDbtCloudTaskConverted, err := dbtCloudTaskFromWire(w.DbtCloudTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.DbtCloudTask", err) + } + taskSelection = &RunTask_Task_DbtCloudTask{DbtCloudTask: *taskDbtCloudTaskConverted} + case w.DbtPlatformTask != nil: + taskDbtPlatformTaskConverted, err := dbtPlatformTaskFromWire(w.DbtPlatformTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.DbtPlatformTask", err) + } + taskSelection = &RunTask_Task_DbtPlatformTask{DbtPlatformTask: *taskDbtPlatformTaskConverted} + case w.PythonOperatorTask != nil: + taskPythonOperatorTaskConverted, err := pythonOperatorTaskFromWire(w.PythonOperatorTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.PythonOperatorTask", err) + } + taskSelection = &RunTask_Task_PythonOperatorTask{PythonOperatorTask: *taskPythonOperatorTaskConverted} + case w.AiRuntimeTask != nil: + taskAiRuntimeTaskConverted, err := aiRuntimeTaskFromWire(w.AiRuntimeTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Task.AiRuntimeTask", err) + } + taskSelection = &RunTask_Task_AiRuntimeTask{AiRuntimeTask: *taskAiRuntimeTaskConverted} + } + var specSelection isRunTask_Spec + switch { + case w.ExistingClusterId != nil: + specSelection = &RunTask_Spec_ExistingClusterId{ExistingClusterId: *w.ExistingClusterId} + case w.NewCluster != nil: + specNewClusterConverted, err := clusterSpec_NewClusterFromWire(w.NewCluster) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTask.Spec.NewCluster", err) + } + specSelection = &RunTask_Spec_NewCluster{NewCluster: *specNewClusterConverted} + case w.JobClusterKey != nil: + specSelection = &RunTask_Spec_JobClusterKey{JobClusterKey: *w.JobClusterKey} + } + return &RunTask{ + RunId: w.RunId, + State: statePublicValue, + RunPageUrl: w.RunPageUrl, + ClusterInstance: clusterInstancePublicValue, + AttemptNumber: w.AttemptNumber, + GitSource: gitSourcePublicValue, + ResolvedValues: resolvedValuesPublicValue, + Status: statusPublicValue, + EffectivePerformanceTarget: w.EffectivePerformanceTarget, + EffectiveServerlessComputeId: w.EffectiveServerlessComputeId, + TaskKey: w.TaskKey, + Description: w.Description, + DependsOn: dependsOnPublicValue, + RunIf: w.RunIf, + TimeoutSeconds: w.TimeoutSeconds, + EmailNotifications: emailNotificationsPublicValue, + Health: healthPublicValue, + NotificationSettings: notificationSettingsPublicValue, + WebhookNotifications: webhookNotificationsPublicValue, + Disabled: w.Disabled, + Compute: computePublicValue, + Libraries: librariesPublicValue, + MaxRetries: w.MaxRetries, + MinRetryIntervalMillis: w.MinRetryIntervalMillis, + RetryOnTimeout: w.RetryOnTimeout, + DisableAutoOptimization: w.DisableAutoOptimization, + StartTime: w.StartTime, + SetupDuration: w.SetupDuration, + ExecutionDuration: w.ExecutionDuration, + CleanupDuration: w.CleanupDuration, + EndTime: w.EndTime, + RunDuration: w.RunDuration, + QueueDuration: w.QueueDuration, + EnvironmentRef: environmentRefSelection, + Task: taskSelection, + Spec: specSelection, + }, nil +} + +type runTaskSettingsWire struct { + TaskKey *string `json:"task_key,omitempty"` + Description *string `json:"description,omitempty"` + DependsOn []taskDependencyWire `json:"depends_on,omitempty"` + RunIf TaskDependencyType `json:"run_if,omitempty"` + TimeoutSeconds *int `json:"timeout_seconds,omitempty"` + EmailNotifications *jobEmailNotificationsWire `json:"email_notifications,omitempty"` + Health *jobsHealthRulesWire `json:"health,omitempty"` + NotificationSettings *notificationSettingsWire `json:"notification_settings,omitempty"` + WebhookNotifications *webhookNotificationsWire `json:"webhook_notifications,omitempty"` + EnvironmentKey *string `json:"environment_key,omitempty"` + Disabled *bool `json:"disabled,omitempty"` + Compute *computeWire `json:"compute,omitempty"` + NotebookTask *notebookTaskWire `json:"notebook_task,omitempty"` + SparkJarTask *sparkJarTaskWire `json:"spark_jar_task,omitempty"` + SparkPythonTask *sparkPythonTaskWire `json:"spark_python_task,omitempty"` + SparkSubmitTask *sparkSubmitTaskWire `json:"spark_submit_task,omitempty"` + PipelineTask *pipelineTaskWire `json:"pipeline_task,omitempty"` + PythonWheelTask *pythonWheelTaskWire `json:"python_wheel_task,omitempty"` + DbtTask *dbtTaskWire `json:"dbt_task,omitempty"` + SqlTask *sqlTaskWire `json:"sql_task,omitempty"` + RunJobTask *runJobTaskWire `json:"run_job_task,omitempty"` + ConditionTask *conditionTaskWire `json:"condition_task,omitempty"` + ForEachTask *forEachTaskWire `json:"for_each_task,omitempty"` + CleanRoomsNotebookTask *cleanRoomsNotebookTaskWire `json:"clean_rooms_notebook_task,omitempty"` + GenAiComputeTask *genAiComputeTaskWire `json:"gen_ai_compute_task,omitempty"` + AlertTask *alertTaskWire `json:"alert_task,omitempty"` + PowerBiTask *powerBiTaskWire `json:"power_bi_task,omitempty"` + DashboardTask *dashboardTaskWire `json:"dashboard_task,omitempty"` + DbtCloudTask *dbtCloudTaskWire `json:"dbt_cloud_task,omitempty"` + DbtPlatformTask *dbtPlatformTaskWire `json:"dbt_platform_task,omitempty"` + PythonOperatorTask *pythonOperatorTaskWire `json:"python_operator_task,omitempty"` + AiRuntimeTask *aiRuntimeTaskWire `json:"ai_runtime_task,omitempty"` + ExistingClusterId *string `json:"existing_cluster_id,omitempty"` + NewCluster *clusterSpec_NewClusterWire `json:"new_cluster,omitempty"` + JobClusterKey *string `json:"job_cluster_key,omitempty"` + Libraries []libraryWire `json:"libraries,omitempty"` + MaxRetries *int `json:"max_retries,omitempty"` + MinRetryIntervalMillis *int `json:"min_retry_interval_millis,omitempty"` + RetryOnTimeout *bool `json:"retry_on_timeout,omitempty"` + DisableAutoOptimization *bool `json:"disable_auto_optimization,omitempty"` +} + +func runTaskSettingsToWire(v *RunTaskSettings) (*runTaskSettingsWire, error) { + if v == nil { + return nil, nil + } + dependsOnWireValue, err := convertSlice(v.DependsOn, taskDependencyToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.DependsOn", err) + } + emailNotificationsWireValue, err := jobEmailNotificationsToWire(v.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.EmailNotifications", err) + } + healthWireValue, err := jobsHealthRulesToWire(v.Health) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Health", err) + } + notificationSettingsWireValue, err := notificationSettingsToWire(v.NotificationSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.NotificationSettings", err) + } + webhookNotificationsWireValue, err := webhookNotificationsToWire(v.WebhookNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.WebhookNotifications", err) + } + computeWireValue, err := computeToWire(v.Compute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Compute", err) + } + librariesWireValue, err := convertSlice(v.Libraries, libraryToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Libraries", err) + } + var environmentRefEnvironmentKeyWire *string + switch value := v.EnvironmentRef.(type) { + case nil: + case *RunTaskSettings_EnvironmentRef_EnvironmentKey: + if value != nil { + environmentRefEnvironmentKeyWire = new(value.EnvironmentKey) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "RunTaskSettings.EnvironmentRef", value) + } + var taskNotebookTaskWire *notebookTaskWire + var taskSparkJarTaskWire *sparkJarTaskWire + var taskSparkPythonTaskWire *sparkPythonTaskWire + var taskSparkSubmitTaskWire *sparkSubmitTaskWire + var taskPipelineTaskWire *pipelineTaskWire + var taskPythonWheelTaskWire *pythonWheelTaskWire + var taskDbtTaskWire *dbtTaskWire + var taskSqlTaskWire *sqlTaskWire + var taskRunJobTaskWire *runJobTaskWire + var taskConditionTaskWire *conditionTaskWire + var taskForEachTaskWire *forEachTaskWire + var taskCleanRoomsNotebookTaskWire *cleanRoomsNotebookTaskWire + var taskGenAiComputeTaskWire *genAiComputeTaskWire + var taskAlertTaskWire *alertTaskWire + var taskPowerBiTaskWire *powerBiTaskWire + var taskDashboardTaskWire *dashboardTaskWire + var taskDbtCloudTaskWire *dbtCloudTaskWire + var taskDbtPlatformTaskWire *dbtPlatformTaskWire + var taskPythonOperatorTaskWire *pythonOperatorTaskWire + var taskAiRuntimeTaskWire *aiRuntimeTaskWire + switch value := v.Task.(type) { + case nil: + case *RunTaskSettings_Task_NotebookTask: + if value != nil { + taskNotebookTaskConverted, err := notebookTaskToWire(&value.NotebookTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.NotebookTask", err) + } + taskNotebookTaskWire = taskNotebookTaskConverted + } + case *RunTaskSettings_Task_SparkJarTask: + if value != nil { + taskSparkJarTaskConverted, err := sparkJarTaskToWire(&value.SparkJarTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.SparkJarTask", err) + } + taskSparkJarTaskWire = taskSparkJarTaskConverted + } + case *RunTaskSettings_Task_SparkPythonTask: + if value != nil { + taskSparkPythonTaskConverted, err := sparkPythonTaskToWire(&value.SparkPythonTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.SparkPythonTask", err) + } + taskSparkPythonTaskWire = taskSparkPythonTaskConverted + } + case *RunTaskSettings_Task_SparkSubmitTask: + if value != nil { + taskSparkSubmitTaskConverted, err := sparkSubmitTaskToWire(&value.SparkSubmitTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.SparkSubmitTask", err) + } + taskSparkSubmitTaskWire = taskSparkSubmitTaskConverted + } + case *RunTaskSettings_Task_PipelineTask: + if value != nil { + taskPipelineTaskConverted, err := pipelineTaskToWire(&value.PipelineTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.PipelineTask", err) + } + taskPipelineTaskWire = taskPipelineTaskConverted + } + case *RunTaskSettings_Task_PythonWheelTask: + if value != nil { + taskPythonWheelTaskConverted, err := pythonWheelTaskToWire(&value.PythonWheelTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.PythonWheelTask", err) + } + taskPythonWheelTaskWire = taskPythonWheelTaskConverted + } + case *RunTaskSettings_Task_DbtTask: + if value != nil { + taskDbtTaskConverted, err := dbtTaskToWire(&value.DbtTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.DbtTask", err) + } + taskDbtTaskWire = taskDbtTaskConverted + } + case *RunTaskSettings_Task_SqlTask: + if value != nil { + taskSqlTaskConverted, err := sqlTaskToWire(&value.SqlTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.SqlTask", err) + } + taskSqlTaskWire = taskSqlTaskConverted + } + case *RunTaskSettings_Task_RunJobTask: + if value != nil { + taskRunJobTaskConverted, err := runJobTaskToWire(&value.RunJobTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.RunJobTask", err) + } + taskRunJobTaskWire = taskRunJobTaskConverted + } + case *RunTaskSettings_Task_ConditionTask: + if value != nil { + taskConditionTaskConverted, err := conditionTaskToWire(&value.ConditionTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.ConditionTask", err) + } + taskConditionTaskWire = taskConditionTaskConverted + } + case *RunTaskSettings_Task_ForEachTask: + if value != nil { + taskForEachTaskConverted, err := forEachTaskToWire(&value.ForEachTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.ForEachTask", err) + } + taskForEachTaskWire = taskForEachTaskConverted + } + case *RunTaskSettings_Task_CleanRoomsNotebookTask: + if value != nil { + taskCleanRoomsNotebookTaskConverted, err := cleanRoomsNotebookTaskToWire(&value.CleanRoomsNotebookTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.CleanRoomsNotebookTask", err) + } + taskCleanRoomsNotebookTaskWire = taskCleanRoomsNotebookTaskConverted + } + case *RunTaskSettings_Task_GenAiComputeTask: + if value != nil { + taskGenAiComputeTaskConverted, err := genAiComputeTaskToWire(&value.GenAiComputeTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.GenAiComputeTask", err) + } + taskGenAiComputeTaskWire = taskGenAiComputeTaskConverted + } + case *RunTaskSettings_Task_AlertTask: + if value != nil { + taskAlertTaskConverted, err := alertTaskToWire(&value.AlertTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.AlertTask", err) + } + taskAlertTaskWire = taskAlertTaskConverted + } + case *RunTaskSettings_Task_PowerBiTask: + if value != nil { + taskPowerBiTaskConverted, err := powerBiTaskToWire(&value.PowerBiTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.PowerBiTask", err) + } + taskPowerBiTaskWire = taskPowerBiTaskConverted + } + case *RunTaskSettings_Task_DashboardTask: + if value != nil { + taskDashboardTaskConverted, err := dashboardTaskToWire(&value.DashboardTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.DashboardTask", err) + } + taskDashboardTaskWire = taskDashboardTaskConverted + } + case *RunTaskSettings_Task_DbtCloudTask: + if value != nil { + taskDbtCloudTaskConverted, err := dbtCloudTaskToWire(&value.DbtCloudTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.DbtCloudTask", err) + } + taskDbtCloudTaskWire = taskDbtCloudTaskConverted + } + case *RunTaskSettings_Task_DbtPlatformTask: + if value != nil { + taskDbtPlatformTaskConverted, err := dbtPlatformTaskToWire(&value.DbtPlatformTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.DbtPlatformTask", err) + } + taskDbtPlatformTaskWire = taskDbtPlatformTaskConverted + } + case *RunTaskSettings_Task_PythonOperatorTask: + if value != nil { + taskPythonOperatorTaskConverted, err := pythonOperatorTaskToWire(&value.PythonOperatorTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.PythonOperatorTask", err) + } + taskPythonOperatorTaskWire = taskPythonOperatorTaskConverted + } + case *RunTaskSettings_Task_AiRuntimeTask: + if value != nil { + taskAiRuntimeTaskConverted, err := aiRuntimeTaskToWire(&value.AiRuntimeTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Task.AiRuntimeTask", err) + } + taskAiRuntimeTaskWire = taskAiRuntimeTaskConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "RunTaskSettings.Task", value) + } + var specExistingClusterIdWire *string + var specNewClusterWire *clusterSpec_NewClusterWire + var specJobClusterKeyWire *string + switch value := v.Spec.(type) { + case nil: + case *RunTaskSettings_Spec_ExistingClusterId: + if value != nil { + specExistingClusterIdWire = new(value.ExistingClusterId) + } + case *RunTaskSettings_Spec_NewCluster: + if value != nil { + specNewClusterConverted, err := clusterSpec_NewClusterToWire(&value.NewCluster) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTaskSettings.Spec.NewCluster", err) + } + specNewClusterWire = specNewClusterConverted + } + case *RunTaskSettings_Spec_JobClusterKey: + if value != nil { + specJobClusterKeyWire = new(value.JobClusterKey) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "RunTaskSettings.Spec", value) + } + return &runTaskSettingsWire{ + TaskKey: v.TaskKey, + Description: v.Description, + DependsOn: dependsOnWireValue, + RunIf: v.RunIf, + TimeoutSeconds: v.TimeoutSeconds, + EmailNotifications: emailNotificationsWireValue, + Health: healthWireValue, + NotificationSettings: notificationSettingsWireValue, + WebhookNotifications: webhookNotificationsWireValue, + EnvironmentKey: environmentRefEnvironmentKeyWire, + Disabled: v.Disabled, + Compute: computeWireValue, + NotebookTask: taskNotebookTaskWire, + SparkJarTask: taskSparkJarTaskWire, + SparkPythonTask: taskSparkPythonTaskWire, + SparkSubmitTask: taskSparkSubmitTaskWire, + PipelineTask: taskPipelineTaskWire, + PythonWheelTask: taskPythonWheelTaskWire, + DbtTask: taskDbtTaskWire, + SqlTask: taskSqlTaskWire, + RunJobTask: taskRunJobTaskWire, + ConditionTask: taskConditionTaskWire, + ForEachTask: taskForEachTaskWire, + CleanRoomsNotebookTask: taskCleanRoomsNotebookTaskWire, + GenAiComputeTask: taskGenAiComputeTaskWire, + AlertTask: taskAlertTaskWire, + PowerBiTask: taskPowerBiTaskWire, + DashboardTask: taskDashboardTaskWire, + DbtCloudTask: taskDbtCloudTaskWire, + DbtPlatformTask: taskDbtPlatformTaskWire, + PythonOperatorTask: taskPythonOperatorTaskWire, + AiRuntimeTask: taskAiRuntimeTaskWire, + ExistingClusterId: specExistingClusterIdWire, + NewCluster: specNewClusterWire, + JobClusterKey: specJobClusterKeyWire, + Libraries: librariesWireValue, + MaxRetries: v.MaxRetries, + MinRetryIntervalMillis: v.MinRetryIntervalMillis, + RetryOnTimeout: v.RetryOnTimeout, + DisableAutoOptimization: v.DisableAutoOptimization, + }, nil +} + +type runTriggerInfoWire struct { + SqlCondition *sqlConditionRunInfoDetailsWire `json:"sql_condition,omitempty"` + RunId *int64 `json:"run_id,omitempty"` +} + +func runTriggerInfoFromWire(w *runTriggerInfoWire) (*RunTriggerInfo, error) { + if w == nil { + return nil, nil + } + sqlConditionPublicValue, err := sqlConditionRunInfoDetailsFromWire(w.SqlCondition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RunTriggerInfo.SqlCondition", err) + } + return &RunTriggerInfo{ + SqlCondition: sqlConditionPublicValue, + RunId: w.RunId, + }, nil +} + +type s3StorageInfoWire struct { + Destination *string `json:"destination,omitempty"` + Region *string `json:"region,omitempty"` + Endpoint *string `json:"endpoint,omitempty"` + EnableEncryption *bool `json:"enable_encryption,omitempty"` + EncryptionType *string `json:"encryption_type,omitempty"` + KmsKey *string `json:"kms_key,omitempty"` + CannedAcl *string `json:"canned_acl,omitempty"` +} + +func s3StorageInfoToWire(v *S3StorageInfo) (*s3StorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &s3StorageInfoWire{ + Destination: v.Destination, + Region: v.Region, + Endpoint: v.Endpoint, + EnableEncryption: v.EnableEncryption, + EncryptionType: v.EncryptionType, + KmsKey: v.KmsKey, + CannedAcl: v.CannedAcl, + }, nil +} + +func s3StorageInfoFromWire(w *s3StorageInfoWire) (*S3StorageInfo, error) { + if w == nil { + return nil, nil + } + return &S3StorageInfo{ + Destination: w.Destination, + Region: w.Region, + Endpoint: w.Endpoint, + EnableEncryption: w.EnableEncryption, + EncryptionType: w.EncryptionType, + KmsKey: w.KmsKey, + CannedAcl: w.CannedAcl, + }, nil +} + +type scheduleTriggerStateWire struct { +} + +func scheduleTriggerStateFromWire(w *scheduleTriggerStateWire) (*ScheduleTriggerState, error) { + if w == nil { + return nil, nil + } + return &ScheduleTriggerState{}, nil +} + +type sparkJarTaskWire struct { + JarUri *string `json:"jar_uri,omitempty"` + MainClassName *string `json:"main_class_name,omitempty"` + Parameters []string `json:"parameters,omitempty"` + RunAsRepl *bool `json:"run_as_repl,omitempty"` +} + +func sparkJarTaskToWire(v *SparkJarTask) (*sparkJarTaskWire, error) { + if v == nil { + return nil, nil + } + return &sparkJarTaskWire{ + JarUri: v.JarUri, + MainClassName: v.MainClassName, + Parameters: v.Parameters, + RunAsRepl: v.RunAsRepl, + }, nil +} + +func sparkJarTaskFromWire(w *sparkJarTaskWire) (*SparkJarTask, error) { + if w == nil { + return nil, nil + } + return &SparkJarTask{ + JarUri: w.JarUri, + MainClassName: w.MainClassName, + Parameters: w.Parameters, + RunAsRepl: w.RunAsRepl, + }, nil +} + +type sparkPythonTaskWire struct { + PythonFile *string `json:"python_file,omitempty"` + Parameters []string `json:"parameters,omitempty"` + Source Source `json:"source,omitempty"` +} + +func sparkPythonTaskToWire(v *SparkPythonTask) (*sparkPythonTaskWire, error) { + if v == nil { + return nil, nil + } + return &sparkPythonTaskWire{ + PythonFile: v.PythonFile, + Parameters: v.Parameters, + Source: v.Source, + }, nil +} + +func sparkPythonTaskFromWire(w *sparkPythonTaskWire) (*SparkPythonTask, error) { + if w == nil { + return nil, nil + } + return &SparkPythonTask{ + PythonFile: w.PythonFile, + Parameters: w.Parameters, + Source: w.Source, + }, nil +} + +type sparkSubmitTaskWire struct { + Parameters []string `json:"parameters,omitempty"` +} + +func sparkSubmitTaskToWire(v *SparkSubmitTask) (*sparkSubmitTaskWire, error) { + if v == nil { + return nil, nil + } + return &sparkSubmitTaskWire{ + Parameters: v.Parameters, + }, nil +} + +func sparkSubmitTaskFromWire(w *sparkSubmitTaskWire) (*SparkSubmitTask, error) { + if w == nil { + return nil, nil + } + return &SparkSubmitTask{ + Parameters: w.Parameters, + }, nil +} + +type sparseCheckoutWire struct { + Patterns []string `json:"patterns,omitempty"` +} + +func sparseCheckoutToWire(v *SparseCheckout) (*sparseCheckoutWire, error) { + if v == nil { + return nil, nil + } + return &sparseCheckoutWire{ + Patterns: v.Patterns, + }, nil +} + +func sparseCheckoutFromWire(w *sparseCheckoutWire) (*SparseCheckout, error) { + if w == nil { + return nil, nil + } + return &SparseCheckout{ + Patterns: w.Patterns, + }, nil +} + +type sqlConditionConfigurationWire struct { + SqlQueryId *string `json:"sql_query_id,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + TriggerMode SqlConditionTriggerMode `json:"trigger_mode,omitempty"` +} + +func sqlConditionConfigurationToWire(v *SqlConditionConfiguration) (*sqlConditionConfigurationWire, error) { + if v == nil { + return nil, nil + } + return &sqlConditionConfigurationWire{ + SqlQueryId: v.SqlQueryId, + WarehouseId: v.WarehouseId, + TriggerMode: v.TriggerMode, + }, nil +} + +func sqlConditionConfigurationFromWire(w *sqlConditionConfigurationWire) (*SqlConditionConfiguration, error) { + if w == nil { + return nil, nil + } + return &SqlConditionConfiguration{ + SqlQueryId: w.SqlQueryId, + WarehouseId: w.WarehouseId, + TriggerMode: w.TriggerMode, + }, nil +} + +type sqlConditionRunInfoDetailsWire struct { + ConditionEvaluationSqlStatementId *string `json:"condition_evaluation_sql_statement_id,omitempty"` + ConditionEvaluationSatisfied *bool `json:"condition_evaluation_satisfied,omitempty"` + ConditionEvaluationSqlSessionId *string `json:"condition_evaluation_sql_session_id,omitempty"` +} + +func sqlConditionRunInfoDetailsFromWire(w *sqlConditionRunInfoDetailsWire) (*SqlConditionRunInfoDetails, error) { + if w == nil { + return nil, nil + } + return &SqlConditionRunInfoDetails{ + ConditionEvaluationSqlStatementId: w.ConditionEvaluationSqlStatementId, + ConditionEvaluationSatisfied: w.ConditionEvaluationSatisfied, + ConditionEvaluationSqlSessionId: w.ConditionEvaluationSqlSessionId, + }, nil +} + +type sqlConditionStateWire struct { + LatestConditionEvaluationSqlStatementId *string `json:"latest_condition_evaluation_sql_statement_id,omitempty"` + LatestConditionEvaluationSatisfied *bool `json:"latest_condition_evaluation_satisfied,omitempty"` + LatestConditionEvaluationSqlSessionId *string `json:"latest_condition_evaluation_sql_session_id,omitempty"` +} + +func sqlConditionStateFromWire(w *sqlConditionStateWire) (*SqlConditionState, error) { + if w == nil { + return nil, nil + } + return &SqlConditionState{ + LatestConditionEvaluationSqlStatementId: w.LatestConditionEvaluationSqlStatementId, + LatestConditionEvaluationSatisfied: w.LatestConditionEvaluationSatisfied, + LatestConditionEvaluationSqlSessionId: w.LatestConditionEvaluationSqlSessionId, + }, nil +} + +type sqlTaskWire struct { + Parameters map[string]string `json:"parameters,omitempty"` + Query *sqlTaskQueryWire `json:"query,omitempty"` + Dashboard *sqlTaskDashboardWire `json:"dashboard,omitempty"` + Alert *sqlTaskAlertWire `json:"alert,omitempty"` + File *sqlTaskFileWire `json:"file,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` +} + +func sqlTaskToWire(v *SqlTask) (*sqlTaskWire, error) { + if v == nil { + return nil, nil + } + var sqlTaskTypeQueryWire *sqlTaskQueryWire + var sqlTaskTypeDashboardWire *sqlTaskDashboardWire + var sqlTaskTypeAlertWire *sqlTaskAlertWire + var sqlTaskTypeFileWire *sqlTaskFileWire + switch value := v.SqlTaskType.(type) { + case nil: + case *SqlTask_SqlTaskType_Query: + if value != nil { + sqlTaskTypeQueryConverted, err := sqlTaskQueryToWire(&value.Query) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask.SqlTaskType.Query", err) + } + sqlTaskTypeQueryWire = sqlTaskTypeQueryConverted + } + case *SqlTask_SqlTaskType_Dashboard: + if value != nil { + sqlTaskTypeDashboardConverted, err := sqlTaskDashboardToWire(&value.Dashboard) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask.SqlTaskType.Dashboard", err) + } + sqlTaskTypeDashboardWire = sqlTaskTypeDashboardConverted + } + case *SqlTask_SqlTaskType_Alert: + if value != nil { + sqlTaskTypeAlertConverted, err := sqlTaskAlertToWire(&value.Alert) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask.SqlTaskType.Alert", err) + } + sqlTaskTypeAlertWire = sqlTaskTypeAlertConverted + } + case *SqlTask_SqlTaskType_File: + if value != nil { + sqlTaskTypeFileConverted, err := sqlTaskFileToWire(&value.File) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask.SqlTaskType.File", err) + } + sqlTaskTypeFileWire = sqlTaskTypeFileConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SqlTask.SqlTaskType", value) + } + return &sqlTaskWire{ + Parameters: v.Parameters, + Query: sqlTaskTypeQueryWire, + Dashboard: sqlTaskTypeDashboardWire, + Alert: sqlTaskTypeAlertWire, + File: sqlTaskTypeFileWire, + WarehouseId: v.WarehouseId, + }, nil +} + +func sqlTaskFromWire(w *sqlTaskWire) (*SqlTask, error) { + if w == nil { + return nil, nil + } + sqlTaskTypeMembers := 0 + if w.Query != nil { + sqlTaskTypeMembers++ + } + if w.Dashboard != nil { + sqlTaskTypeMembers++ + } + if w.Alert != nil { + sqlTaskTypeMembers++ + } + if w.File != nil { + sqlTaskTypeMembers++ + } + if sqlTaskTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SqlTask.SqlTaskType") + } + var sqlTaskTypeSelection isSqlTask_SqlTaskType + switch { + case w.Query != nil: + sqlTaskTypeQueryConverted, err := sqlTaskQueryFromWire(w.Query) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask.SqlTaskType.Query", err) + } + sqlTaskTypeSelection = &SqlTask_SqlTaskType_Query{Query: *sqlTaskTypeQueryConverted} + case w.Dashboard != nil: + sqlTaskTypeDashboardConverted, err := sqlTaskDashboardFromWire(w.Dashboard) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask.SqlTaskType.Dashboard", err) + } + sqlTaskTypeSelection = &SqlTask_SqlTaskType_Dashboard{Dashboard: *sqlTaskTypeDashboardConverted} + case w.Alert != nil: + sqlTaskTypeAlertConverted, err := sqlTaskAlertFromWire(w.Alert) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask.SqlTaskType.Alert", err) + } + sqlTaskTypeSelection = &SqlTask_SqlTaskType_Alert{Alert: *sqlTaskTypeAlertConverted} + case w.File != nil: + sqlTaskTypeFileConverted, err := sqlTaskFileFromWire(w.File) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask.SqlTaskType.File", err) + } + sqlTaskTypeSelection = &SqlTask_SqlTaskType_File{File: *sqlTaskTypeFileConverted} + } + return &SqlTask{ + Parameters: w.Parameters, + WarehouseId: w.WarehouseId, + SqlTaskType: sqlTaskTypeSelection, + }, nil +} + +type sqlTask_SqlAlertOutputWire struct { + QueryText *string `json:"query_text,omitempty"` + SqlStatements []sqlTask_SqlStatementOutputWire `json:"sql_statements,omitempty"` + OutputLink *string `json:"output_link,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + AlertState SqlAlertState_SqlAlertState `json:"alert_state,omitempty"` +} + +func sqlTask_SqlAlertOutputFromWire(w *sqlTask_SqlAlertOutputWire) (*SqlTask_SqlAlertOutput, error) { + if w == nil { + return nil, nil + } + sqlStatementsPublicValue, err := convertSlice(w.SqlStatements, sqlTask_SqlStatementOutputFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask_SqlAlertOutput.SqlStatements", err) + } + return &SqlTask_SqlAlertOutput{ + QueryText: w.QueryText, + SqlStatements: sqlStatementsPublicValue, + OutputLink: w.OutputLink, + WarehouseId: w.WarehouseId, + AlertState: w.AlertState, + }, nil +} + +type sqlTask_SqlDashboardOutputWire struct { + Widgets []sqlTask_SqlDashboardWidgetOutputWire `json:"widgets,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` +} + +func sqlTask_SqlDashboardOutputFromWire(w *sqlTask_SqlDashboardOutputWire) (*SqlTask_SqlDashboardOutput, error) { + if w == nil { + return nil, nil + } + widgetsPublicValue, err := convertSlice(w.Widgets, sqlTask_SqlDashboardWidgetOutputFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask_SqlDashboardOutput.Widgets", err) + } + return &SqlTask_SqlDashboardOutput{ + Widgets: widgetsPublicValue, + WarehouseId: w.WarehouseId, + }, nil +} + +type sqlTask_SqlDashboardWidgetOutputWire struct { + WidgetId *string `json:"widget_id,omitempty"` + WidgetTitle *string `json:"widget_title,omitempty"` + OutputLink *string `json:"output_link,omitempty"` + Status SqlTask_SqlTaskQueryStatus `json:"status,omitempty"` + Error *sqlTask_SqlOutputErrorWire `json:"error,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + EndTime *int64 `json:"end_time,omitempty"` +} + +func sqlTask_SqlDashboardWidgetOutputFromWire(w *sqlTask_SqlDashboardWidgetOutputWire) (*SqlTask_SqlDashboardWidgetOutput, error) { + if w == nil { + return nil, nil + } + errorPublicValue, err := sqlTask_SqlOutputErrorFromWire(w.Error) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask_SqlDashboardWidgetOutput.Error", err) + } + return &SqlTask_SqlDashboardWidgetOutput{ + WidgetId: w.WidgetId, + WidgetTitle: w.WidgetTitle, + OutputLink: w.OutputLink, + Status: w.Status, + Error: errorPublicValue, + StartTime: w.StartTime, + EndTime: w.EndTime, + }, nil +} + +type sqlTask_SqlOutputWire struct { + QueryOutput *sqlTask_SqlQueryOutputWire `json:"query_output,omitempty"` + DashboardOutput *sqlTask_SqlDashboardOutputWire `json:"dashboard_output,omitempty"` + AlertOutput *sqlTask_SqlAlertOutputWire `json:"alert_output,omitempty"` +} + +func sqlTask_SqlOutputFromWire(w *sqlTask_SqlOutputWire) (*SqlTask_SqlOutput, error) { + if w == nil { + return nil, nil + } + sqlOutputTypeMembers := 0 + if w.QueryOutput != nil { + sqlOutputTypeMembers++ + } + if w.DashboardOutput != nil { + sqlOutputTypeMembers++ + } + if w.AlertOutput != nil { + sqlOutputTypeMembers++ + } + if sqlOutputTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SqlTask_SqlOutput.SqlOutputType") + } + var sqlOutputTypeSelection isSqlTask_SqlOutput_SqlOutputType + switch { + case w.QueryOutput != nil: + sqlOutputTypeQueryOutputConverted, err := sqlTask_SqlQueryOutputFromWire(w.QueryOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask_SqlOutput.SqlOutputType.QueryOutput", err) + } + sqlOutputTypeSelection = &SqlTask_SqlOutput_SqlOutputType_QueryOutput{QueryOutput: *sqlOutputTypeQueryOutputConverted} + case w.DashboardOutput != nil: + sqlOutputTypeDashboardOutputConverted, err := sqlTask_SqlDashboardOutputFromWire(w.DashboardOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask_SqlOutput.SqlOutputType.DashboardOutput", err) + } + sqlOutputTypeSelection = &SqlTask_SqlOutput_SqlOutputType_DashboardOutput{DashboardOutput: *sqlOutputTypeDashboardOutputConverted} + case w.AlertOutput != nil: + sqlOutputTypeAlertOutputConverted, err := sqlTask_SqlAlertOutputFromWire(w.AlertOutput) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask_SqlOutput.SqlOutputType.AlertOutput", err) + } + sqlOutputTypeSelection = &SqlTask_SqlOutput_SqlOutputType_AlertOutput{AlertOutput: *sqlOutputTypeAlertOutputConverted} + } + return &SqlTask_SqlOutput{ + SqlOutputType: sqlOutputTypeSelection, + }, nil +} + +type sqlTask_SqlOutputErrorWire struct { + Message *string `json:"message,omitempty"` +} + +func sqlTask_SqlOutputErrorFromWire(w *sqlTask_SqlOutputErrorWire) (*SqlTask_SqlOutputError, error) { + if w == nil { + return nil, nil + } + return &SqlTask_SqlOutputError{ + Message: w.Message, + }, nil +} + +type sqlTask_SqlQueryOutputWire struct { + QueryText *string `json:"query_text,omitempty"` + EndpointId *string `json:"endpoint_id,omitempty"` + SqlStatements []sqlTask_SqlStatementOutputWire `json:"sql_statements,omitempty"` + OutputLink *string `json:"output_link,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` +} + +func sqlTask_SqlQueryOutputFromWire(w *sqlTask_SqlQueryOutputWire) (*SqlTask_SqlQueryOutput, error) { + if w == nil { + return nil, nil + } + sqlStatementsPublicValue, err := convertSlice(w.SqlStatements, sqlTask_SqlStatementOutputFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTask_SqlQueryOutput.SqlStatements", err) + } + return &SqlTask_SqlQueryOutput{ + QueryText: w.QueryText, + EndpointId: w.EndpointId, + SqlStatements: sqlStatementsPublicValue, + OutputLink: w.OutputLink, + WarehouseId: w.WarehouseId, + }, nil +} + +type sqlTask_SqlStatementOutputWire struct { + LookupKey *string `json:"lookup_key,omitempty"` +} + +func sqlTask_SqlStatementOutputFromWire(w *sqlTask_SqlStatementOutputWire) (*SqlTask_SqlStatementOutput, error) { + if w == nil { + return nil, nil + } + return &SqlTask_SqlStatementOutput{ + LookupKey: w.LookupKey, + }, nil +} + +type sqlTaskAlertWire struct { + AlertId *string `json:"alert_id,omitempty"` + Subscriptions []sqlTaskSubscriptionWire `json:"subscriptions,omitempty"` + PauseSubscriptions *bool `json:"pause_subscriptions,omitempty"` +} + +func sqlTaskAlertToWire(v *SqlTaskAlert) (*sqlTaskAlertWire, error) { + if v == nil { + return nil, nil + } + subscriptionsWireValue, err := convertSlice(v.Subscriptions, sqlTaskSubscriptionToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTaskAlert.Subscriptions", err) + } + return &sqlTaskAlertWire{ + AlertId: v.AlertId, + Subscriptions: subscriptionsWireValue, + PauseSubscriptions: v.PauseSubscriptions, + }, nil +} + +func sqlTaskAlertFromWire(w *sqlTaskAlertWire) (*SqlTaskAlert, error) { + if w == nil { + return nil, nil + } + subscriptionsPublicValue, err := convertSlice(w.Subscriptions, sqlTaskSubscriptionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTaskAlert.Subscriptions", err) + } + return &SqlTaskAlert{ + AlertId: w.AlertId, + Subscriptions: subscriptionsPublicValue, + PauseSubscriptions: w.PauseSubscriptions, + }, nil +} + +type sqlTaskDashboardWire struct { + DashboardId *string `json:"dashboard_id,omitempty"` + Subscriptions []sqlTaskSubscriptionWire `json:"subscriptions,omitempty"` + CustomSubject *string `json:"custom_subject,omitempty"` + PauseSubscriptions *bool `json:"pause_subscriptions,omitempty"` +} + +func sqlTaskDashboardToWire(v *SqlTaskDashboard) (*sqlTaskDashboardWire, error) { + if v == nil { + return nil, nil + } + subscriptionsWireValue, err := convertSlice(v.Subscriptions, sqlTaskSubscriptionToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTaskDashboard.Subscriptions", err) + } + return &sqlTaskDashboardWire{ + DashboardId: v.DashboardId, + Subscriptions: subscriptionsWireValue, + CustomSubject: v.CustomSubject, + PauseSubscriptions: v.PauseSubscriptions, + }, nil +} + +func sqlTaskDashboardFromWire(w *sqlTaskDashboardWire) (*SqlTaskDashboard, error) { + if w == nil { + return nil, nil + } + subscriptionsPublicValue, err := convertSlice(w.Subscriptions, sqlTaskSubscriptionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SqlTaskDashboard.Subscriptions", err) + } + return &SqlTaskDashboard{ + DashboardId: w.DashboardId, + Subscriptions: subscriptionsPublicValue, + CustomSubject: w.CustomSubject, + PauseSubscriptions: w.PauseSubscriptions, + }, nil +} + +type sqlTaskFileWire struct { + Path *string `json:"path,omitempty"` + Source Source `json:"source,omitempty"` +} + +func sqlTaskFileToWire(v *SqlTaskFile) (*sqlTaskFileWire, error) { + if v == nil { + return nil, nil + } + return &sqlTaskFileWire{ + Path: v.Path, + Source: v.Source, + }, nil +} + +func sqlTaskFileFromWire(w *sqlTaskFileWire) (*SqlTaskFile, error) { + if w == nil { + return nil, nil + } + return &SqlTaskFile{ + Path: w.Path, + Source: w.Source, + }, nil +} + +type sqlTaskQueryWire struct { + QueryId *string `json:"query_id,omitempty"` +} + +func sqlTaskQueryToWire(v *SqlTaskQuery) (*sqlTaskQueryWire, error) { + if v == nil { + return nil, nil + } + var queryTypeQueryIdWire *string + switch value := v.QueryType.(type) { + case nil: + case *SqlTaskQuery_QueryType_QueryId: + if value != nil { + queryTypeQueryIdWire = new(value.QueryId) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SqlTaskQuery.QueryType", value) + } + return &sqlTaskQueryWire{ + QueryId: queryTypeQueryIdWire, + }, nil +} + +func sqlTaskQueryFromWire(w *sqlTaskQueryWire) (*SqlTaskQuery, error) { + if w == nil { + return nil, nil + } + queryTypeMembers := 0 + if w.QueryId != nil { + queryTypeMembers++ + } + if queryTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SqlTaskQuery.QueryType") + } + var queryTypeSelection isSqlTaskQuery_QueryType + switch { + case w.QueryId != nil: + queryTypeSelection = &SqlTaskQuery_QueryType_QueryId{QueryId: *w.QueryId} + } + return &SqlTaskQuery{ + QueryType: queryTypeSelection, + }, nil +} + +type sqlTaskSubscriptionWire struct { + UserName *string `json:"user_name,omitempty"` + DestinationId *string `json:"destination_id,omitempty"` +} + +func sqlTaskSubscriptionToWire(v *SqlTaskSubscription) (*sqlTaskSubscriptionWire, error) { + if v == nil { + return nil, nil + } + var subscriptionTypeUserNameWire *string + var subscriptionTypeDestinationIdWire *string + switch value := v.SubscriptionType.(type) { + case nil: + case *SqlTaskSubscription_SubscriptionType_UserName: + if value != nil { + subscriptionTypeUserNameWire = new(value.UserName) + } + case *SqlTaskSubscription_SubscriptionType_DestinationId: + if value != nil { + subscriptionTypeDestinationIdWire = new(value.DestinationId) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SqlTaskSubscription.SubscriptionType", value) + } + return &sqlTaskSubscriptionWire{ + UserName: subscriptionTypeUserNameWire, + DestinationId: subscriptionTypeDestinationIdWire, + }, nil +} + +func sqlTaskSubscriptionFromWire(w *sqlTaskSubscriptionWire) (*SqlTaskSubscription, error) { + if w == nil { + return nil, nil + } + subscriptionTypeMembers := 0 + if w.UserName != nil { + subscriptionTypeMembers++ + } + if w.DestinationId != nil { + subscriptionTypeMembers++ + } + if subscriptionTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SqlTaskSubscription.SubscriptionType") + } + var subscriptionTypeSelection isSqlTaskSubscription_SubscriptionType + switch { + case w.UserName != nil: + subscriptionTypeSelection = &SqlTaskSubscription_SubscriptionType_UserName{UserName: *w.UserName} + case w.DestinationId != nil: + subscriptionTypeSelection = &SqlTaskSubscription_SubscriptionType_DestinationId{DestinationId: *w.DestinationId} + } + return &SqlTaskSubscription{ + SubscriptionType: subscriptionTypeSelection, + }, nil +} + +type submitRunRequestWire struct { + AccessControlList []accessControlRequestWire `json:"access_control_list,omitempty"` + Queue *queueSettingsWire `json:"queue,omitempty"` + RunAs *jobRunAsWire `json:"run_as,omitempty"` + RunName *string `json:"run_name,omitempty"` + TimeoutSeconds *int `json:"timeout_seconds,omitempty"` + Health *jobsHealthRulesWire `json:"health,omitempty"` + IdempotencyToken *string `json:"idempotency_token,omitempty"` + Tasks []runTaskSettingsWire `json:"tasks,omitempty"` + GitSource *gitSourceWire `json:"git_source,omitempty"` + WebhookNotifications *webhookNotificationsWire `json:"webhook_notifications,omitempty"` + EmailNotifications *jobEmailNotificationsWire `json:"email_notifications,omitempty"` + NotificationSettings *notificationSettingsWire `json:"notification_settings,omitempty"` + Environments []jobEnvironmentWire `json:"environments,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + PerformanceTarget PerformanceTarget_PerformanceTarget `json:"performance_target,omitempty"` +} + +func submitRunRequestToWire(v *SubmitRunRequest) (*submitRunRequestWire, error) { + if v == nil { + return nil, nil + } + accessControlListWireValue, err := convertSlice(v.AccessControlList, accessControlRequestToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SubmitRunRequest.AccessControlList", err) + } + queueWireValue, err := queueSettingsToWire(v.Queue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SubmitRunRequest.Queue", err) + } + runAsWireValue, err := jobRunAsToWire(v.RunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SubmitRunRequest.RunAs", err) + } + healthWireValue, err := jobsHealthRulesToWire(v.Health) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SubmitRunRequest.Health", err) + } + tasksWireValue, err := convertSlice(v.Tasks, runTaskSettingsToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SubmitRunRequest.Tasks", err) + } + gitSourceWireValue, err := gitSourceToWire(v.GitSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SubmitRunRequest.GitSource", err) + } + webhookNotificationsWireValue, err := webhookNotificationsToWire(v.WebhookNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SubmitRunRequest.WebhookNotifications", err) + } + emailNotificationsWireValue, err := jobEmailNotificationsToWire(v.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SubmitRunRequest.EmailNotifications", err) + } + notificationSettingsWireValue, err := notificationSettingsToWire(v.NotificationSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SubmitRunRequest.NotificationSettings", err) + } + environmentsWireValue, err := convertSlice(v.Environments, jobEnvironmentToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SubmitRunRequest.Environments", err) + } + return &submitRunRequestWire{ + AccessControlList: accessControlListWireValue, + Queue: queueWireValue, + RunAs: runAsWireValue, + RunName: v.RunName, + TimeoutSeconds: v.TimeoutSeconds, + Health: healthWireValue, + IdempotencyToken: v.IdempotencyToken, + Tasks: tasksWireValue, + GitSource: gitSourceWireValue, + WebhookNotifications: webhookNotificationsWireValue, + EmailNotifications: emailNotificationsWireValue, + NotificationSettings: notificationSettingsWireValue, + Environments: environmentsWireValue, + BudgetPolicyId: v.BudgetPolicyId, + UsagePolicyId: v.UsagePolicyId, + PerformanceTarget: v.PerformanceTarget, + }, nil +} + +type submitRunResponseWire struct { + RunId *int64 `json:"run_id,omitempty"` +} + +func submitRunResponseFromWire(w *submitRunResponseWire) (*SubmitRunResponse, error) { + if w == nil { + return nil, nil + } + return &SubmitRunResponse{ + RunId: w.RunId, + }, nil +} + +type subscriptionWire struct { + Subscribers []subscription_SubscriberWire `json:"subscribers,omitempty"` + Paused *bool `json:"paused,omitempty"` + CustomSubject *string `json:"custom_subject,omitempty"` +} + +func subscriptionToWire(v *Subscription) (*subscriptionWire, error) { + if v == nil { + return nil, nil + } + subscribersWireValue, err := convertSlice(v.Subscribers, subscription_SubscriberToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Subscription.Subscribers", err) + } + return &subscriptionWire{ + Subscribers: subscribersWireValue, + Paused: v.Paused, + CustomSubject: v.CustomSubject, + }, nil +} + +func subscriptionFromWire(w *subscriptionWire) (*Subscription, error) { + if w == nil { + return nil, nil + } + subscribersPublicValue, err := convertSlice(w.Subscribers, subscription_SubscriberFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Subscription.Subscribers", err) + } + return &Subscription{ + Subscribers: subscribersPublicValue, + Paused: w.Paused, + CustomSubject: w.CustomSubject, + }, nil +} + +type subscription_SubscriberWire struct { + UserName *string `json:"user_name,omitempty"` + DestinationId *string `json:"destination_id,omitempty"` +} + +func subscription_SubscriberToWire(v *Subscription_Subscriber) (*subscription_SubscriberWire, error) { + if v == nil { + return nil, nil + } + var subscriptionTypeUserNameWire *string + var subscriptionTypeDestinationIdWire *string + switch value := v.SubscriptionType.(type) { + case nil: + case *Subscription_Subscriber_SubscriptionType_UserName: + if value != nil { + subscriptionTypeUserNameWire = new(value.UserName) + } + case *Subscription_Subscriber_SubscriptionType_DestinationId: + if value != nil { + subscriptionTypeDestinationIdWire = new(value.DestinationId) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Subscription_Subscriber.SubscriptionType", value) + } + return &subscription_SubscriberWire{ + UserName: subscriptionTypeUserNameWire, + DestinationId: subscriptionTypeDestinationIdWire, + }, nil +} + +func subscription_SubscriberFromWire(w *subscription_SubscriberWire) (*Subscription_Subscriber, error) { + if w == nil { + return nil, nil + } + subscriptionTypeMembers := 0 + if w.UserName != nil { + subscriptionTypeMembers++ + } + if w.DestinationId != nil { + subscriptionTypeMembers++ + } + if subscriptionTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Subscription_Subscriber.SubscriptionType") + } + var subscriptionTypeSelection isSubscription_Subscriber_SubscriptionType + switch { + case w.UserName != nil: + subscriptionTypeSelection = &Subscription_Subscriber_SubscriptionType_UserName{UserName: *w.UserName} + case w.DestinationId != nil: + subscriptionTypeSelection = &Subscription_Subscriber_SubscriptionType_DestinationId{DestinationId: *w.DestinationId} + } + return &Subscription_Subscriber{ + SubscriptionType: subscriptionTypeSelection, + }, nil +} + +type tableStateWire struct { + TableName *string `json:"table_name,omitempty"` + HasSeenUpdates *bool `json:"has_seen_updates,omitempty"` +} + +func tableStateFromWire(w *tableStateWire) (*TableState, error) { + if w == nil { + return nil, nil + } + return &TableState{ + TableName: w.TableName, + HasSeenUpdates: w.HasSeenUpdates, + }, nil +} + +type tableTriggerConfigurationWire struct { + TableNames []string `json:"table_names,omitempty"` + MinTimeBetweenTriggersSeconds *int `json:"min_time_between_triggers_seconds,omitempty"` + WaitAfterLastChangeSeconds *int `json:"wait_after_last_change_seconds,omitempty"` + Condition TableTriggerConfiguration_Condition `json:"condition,omitempty"` +} + +func tableTriggerConfigurationToWire(v *TableTriggerConfiguration) (*tableTriggerConfigurationWire, error) { + if v == nil { + return nil, nil + } + return &tableTriggerConfigurationWire{ + TableNames: v.TableNames, + MinTimeBetweenTriggersSeconds: v.MinTimeBetweenTriggersSeconds, + WaitAfterLastChangeSeconds: v.WaitAfterLastChangeSeconds, + Condition: v.Condition, + }, nil +} + +func tableTriggerConfigurationFromWire(w *tableTriggerConfigurationWire) (*TableTriggerConfiguration, error) { + if w == nil { + return nil, nil + } + return &TableTriggerConfiguration{ + TableNames: w.TableNames, + MinTimeBetweenTriggersSeconds: w.MinTimeBetweenTriggersSeconds, + WaitAfterLastChangeSeconds: w.WaitAfterLastChangeSeconds, + Condition: w.Condition, + }, nil +} + +type tableTriggerStateWire struct { + LastSeenTableStates []tableStateWire `json:"last_seen_table_states,omitempty"` + UsingScalableMonitoring *bool `json:"using_scalable_monitoring,omitempty"` +} + +func tableTriggerStateFromWire(w *tableTriggerStateWire) (*TableTriggerState, error) { + if w == nil { + return nil, nil + } + lastSeenTableStatesPublicValue, err := convertSlice(w.LastSeenTableStates, tableStateFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableTriggerState.LastSeenTableStates", err) + } + return &TableTriggerState{ + LastSeenTableStates: lastSeenTableStatesPublicValue, + UsingScalableMonitoring: w.UsingScalableMonitoring, + }, nil +} + +type taskDependencyWire struct { + TaskKey *string `json:"task_key,omitempty"` + Outcome *string `json:"outcome,omitempty"` +} + +func taskDependencyToWire(v *TaskDependency) (*taskDependencyWire, error) { + if v == nil { + return nil, nil + } + return &taskDependencyWire{ + TaskKey: v.TaskKey, + Outcome: v.Outcome, + }, nil +} + +func taskDependencyFromWire(w *taskDependencyWire) (*TaskDependency, error) { + if w == nil { + return nil, nil + } + return &TaskDependency{ + TaskKey: w.TaskKey, + Outcome: w.Outcome, + }, nil +} + +type taskSettingsWire struct { + TaskKey *string `json:"task_key,omitempty"` + DependsOn []taskDependencyWire `json:"depends_on,omitempty"` + RunIf TaskDependencyType `json:"run_if,omitempty"` + TimeoutSeconds *int `json:"timeout_seconds,omitempty"` + Health *jobsHealthRulesWire `json:"health,omitempty"` + EmailNotifications *jobEmailNotificationsWire `json:"email_notifications,omitempty"` + NotificationSettings *notificationSettingsWire `json:"notification_settings,omitempty"` + WebhookNotifications *webhookNotificationsWire `json:"webhook_notifications,omitempty"` + Description *string `json:"description,omitempty"` + EnvironmentKey *string `json:"environment_key,omitempty"` + Disabled *bool `json:"disabled,omitempty"` + Compute *computeWire `json:"compute,omitempty"` + NotebookTask *notebookTaskWire `json:"notebook_task,omitempty"` + SparkJarTask *sparkJarTaskWire `json:"spark_jar_task,omitempty"` + SparkPythonTask *sparkPythonTaskWire `json:"spark_python_task,omitempty"` + SparkSubmitTask *sparkSubmitTaskWire `json:"spark_submit_task,omitempty"` + PipelineTask *pipelineTaskWire `json:"pipeline_task,omitempty"` + PythonWheelTask *pythonWheelTaskWire `json:"python_wheel_task,omitempty"` + DbtTask *dbtTaskWire `json:"dbt_task,omitempty"` + SqlTask *sqlTaskWire `json:"sql_task,omitempty"` + RunJobTask *runJobTaskWire `json:"run_job_task,omitempty"` + ConditionTask *conditionTaskWire `json:"condition_task,omitempty"` + ForEachTask *forEachTaskWire `json:"for_each_task,omitempty"` + CleanRoomsNotebookTask *cleanRoomsNotebookTaskWire `json:"clean_rooms_notebook_task,omitempty"` + GenAiComputeTask *genAiComputeTaskWire `json:"gen_ai_compute_task,omitempty"` + AlertTask *alertTaskWire `json:"alert_task,omitempty"` + PowerBiTask *powerBiTaskWire `json:"power_bi_task,omitempty"` + DashboardTask *dashboardTaskWire `json:"dashboard_task,omitempty"` + DbtCloudTask *dbtCloudTaskWire `json:"dbt_cloud_task,omitempty"` + DbtPlatformTask *dbtPlatformTaskWire `json:"dbt_platform_task,omitempty"` + PythonOperatorTask *pythonOperatorTaskWire `json:"python_operator_task,omitempty"` + AiRuntimeTask *aiRuntimeTaskWire `json:"ai_runtime_task,omitempty"` + ExistingClusterId *string `json:"existing_cluster_id,omitempty"` + NewCluster *clusterSpec_NewClusterWire `json:"new_cluster,omitempty"` + JobClusterKey *string `json:"job_cluster_key,omitempty"` + Libraries []libraryWire `json:"libraries,omitempty"` + MaxRetries *int `json:"max_retries,omitempty"` + MinRetryIntervalMillis *int `json:"min_retry_interval_millis,omitempty"` + RetryOnTimeout *bool `json:"retry_on_timeout,omitempty"` + DisableAutoOptimization *bool `json:"disable_auto_optimization,omitempty"` +} + +func taskSettingsToWire(v *TaskSettings) (*taskSettingsWire, error) { + if v == nil { + return nil, nil + } + dependsOnWireValue, err := convertSlice(v.DependsOn, taskDependencyToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.DependsOn", err) + } + healthWireValue, err := jobsHealthRulesToWire(v.Health) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Health", err) + } + emailNotificationsWireValue, err := jobEmailNotificationsToWire(v.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.EmailNotifications", err) + } + notificationSettingsWireValue, err := notificationSettingsToWire(v.NotificationSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.NotificationSettings", err) + } + webhookNotificationsWireValue, err := webhookNotificationsToWire(v.WebhookNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.WebhookNotifications", err) + } + computeWireValue, err := computeToWire(v.Compute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Compute", err) + } + librariesWireValue, err := convertSlice(v.Libraries, libraryToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Libraries", err) + } + var environmentRefEnvironmentKeyWire *string + switch value := v.EnvironmentRef.(type) { + case nil: + case *TaskSettings_EnvironmentRef_EnvironmentKey: + if value != nil { + environmentRefEnvironmentKeyWire = new(value.EnvironmentKey) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "TaskSettings.EnvironmentRef", value) + } + var taskNotebookTaskWire *notebookTaskWire + var taskSparkJarTaskWire *sparkJarTaskWire + var taskSparkPythonTaskWire *sparkPythonTaskWire + var taskSparkSubmitTaskWire *sparkSubmitTaskWire + var taskPipelineTaskWire *pipelineTaskWire + var taskPythonWheelTaskWire *pythonWheelTaskWire + var taskDbtTaskWire *dbtTaskWire + var taskSqlTaskWire *sqlTaskWire + var taskRunJobTaskWire *runJobTaskWire + var taskConditionTaskWire *conditionTaskWire + var taskForEachTaskWire *forEachTaskWire + var taskCleanRoomsNotebookTaskWire *cleanRoomsNotebookTaskWire + var taskGenAiComputeTaskWire *genAiComputeTaskWire + var taskAlertTaskWire *alertTaskWire + var taskPowerBiTaskWire *powerBiTaskWire + var taskDashboardTaskWire *dashboardTaskWire + var taskDbtCloudTaskWire *dbtCloudTaskWire + var taskDbtPlatformTaskWire *dbtPlatformTaskWire + var taskPythonOperatorTaskWire *pythonOperatorTaskWire + var taskAiRuntimeTaskWire *aiRuntimeTaskWire + switch value := v.Task.(type) { + case nil: + case *TaskSettings_Task_NotebookTask: + if value != nil { + taskNotebookTaskConverted, err := notebookTaskToWire(&value.NotebookTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.NotebookTask", err) + } + taskNotebookTaskWire = taskNotebookTaskConverted + } + case *TaskSettings_Task_SparkJarTask: + if value != nil { + taskSparkJarTaskConverted, err := sparkJarTaskToWire(&value.SparkJarTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.SparkJarTask", err) + } + taskSparkJarTaskWire = taskSparkJarTaskConverted + } + case *TaskSettings_Task_SparkPythonTask: + if value != nil { + taskSparkPythonTaskConverted, err := sparkPythonTaskToWire(&value.SparkPythonTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.SparkPythonTask", err) + } + taskSparkPythonTaskWire = taskSparkPythonTaskConverted + } + case *TaskSettings_Task_SparkSubmitTask: + if value != nil { + taskSparkSubmitTaskConverted, err := sparkSubmitTaskToWire(&value.SparkSubmitTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.SparkSubmitTask", err) + } + taskSparkSubmitTaskWire = taskSparkSubmitTaskConverted + } + case *TaskSettings_Task_PipelineTask: + if value != nil { + taskPipelineTaskConverted, err := pipelineTaskToWire(&value.PipelineTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.PipelineTask", err) + } + taskPipelineTaskWire = taskPipelineTaskConverted + } + case *TaskSettings_Task_PythonWheelTask: + if value != nil { + taskPythonWheelTaskConverted, err := pythonWheelTaskToWire(&value.PythonWheelTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.PythonWheelTask", err) + } + taskPythonWheelTaskWire = taskPythonWheelTaskConverted + } + case *TaskSettings_Task_DbtTask: + if value != nil { + taskDbtTaskConverted, err := dbtTaskToWire(&value.DbtTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.DbtTask", err) + } + taskDbtTaskWire = taskDbtTaskConverted + } + case *TaskSettings_Task_SqlTask: + if value != nil { + taskSqlTaskConverted, err := sqlTaskToWire(&value.SqlTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.SqlTask", err) + } + taskSqlTaskWire = taskSqlTaskConverted + } + case *TaskSettings_Task_RunJobTask: + if value != nil { + taskRunJobTaskConverted, err := runJobTaskToWire(&value.RunJobTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.RunJobTask", err) + } + taskRunJobTaskWire = taskRunJobTaskConverted + } + case *TaskSettings_Task_ConditionTask: + if value != nil { + taskConditionTaskConverted, err := conditionTaskToWire(&value.ConditionTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.ConditionTask", err) + } + taskConditionTaskWire = taskConditionTaskConverted + } + case *TaskSettings_Task_ForEachTask: + if value != nil { + taskForEachTaskConverted, err := forEachTaskToWire(&value.ForEachTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.ForEachTask", err) + } + taskForEachTaskWire = taskForEachTaskConverted + } + case *TaskSettings_Task_CleanRoomsNotebookTask: + if value != nil { + taskCleanRoomsNotebookTaskConverted, err := cleanRoomsNotebookTaskToWire(&value.CleanRoomsNotebookTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.CleanRoomsNotebookTask", err) + } + taskCleanRoomsNotebookTaskWire = taskCleanRoomsNotebookTaskConverted + } + case *TaskSettings_Task_GenAiComputeTask: + if value != nil { + taskGenAiComputeTaskConverted, err := genAiComputeTaskToWire(&value.GenAiComputeTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.GenAiComputeTask", err) + } + taskGenAiComputeTaskWire = taskGenAiComputeTaskConverted + } + case *TaskSettings_Task_AlertTask: + if value != nil { + taskAlertTaskConverted, err := alertTaskToWire(&value.AlertTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.AlertTask", err) + } + taskAlertTaskWire = taskAlertTaskConverted + } + case *TaskSettings_Task_PowerBiTask: + if value != nil { + taskPowerBiTaskConverted, err := powerBiTaskToWire(&value.PowerBiTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.PowerBiTask", err) + } + taskPowerBiTaskWire = taskPowerBiTaskConverted + } + case *TaskSettings_Task_DashboardTask: + if value != nil { + taskDashboardTaskConverted, err := dashboardTaskToWire(&value.DashboardTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.DashboardTask", err) + } + taskDashboardTaskWire = taskDashboardTaskConverted + } + case *TaskSettings_Task_DbtCloudTask: + if value != nil { + taskDbtCloudTaskConverted, err := dbtCloudTaskToWire(&value.DbtCloudTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.DbtCloudTask", err) + } + taskDbtCloudTaskWire = taskDbtCloudTaskConverted + } + case *TaskSettings_Task_DbtPlatformTask: + if value != nil { + taskDbtPlatformTaskConverted, err := dbtPlatformTaskToWire(&value.DbtPlatformTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.DbtPlatformTask", err) + } + taskDbtPlatformTaskWire = taskDbtPlatformTaskConverted + } + case *TaskSettings_Task_PythonOperatorTask: + if value != nil { + taskPythonOperatorTaskConverted, err := pythonOperatorTaskToWire(&value.PythonOperatorTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.PythonOperatorTask", err) + } + taskPythonOperatorTaskWire = taskPythonOperatorTaskConverted + } + case *TaskSettings_Task_AiRuntimeTask: + if value != nil { + taskAiRuntimeTaskConverted, err := aiRuntimeTaskToWire(&value.AiRuntimeTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.AiRuntimeTask", err) + } + taskAiRuntimeTaskWire = taskAiRuntimeTaskConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "TaskSettings.Task", value) + } + var specExistingClusterIdWire *string + var specNewClusterWire *clusterSpec_NewClusterWire + var specJobClusterKeyWire *string + switch value := v.Spec.(type) { + case nil: + case *TaskSettings_Spec_ExistingClusterId: + if value != nil { + specExistingClusterIdWire = new(value.ExistingClusterId) + } + case *TaskSettings_Spec_NewCluster: + if value != nil { + specNewClusterConverted, err := clusterSpec_NewClusterToWire(&value.NewCluster) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Spec.NewCluster", err) + } + specNewClusterWire = specNewClusterConverted + } + case *TaskSettings_Spec_JobClusterKey: + if value != nil { + specJobClusterKeyWire = new(value.JobClusterKey) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "TaskSettings.Spec", value) + } + return &taskSettingsWire{ + TaskKey: v.TaskKey, + DependsOn: dependsOnWireValue, + RunIf: v.RunIf, + TimeoutSeconds: v.TimeoutSeconds, + Health: healthWireValue, + EmailNotifications: emailNotificationsWireValue, + NotificationSettings: notificationSettingsWireValue, + WebhookNotifications: webhookNotificationsWireValue, + Description: v.Description, + EnvironmentKey: environmentRefEnvironmentKeyWire, + Disabled: v.Disabled, + Compute: computeWireValue, + NotebookTask: taskNotebookTaskWire, + SparkJarTask: taskSparkJarTaskWire, + SparkPythonTask: taskSparkPythonTaskWire, + SparkSubmitTask: taskSparkSubmitTaskWire, + PipelineTask: taskPipelineTaskWire, + PythonWheelTask: taskPythonWheelTaskWire, + DbtTask: taskDbtTaskWire, + SqlTask: taskSqlTaskWire, + RunJobTask: taskRunJobTaskWire, + ConditionTask: taskConditionTaskWire, + ForEachTask: taskForEachTaskWire, + CleanRoomsNotebookTask: taskCleanRoomsNotebookTaskWire, + GenAiComputeTask: taskGenAiComputeTaskWire, + AlertTask: taskAlertTaskWire, + PowerBiTask: taskPowerBiTaskWire, + DashboardTask: taskDashboardTaskWire, + DbtCloudTask: taskDbtCloudTaskWire, + DbtPlatformTask: taskDbtPlatformTaskWire, + PythonOperatorTask: taskPythonOperatorTaskWire, + AiRuntimeTask: taskAiRuntimeTaskWire, + ExistingClusterId: specExistingClusterIdWire, + NewCluster: specNewClusterWire, + JobClusterKey: specJobClusterKeyWire, + Libraries: librariesWireValue, + MaxRetries: v.MaxRetries, + MinRetryIntervalMillis: v.MinRetryIntervalMillis, + RetryOnTimeout: v.RetryOnTimeout, + DisableAutoOptimization: v.DisableAutoOptimization, + }, nil +} + +func taskSettingsFromWire(w *taskSettingsWire) (*TaskSettings, error) { + if w == nil { + return nil, nil + } + environmentRefMembers := 0 + if w.EnvironmentKey != nil { + environmentRefMembers++ + } + if environmentRefMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "TaskSettings.EnvironmentRef") + } + taskMembers := 0 + if w.NotebookTask != nil { + taskMembers++ + } + if w.SparkJarTask != nil { + taskMembers++ + } + if w.SparkPythonTask != nil { + taskMembers++ + } + if w.SparkSubmitTask != nil { + taskMembers++ + } + if w.PipelineTask != nil { + taskMembers++ + } + if w.PythonWheelTask != nil { + taskMembers++ + } + if w.DbtTask != nil { + taskMembers++ + } + if w.SqlTask != nil { + taskMembers++ + } + if w.RunJobTask != nil { + taskMembers++ + } + if w.ConditionTask != nil { + taskMembers++ + } + if w.ForEachTask != nil { + taskMembers++ + } + if w.CleanRoomsNotebookTask != nil { + taskMembers++ + } + if w.GenAiComputeTask != nil { + taskMembers++ + } + if w.AlertTask != nil { + taskMembers++ + } + if w.PowerBiTask != nil { + taskMembers++ + } + if w.DashboardTask != nil { + taskMembers++ + } + if w.DbtCloudTask != nil { + taskMembers++ + } + if w.DbtPlatformTask != nil { + taskMembers++ + } + if w.PythonOperatorTask != nil { + taskMembers++ + } + if w.AiRuntimeTask != nil { + taskMembers++ + } + if taskMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "TaskSettings.Task") + } + specMembers := 0 + if w.ExistingClusterId != nil { + specMembers++ + } + if w.NewCluster != nil { + specMembers++ + } + if w.JobClusterKey != nil { + specMembers++ + } + if specMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "TaskSettings.Spec") + } + dependsOnPublicValue, err := convertSlice(w.DependsOn, taskDependencyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.DependsOn", err) + } + healthPublicValue, err := jobsHealthRulesFromWire(w.Health) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Health", err) + } + emailNotificationsPublicValue, err := jobEmailNotificationsFromWire(w.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.EmailNotifications", err) + } + notificationSettingsPublicValue, err := notificationSettingsFromWire(w.NotificationSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.NotificationSettings", err) + } + webhookNotificationsPublicValue, err := webhookNotificationsFromWire(w.WebhookNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.WebhookNotifications", err) + } + computePublicValue, err := computeFromWire(w.Compute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Compute", err) + } + librariesPublicValue, err := convertSlice(w.Libraries, libraryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Libraries", err) + } + var environmentRefSelection isTaskSettings_EnvironmentRef + switch { + case w.EnvironmentKey != nil: + environmentRefSelection = &TaskSettings_EnvironmentRef_EnvironmentKey{EnvironmentKey: *w.EnvironmentKey} + } + var taskSelection isTaskSettings_Task + switch { + case w.NotebookTask != nil: + taskNotebookTaskConverted, err := notebookTaskFromWire(w.NotebookTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.NotebookTask", err) + } + taskSelection = &TaskSettings_Task_NotebookTask{NotebookTask: *taskNotebookTaskConverted} + case w.SparkJarTask != nil: + taskSparkJarTaskConverted, err := sparkJarTaskFromWire(w.SparkJarTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.SparkJarTask", err) + } + taskSelection = &TaskSettings_Task_SparkJarTask{SparkJarTask: *taskSparkJarTaskConverted} + case w.SparkPythonTask != nil: + taskSparkPythonTaskConverted, err := sparkPythonTaskFromWire(w.SparkPythonTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.SparkPythonTask", err) + } + taskSelection = &TaskSettings_Task_SparkPythonTask{SparkPythonTask: *taskSparkPythonTaskConverted} + case w.SparkSubmitTask != nil: + taskSparkSubmitTaskConverted, err := sparkSubmitTaskFromWire(w.SparkSubmitTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.SparkSubmitTask", err) + } + taskSelection = &TaskSettings_Task_SparkSubmitTask{SparkSubmitTask: *taskSparkSubmitTaskConverted} + case w.PipelineTask != nil: + taskPipelineTaskConverted, err := pipelineTaskFromWire(w.PipelineTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.PipelineTask", err) + } + taskSelection = &TaskSettings_Task_PipelineTask{PipelineTask: *taskPipelineTaskConverted} + case w.PythonWheelTask != nil: + taskPythonWheelTaskConverted, err := pythonWheelTaskFromWire(w.PythonWheelTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.PythonWheelTask", err) + } + taskSelection = &TaskSettings_Task_PythonWheelTask{PythonWheelTask: *taskPythonWheelTaskConverted} + case w.DbtTask != nil: + taskDbtTaskConverted, err := dbtTaskFromWire(w.DbtTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.DbtTask", err) + } + taskSelection = &TaskSettings_Task_DbtTask{DbtTask: *taskDbtTaskConverted} + case w.SqlTask != nil: + taskSqlTaskConverted, err := sqlTaskFromWire(w.SqlTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.SqlTask", err) + } + taskSelection = &TaskSettings_Task_SqlTask{SqlTask: *taskSqlTaskConverted} + case w.RunJobTask != nil: + taskRunJobTaskConverted, err := runJobTaskFromWire(w.RunJobTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.RunJobTask", err) + } + taskSelection = &TaskSettings_Task_RunJobTask{RunJobTask: *taskRunJobTaskConverted} + case w.ConditionTask != nil: + taskConditionTaskConverted, err := conditionTaskFromWire(w.ConditionTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.ConditionTask", err) + } + taskSelection = &TaskSettings_Task_ConditionTask{ConditionTask: *taskConditionTaskConverted} + case w.ForEachTask != nil: + taskForEachTaskConverted, err := forEachTaskFromWire(w.ForEachTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.ForEachTask", err) + } + taskSelection = &TaskSettings_Task_ForEachTask{ForEachTask: *taskForEachTaskConverted} + case w.CleanRoomsNotebookTask != nil: + taskCleanRoomsNotebookTaskConverted, err := cleanRoomsNotebookTaskFromWire(w.CleanRoomsNotebookTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.CleanRoomsNotebookTask", err) + } + taskSelection = &TaskSettings_Task_CleanRoomsNotebookTask{CleanRoomsNotebookTask: *taskCleanRoomsNotebookTaskConverted} + case w.GenAiComputeTask != nil: + taskGenAiComputeTaskConverted, err := genAiComputeTaskFromWire(w.GenAiComputeTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.GenAiComputeTask", err) + } + taskSelection = &TaskSettings_Task_GenAiComputeTask{GenAiComputeTask: *taskGenAiComputeTaskConverted} + case w.AlertTask != nil: + taskAlertTaskConverted, err := alertTaskFromWire(w.AlertTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.AlertTask", err) + } + taskSelection = &TaskSettings_Task_AlertTask{AlertTask: *taskAlertTaskConverted} + case w.PowerBiTask != nil: + taskPowerBiTaskConverted, err := powerBiTaskFromWire(w.PowerBiTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.PowerBiTask", err) + } + taskSelection = &TaskSettings_Task_PowerBiTask{PowerBiTask: *taskPowerBiTaskConverted} + case w.DashboardTask != nil: + taskDashboardTaskConverted, err := dashboardTaskFromWire(w.DashboardTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.DashboardTask", err) + } + taskSelection = &TaskSettings_Task_DashboardTask{DashboardTask: *taskDashboardTaskConverted} + case w.DbtCloudTask != nil: + taskDbtCloudTaskConverted, err := dbtCloudTaskFromWire(w.DbtCloudTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.DbtCloudTask", err) + } + taskSelection = &TaskSettings_Task_DbtCloudTask{DbtCloudTask: *taskDbtCloudTaskConverted} + case w.DbtPlatformTask != nil: + taskDbtPlatformTaskConverted, err := dbtPlatformTaskFromWire(w.DbtPlatformTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.DbtPlatformTask", err) + } + taskSelection = &TaskSettings_Task_DbtPlatformTask{DbtPlatformTask: *taskDbtPlatformTaskConverted} + case w.PythonOperatorTask != nil: + taskPythonOperatorTaskConverted, err := pythonOperatorTaskFromWire(w.PythonOperatorTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.PythonOperatorTask", err) + } + taskSelection = &TaskSettings_Task_PythonOperatorTask{PythonOperatorTask: *taskPythonOperatorTaskConverted} + case w.AiRuntimeTask != nil: + taskAiRuntimeTaskConverted, err := aiRuntimeTaskFromWire(w.AiRuntimeTask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Task.AiRuntimeTask", err) + } + taskSelection = &TaskSettings_Task_AiRuntimeTask{AiRuntimeTask: *taskAiRuntimeTaskConverted} + } + var specSelection isTaskSettings_Spec + switch { + case w.ExistingClusterId != nil: + specSelection = &TaskSettings_Spec_ExistingClusterId{ExistingClusterId: *w.ExistingClusterId} + case w.NewCluster != nil: + specNewClusterConverted, err := clusterSpec_NewClusterFromWire(w.NewCluster) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskSettings.Spec.NewCluster", err) + } + specSelection = &TaskSettings_Spec_NewCluster{NewCluster: *specNewClusterConverted} + case w.JobClusterKey != nil: + specSelection = &TaskSettings_Spec_JobClusterKey{JobClusterKey: *w.JobClusterKey} + } + return &TaskSettings{ + TaskKey: w.TaskKey, + DependsOn: dependsOnPublicValue, + RunIf: w.RunIf, + TimeoutSeconds: w.TimeoutSeconds, + Health: healthPublicValue, + EmailNotifications: emailNotificationsPublicValue, + NotificationSettings: notificationSettingsPublicValue, + WebhookNotifications: webhookNotificationsPublicValue, + Description: w.Description, + Disabled: w.Disabled, + Compute: computePublicValue, + Libraries: librariesPublicValue, + MaxRetries: w.MaxRetries, + MinRetryIntervalMillis: w.MinRetryIntervalMillis, + RetryOnTimeout: w.RetryOnTimeout, + DisableAutoOptimization: w.DisableAutoOptimization, + EnvironmentRef: environmentRefSelection, + Task: taskSelection, + Spec: specSelection, + }, nil +} + +type terminationDetailsWire struct { + Code TerminationCode_Code `json:"code,omitempty"` + Type TerminationType_Type `json:"type,omitempty"` + Message *string `json:"message,omitempty"` +} + +func terminationDetailsFromWire(w *terminationDetailsWire) (*TerminationDetails, error) { + if w == nil { + return nil, nil + } + return &TerminationDetails{ + Code: w.Code, + Type: w.Type, + Message: w.Message, + }, nil +} + +type triggerConfigurationWire struct { + PauseStatus SchedulePauseStatus `json:"pause_status,omitempty"` + Periodic *periodicTriggerConfigurationWire `json:"periodic,omitempty"` + Schedule *cronTriggerConfigurationWire `json:"schedule,omitempty"` + Continuous *continuousTriggerConfigurationWire `json:"continuous,omitempty"` + FileArrival *fileArrivalTriggerConfigurationWire `json:"file_arrival,omitempty"` + TableUpdate *tableTriggerConfigurationWire `json:"table_update,omitempty"` + Model *modelTriggerConfigurationWire `json:"model,omitempty"` + SqlCondition *sqlConditionConfigurationWire `json:"sql_condition,omitempty"` +} + +func triggerConfigurationToWire(v *TriggerConfiguration) (*triggerConfigurationWire, error) { + if v == nil { + return nil, nil + } + periodicWireValue, err := periodicTriggerConfigurationToWire(v.Periodic) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.Periodic", err) + } + scheduleWireValue, err := cronTriggerConfigurationToWire(v.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.Schedule", err) + } + continuousWireValue, err := continuousTriggerConfigurationToWire(v.Continuous) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.Continuous", err) + } + fileArrivalWireValue, err := fileArrivalTriggerConfigurationToWire(v.FileArrival) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.FileArrival", err) + } + tableUpdateWireValue, err := tableTriggerConfigurationToWire(v.TableUpdate) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.TableUpdate", err) + } + modelWireValue, err := modelTriggerConfigurationToWire(v.Model) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.Model", err) + } + sqlConditionWireValue, err := sqlConditionConfigurationToWire(v.SqlCondition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.SqlCondition", err) + } + return &triggerConfigurationWire{ + PauseStatus: v.PauseStatus, + Periodic: periodicWireValue, + Schedule: scheduleWireValue, + Continuous: continuousWireValue, + FileArrival: fileArrivalWireValue, + TableUpdate: tableUpdateWireValue, + Model: modelWireValue, + SqlCondition: sqlConditionWireValue, + }, nil +} + +func triggerConfigurationFromWire(w *triggerConfigurationWire) (*TriggerConfiguration, error) { + if w == nil { + return nil, nil + } + periodicPublicValue, err := periodicTriggerConfigurationFromWire(w.Periodic) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.Periodic", err) + } + schedulePublicValue, err := cronTriggerConfigurationFromWire(w.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.Schedule", err) + } + continuousPublicValue, err := continuousTriggerConfigurationFromWire(w.Continuous) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.Continuous", err) + } + fileArrivalPublicValue, err := fileArrivalTriggerConfigurationFromWire(w.FileArrival) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.FileArrival", err) + } + tableUpdatePublicValue, err := tableTriggerConfigurationFromWire(w.TableUpdate) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.TableUpdate", err) + } + modelPublicValue, err := modelTriggerConfigurationFromWire(w.Model) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.Model", err) + } + sqlConditionPublicValue, err := sqlConditionConfigurationFromWire(w.SqlCondition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerConfiguration.SqlCondition", err) + } + return &TriggerConfiguration{ + PauseStatus: w.PauseStatus, + Periodic: periodicPublicValue, + Schedule: schedulePublicValue, + Continuous: continuousPublicValue, + FileArrival: fileArrivalPublicValue, + TableUpdate: tableUpdatePublicValue, + Model: modelPublicValue, + SqlCondition: sqlConditionPublicValue, + }, nil +} + +type triggerDetailsWire struct { + State *perTriggerStateWire `json:"state,omitempty"` + History *triggerHistoryWire `json:"history,omitempty"` +} + +func triggerDetailsFromWire(w *triggerDetailsWire) (*TriggerDetails, error) { + if w == nil { + return nil, nil + } + statePublicValue, err := perTriggerStateFromWire(w.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerDetails.State", err) + } + historyPublicValue, err := triggerHistoryFromWire(w.History) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerDetails.History", err) + } + return &TriggerDetails{ + State: statePublicValue, + History: historyPublicValue, + }, nil +} + +type triggerEvaluationWire struct { + Timestamp *int64 `json:"timestamp,omitempty"` + Description *string `json:"description,omitempty"` + RunId *int64 `json:"run_id,omitempty"` +} + +func triggerEvaluationFromWire(w *triggerEvaluationWire) (*TriggerEvaluation, error) { + if w == nil { + return nil, nil + } + return &TriggerEvaluation{ + Timestamp: w.Timestamp, + Description: w.Description, + RunId: w.RunId, + }, nil +} + +type triggerHistoryWire struct { + LastTriggered *triggerEvaluationWire `json:"last_triggered,omitempty"` + LastNotTriggered *triggerEvaluationWire `json:"last_not_triggered,omitempty"` + LastFailed *triggerEvaluationWire `json:"last_failed,omitempty"` +} + +func triggerHistoryFromWire(w *triggerHistoryWire) (*TriggerHistory, error) { + if w == nil { + return nil, nil + } + lastTriggeredPublicValue, err := triggerEvaluationFromWire(w.LastTriggered) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerHistory.LastTriggered", err) + } + lastNotTriggeredPublicValue, err := triggerEvaluationFromWire(w.LastNotTriggered) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerHistory.LastNotTriggered", err) + } + lastFailedPublicValue, err := triggerEvaluationFromWire(w.LastFailed) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerHistory.LastFailed", err) + } + return &TriggerHistory{ + LastTriggered: lastTriggeredPublicValue, + LastNotTriggered: lastNotTriggeredPublicValue, + LastFailed: lastFailedPublicValue, + }, nil +} + +type triggerSettingsWire struct { + PauseStatus SchedulePauseStatus `json:"pause_status,omitempty"` + FileArrival *fileArrivalTriggerConfigurationWire `json:"file_arrival,omitempty"` + Periodic *periodicTriggerConfigurationWire `json:"periodic,omitempty"` + TableUpdate *tableTriggerConfigurationWire `json:"table_update,omitempty"` + Model *modelTriggerConfigurationWire `json:"model,omitempty"` + SqlCondition *sqlConditionConfigurationWire `json:"sql_condition,omitempty"` +} + +func triggerSettingsToWire(v *TriggerSettings) (*triggerSettingsWire, error) { + if v == nil { + return nil, nil + } + sqlConditionWireValue, err := sqlConditionConfigurationToWire(v.SqlCondition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerSettings.SqlCondition", err) + } + var configurationFileArrivalWire *fileArrivalTriggerConfigurationWire + var configurationPeriodicWire *periodicTriggerConfigurationWire + var configurationTableUpdateWire *tableTriggerConfigurationWire + var configurationModelWire *modelTriggerConfigurationWire + switch value := v.Configuration.(type) { + case nil: + case *TriggerSettings_Configuration_FileArrival: + if value != nil { + configurationFileArrivalConverted, err := fileArrivalTriggerConfigurationToWire(&value.FileArrival) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerSettings.Configuration.FileArrival", err) + } + configurationFileArrivalWire = configurationFileArrivalConverted + } + case *TriggerSettings_Configuration_Periodic: + if value != nil { + configurationPeriodicConverted, err := periodicTriggerConfigurationToWire(&value.Periodic) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerSettings.Configuration.Periodic", err) + } + configurationPeriodicWire = configurationPeriodicConverted + } + case *TriggerSettings_Configuration_TableUpdate: + if value != nil { + configurationTableUpdateConverted, err := tableTriggerConfigurationToWire(&value.TableUpdate) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerSettings.Configuration.TableUpdate", err) + } + configurationTableUpdateWire = configurationTableUpdateConverted + } + case *TriggerSettings_Configuration_Model: + if value != nil { + configurationModelConverted, err := modelTriggerConfigurationToWire(&value.Model) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerSettings.Configuration.Model", err) + } + configurationModelWire = configurationModelConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "TriggerSettings.Configuration", value) + } + return &triggerSettingsWire{ + PauseStatus: v.PauseStatus, + FileArrival: configurationFileArrivalWire, + Periodic: configurationPeriodicWire, + TableUpdate: configurationTableUpdateWire, + Model: configurationModelWire, + SqlCondition: sqlConditionWireValue, + }, nil +} + +func triggerSettingsFromWire(w *triggerSettingsWire) (*TriggerSettings, error) { + if w == nil { + return nil, nil + } + configurationMembers := 0 + if w.FileArrival != nil { + configurationMembers++ + } + if w.Periodic != nil { + configurationMembers++ + } + if w.TableUpdate != nil { + configurationMembers++ + } + if w.Model != nil { + configurationMembers++ + } + if configurationMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "TriggerSettings.Configuration") + } + sqlConditionPublicValue, err := sqlConditionConfigurationFromWire(w.SqlCondition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerSettings.SqlCondition", err) + } + var configurationSelection isTriggerSettings_Configuration + switch { + case w.FileArrival != nil: + configurationFileArrivalConverted, err := fileArrivalTriggerConfigurationFromWire(w.FileArrival) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerSettings.Configuration.FileArrival", err) + } + configurationSelection = &TriggerSettings_Configuration_FileArrival{FileArrival: *configurationFileArrivalConverted} + case w.Periodic != nil: + configurationPeriodicConverted, err := periodicTriggerConfigurationFromWire(w.Periodic) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerSettings.Configuration.Periodic", err) + } + configurationSelection = &TriggerSettings_Configuration_Periodic{Periodic: *configurationPeriodicConverted} + case w.TableUpdate != nil: + configurationTableUpdateConverted, err := tableTriggerConfigurationFromWire(w.TableUpdate) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerSettings.Configuration.TableUpdate", err) + } + configurationSelection = &TriggerSettings_Configuration_TableUpdate{TableUpdate: *configurationTableUpdateConverted} + case w.Model != nil: + configurationModelConverted, err := modelTriggerConfigurationFromWire(w.Model) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerSettings.Configuration.Model", err) + } + configurationSelection = &TriggerSettings_Configuration_Model{Model: *configurationModelConverted} + } + return &TriggerSettings{ + PauseStatus: w.PauseStatus, + SqlCondition: sqlConditionPublicValue, + Configuration: configurationSelection, + }, nil +} + +type triggerStateWire struct { + Table *tableTriggerStateWire `json:"table,omitempty"` + FileArrival *fileArrivalTriggerStateWire `json:"file_arrival,omitempty"` + SqlCondition *sqlConditionStateWire `json:"sql_condition,omitempty"` + PauseStatus SchedulePauseStatus `json:"pause_status,omitempty"` +} + +func triggerStateFromWire(w *triggerStateWire) (*TriggerState, error) { + if w == nil { + return nil, nil + } + triggerTypeMembers := 0 + if w.Table != nil { + triggerTypeMembers++ + } + if w.FileArrival != nil { + triggerTypeMembers++ + } + if triggerTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "TriggerState.TriggerType") + } + sqlConditionPublicValue, err := sqlConditionStateFromWire(w.SqlCondition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerState.SqlCondition", err) + } + var triggerTypeSelection isTriggerState_TriggerType + switch { + case w.Table != nil: + triggerTypeTableConverted, err := tableTriggerStateFromWire(w.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerState.TriggerType.Table", err) + } + triggerTypeSelection = &TriggerState_TriggerType_Table{Table: *triggerTypeTableConverted} + case w.FileArrival != nil: + triggerTypeFileArrivalConverted, err := fileArrivalTriggerStateFromWire(w.FileArrival) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggerState.TriggerType.FileArrival", err) + } + triggerTypeSelection = &TriggerState_TriggerType_FileArrival{FileArrival: *triggerTypeFileArrivalConverted} + } + return &TriggerState{ + SqlCondition: sqlConditionPublicValue, + PauseStatus: w.PauseStatus, + TriggerType: triggerTypeSelection, + }, nil +} + +type updateJobRequestWire struct { + JobId *int64 `json:"job_id,omitempty"` + NewSettings *jobSettingsWire `json:"new_settings,omitempty"` + FieldsToRemove []string `json:"fields_to_remove,omitempty"` +} + +func updateJobRequestToWire(v *UpdateJobRequest) (*updateJobRequestWire, error) { + if v == nil { + return nil, nil + } + newSettingsWireValue, err := jobSettingsToWire(v.NewSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateJobRequest.NewSettings", err) + } + return &updateJobRequestWire{ + JobId: v.JobId, + NewSettings: newSettingsWireValue, + FieldsToRemove: v.FieldsToRemove, + }, nil +} + +type viewItemWire struct { + Content *string `json:"content,omitempty"` + Name *string `json:"name,omitempty"` + Type ViewType `json:"type,omitempty"` +} + +func viewItemFromWire(w *viewItemWire) (*ViewItem, error) { + if w == nil { + return nil, nil + } + return &ViewItem{ + Content: w.Content, + Name: w.Name, + Type: w.Type, + }, nil +} + +type volumesStorageInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func volumesStorageInfoToWire(v *VolumesStorageInfo) (*volumesStorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &volumesStorageInfoWire{ + Destination: v.Destination, + }, nil +} + +func volumesStorageInfoFromWire(w *volumesStorageInfoWire) (*VolumesStorageInfo, error) { + if w == nil { + return nil, nil + } + return &VolumesStorageInfo{ + Destination: w.Destination, + }, nil +} + +type webhookWire struct { + Id *string `json:"id,omitempty"` +} + +func webhookToWire(v *Webhook) (*webhookWire, error) { + if v == nil { + return nil, nil + } + return &webhookWire{ + Id: v.Id, + }, nil +} + +func webhookFromWire(w *webhookWire) (*Webhook, error) { + if w == nil { + return nil, nil + } + return &Webhook{ + Id: w.Id, + }, nil +} + +type webhookNotificationsWire struct { + OnStart []webhookWire `json:"on_start,omitempty"` + OnSuccess []webhookWire `json:"on_success,omitempty"` + OnFailure []webhookWire `json:"on_failure,omitempty"` + OnDurationWarningThresholdExceeded []webhookWire `json:"on_duration_warning_threshold_exceeded,omitempty"` + OnStreamingBacklogExceeded []webhookWire `json:"on_streaming_backlog_exceeded,omitempty"` +} + +func webhookNotificationsToWire(v *WebhookNotifications) (*webhookNotificationsWire, error) { + if v == nil { + return nil, nil + } + onStartWireValue, err := convertSlice(v.OnStart, webhookToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WebhookNotifications.OnStart", err) + } + onSuccessWireValue, err := convertSlice(v.OnSuccess, webhookToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WebhookNotifications.OnSuccess", err) + } + onFailureWireValue, err := convertSlice(v.OnFailure, webhookToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WebhookNotifications.OnFailure", err) + } + onDurationWarningThresholdExceededWireValue, err := convertSlice(v.OnDurationWarningThresholdExceeded, webhookToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WebhookNotifications.OnDurationWarningThresholdExceeded", err) + } + onStreamingBacklogExceededWireValue, err := convertSlice(v.OnStreamingBacklogExceeded, webhookToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WebhookNotifications.OnStreamingBacklogExceeded", err) + } + return &webhookNotificationsWire{ + OnStart: onStartWireValue, + OnSuccess: onSuccessWireValue, + OnFailure: onFailureWireValue, + OnDurationWarningThresholdExceeded: onDurationWarningThresholdExceededWireValue, + OnStreamingBacklogExceeded: onStreamingBacklogExceededWireValue, + }, nil +} + +func webhookNotificationsFromWire(w *webhookNotificationsWire) (*WebhookNotifications, error) { + if w == nil { + return nil, nil + } + onStartPublicValue, err := convertSlice(w.OnStart, webhookFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WebhookNotifications.OnStart", err) + } + onSuccessPublicValue, err := convertSlice(w.OnSuccess, webhookFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WebhookNotifications.OnSuccess", err) + } + onFailurePublicValue, err := convertSlice(w.OnFailure, webhookFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WebhookNotifications.OnFailure", err) + } + onDurationWarningThresholdExceededPublicValue, err := convertSlice(w.OnDurationWarningThresholdExceeded, webhookFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WebhookNotifications.OnDurationWarningThresholdExceeded", err) + } + onStreamingBacklogExceededPublicValue, err := convertSlice(w.OnStreamingBacklogExceeded, webhookFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WebhookNotifications.OnStreamingBacklogExceeded", err) + } + return &WebhookNotifications{ + OnStart: onStartPublicValue, + OnSuccess: onSuccessPublicValue, + OnFailure: onFailurePublicValue, + OnDurationWarningThresholdExceeded: onDurationWarningThresholdExceededPublicValue, + OnStreamingBacklogExceeded: onStreamingBacklogExceededPublicValue, + }, nil +} + +type widgetErrorDetailWire struct { + Message *string `json:"message,omitempty"` +} + +func widgetErrorDetailFromWire(w *widgetErrorDetailWire) (*WidgetErrorDetail, error) { + if w == nil { + return nil, nil + } + return &WidgetErrorDetail{ + Message: w.Message, + }, nil +} + +type workloadTypeWire struct { + Clients *workloadType_ClientsTypesWire `json:"clients,omitempty"` +} + +func workloadTypeToWire(v *WorkloadType) (*workloadTypeWire, error) { + if v == nil { + return nil, nil + } + clientsWireValue, err := workloadType_ClientsTypesToWire(v.Clients) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkloadType.Clients", err) + } + return &workloadTypeWire{ + Clients: clientsWireValue, + }, nil +} + +func workloadTypeFromWire(w *workloadTypeWire) (*WorkloadType, error) { + if w == nil { + return nil, nil + } + clientsPublicValue, err := workloadType_ClientsTypesFromWire(w.Clients) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkloadType.Clients", err) + } + return &WorkloadType{ + Clients: clientsPublicValue, + }, nil +} + +type workloadType_ClientsTypesWire struct { + Notebooks *bool `json:"notebooks,omitempty"` + Jobs *bool `json:"jobs,omitempty"` +} + +func workloadType_ClientsTypesToWire(v *WorkloadType_ClientsTypes) (*workloadType_ClientsTypesWire, error) { + if v == nil { + return nil, nil + } + return &workloadType_ClientsTypesWire{ + Notebooks: v.Notebooks, + Jobs: v.Jobs, + }, nil +} + +func workloadType_ClientsTypesFromWire(w *workloadType_ClientsTypesWire) (*WorkloadType_ClientsTypes, error) { + if w == nil { + return nil, nil + } + return &WorkloadType_ClientsTypes{ + Notebooks: w.Notebooks, + Jobs: w.Jobs, + }, nil +} + +type workspaceStorageInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func workspaceStorageInfoToWire(v *WorkspaceStorageInfo) (*workspaceStorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &workspaceStorageInfoWire{ + Destination: v.Destination, + }, nil +} + +func workspaceStorageInfoFromWire(w *workspaceStorageInfoWire) (*WorkspaceStorageInfo, error) { + if w == nil { + return nil, nil + } + return &WorkspaceStorageInfo{ + Destination: w.Destination, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/keyconfigurations/.package.json b/keyconfigurations/.package.json new file mode 100644 index 0000000..61c3f5e --- /dev/null +++ b/keyconfigurations/.package.json @@ -0,0 +1,3 @@ +{ + "package": "keyconfigurations" +} diff --git a/keyconfigurations/CHANGELOG.md b/keyconfigurations/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/keyconfigurations/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/keyconfigurations/README.md b/keyconfigurations/README.md new file mode 100644 index 0000000..3495660 --- /dev/null +++ b/keyconfigurations/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/keyconfigurations + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/keyconfigurations@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/keyconfigurations/v1" + +client, err := keyconfigurations.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/keyconfigurations/go.mod b/keyconfigurations/go.mod new file mode 100644 index 0000000..45f915a --- /dev/null +++ b/keyconfigurations/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/keyconfigurations + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/keyconfigurations/internal/version.go b/keyconfigurations/internal/version.go new file mode 100644 index 0000000..1b850b8 --- /dev/null +++ b/keyconfigurations/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-keyconfigurations" + +const Version = "0.0.1-dev.1" diff --git a/keyconfigurations/v1/client.go b/keyconfigurations/v1/client.go new file mode 100755 index 0000000..cd3a4c8 --- /dev/null +++ b/keyconfigurations/v1/client.go @@ -0,0 +1,382 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package keyconfigurations + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/keyconfigurations/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a customer-managed key configuration object for an account, specified +// by ID. This operation uploads a reference to a customer-managed key to +// . If the key is assigned as a workspace's customer-managed key +// for managed services, uses the key to encrypt the workspaces +// notebooks and secrets in the control plane, in addition to Databricks SQL +// queries and query history. If it is specified as a workspace's +// customer-managed key for workspace storage, the key encrypts the workspace's +// root S3 bucket (which contains the workspace's root DBFS and system data) +// and, optionally, cluster EBS volume data. +// +// **Important**: Customer-managed keys are supported only for some deployment +// types, subscription types, and AWS regions that currently support creation of +// workspaces. +// +// This operation is available only if your account is on the E2 version of the +// platform or on a select custom plan that allows multiple workspaces per +// account. +// +// **GCP only**: To create a customer-managed key on GCP, you must include the +// `X-Databricks-GCP-SA-Access-Token` HTTP header in your request. This header +// must contain a Google Cloud OAuth access token with the `cloud-platform` +// scope. The Google identity associated with the token must also have the +// `setIamPermissions` and `getIamPermissions` IAM permissions on the key +// resource. For details on obtaining this token, see [Authenticate with Google +// ID tokens]. +// +// [Authenticate with Google ID tokens]: https://docs.databricks.com/gcp/en/dev-tools/auth/authentication-google-id.html +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateCustomerManagedKeyPublic(ctx context.Context, req *CreateCustomerManagedKeyRequest, opts ...call.Option) (*CustomerManagedKey, error) { + wireReq, err := createCustomerManagedKeyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/customer-managed-keys") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomerManagedKey + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customerManagedKeyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customerManagedKeyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a customer-managed key configuration object for an account. You +// cannot delete a configuration that is associated with a running workspace. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteCustomerManagedKeyPublic(ctx context.Context, req *DeleteCustomerManagedKeyRequest, opts ...call.Option) (*CustomerManagedKey, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/customer-managed-keys/") + pb.singleSegment(*req.CustomerManagedKeyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomerManagedKey + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customerManagedKeyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customerManagedKeyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a customer-managed key configuration object for an account, specified by +// ID. This operation uploads a reference to a customer-managed key to +// . If assigned as a workspace's customer-managed key for managed +// services, uses the key to encrypt the workspaces notebooks and +// secrets in the control plane, in addition to Databricks SQL queries and query +// history. If it is specified as a workspace's customer-managed key for +// storage, the key encrypts the workspace's root S3 bucket (which contains the +// workspace's root DBFS and system data) and, optionally, cluster EBS volume +// data. +// +// **Important**: Customer-managed keys are supported only for some deployment +// types, subscription types, and AWS regions. +// +// This operation is available only if your account is on the E2 version of the +// platform.", +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetCustomerManagedKeyPublic(ctx context.Context, req *GetCustomerManagedKeyRequest, opts ...call.Option) (*CustomerManagedKey, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/customer-managed-keys/") + pb.singleSegment(*req.CustomerManagedKeyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomerManagedKey + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customerManagedKeyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customerManagedKeyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists customer-managed key configurations for an account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListCustomerManagedKeyPublic(ctx context.Context, req *ListCustomerManagedKeyRequest, opts ...call.Option) (*ListCustomerManagedKeyResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/customer-managed-keys") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCustomerManagedKeyResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp []customerManagedKeyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + convertedResponseBody, err := convertSlice(wireResp, customerManagedKeyFromWire) + if err != nil { + return fmt.Errorf("ListCustomerManagedKeyResponse.CustomerManagedKeys: %w", err) + } + resp = &ListCustomerManagedKeyResponse{ + CustomerManagedKeys: convertedResponseBody, + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/keyconfigurations/v1/genhelper.go b/keyconfigurations/v1/genhelper.go new file mode 100755 index 0000000..00010ac --- /dev/null +++ b/keyconfigurations/v1/genhelper.go @@ -0,0 +1,188 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package keyconfigurations + +import ( + "context" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/keyconfigurations/v1/model.go b/keyconfigurations/v1/model.go new file mode 100755 index 0000000..46304c0 --- /dev/null +++ b/keyconfigurations/v1/model.go @@ -0,0 +1,205 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package keyconfigurations + +type CmkUseCase string + +const ( + CmkUseCase_Unspecified CmkUseCase = "" + // Encryption for the customer cloud resources. + CmkUseCase_Storage CmkUseCase = "STORAGE" +) + +type AwsKeyInfo struct { + // The AWS KMS key's Amazon Resource Name (ARN). + KeyArn *string + // The AWS KMS key alias. + KeyAlias *string + // The AWS KMS key region. + KeyRegion *string + // This field applies only if the `use_cases` property includes `STORAGE`. If + // this is set to true or omitted, the key is also used to encrypt cluster EBS + // volumes. If you do not want to use this key for encrypting EBS volumes, set + // to false. + ReuseKeyForClusterVolumes *bool +} + +type AzureKeyInfo struct { + // The base URI of the KeyVault. + KeyVaultUri *string + // The name of the key in KeyVault. + KeyName *string + // The current key version. + Version *string + // The tenant id where the KeyVault lives. + TenantId *string + // The Disk Encryption Set id that is used to represent the key info used for + // Managed Disk BYOK use case + DiskEncryptionSetId *string + // The structure to store key access credential This is set if the Managed + // Identity is being used to access the Azure Key Vault key. + KeyAccessConfiguration *KeyAccessConfiguration +} + +type CreateAwsKeyInfo struct { + // The AWS KMS key's Amazon Resource Name (ARN). + KeyArn *string + // The AWS KMS key alias. + KeyAlias *string + // The AWS KMS key region. + KeyRegion *string + // This field applies only if the `use_cases` property includes `STORAGE`. If + // this is set to true or omitted, the key is also used to encrypt cluster EBS + // volumes. If you do not want to use this key for encrypting EBS volumes, set + // to false. + ReuseKeyForClusterVolumes *bool +} + +type CreateAzureKeyInfo struct { + // The base URI of the KeyVault. + KeyVaultUri *string + // The name of the key in KeyVault. + KeyName *string + // The current key version. + Version *string + // The tenant id where the KeyVault lives. + TenantId *string + // The Disk Encryption Set id that is used to represent the key info used for + // Managed Disk BYOK use case + DiskEncryptionSetId *string + // The structure to store key access credential This is set if the Managed + // Identity is being used to access the Azure Key Vault key. + KeyAccessConfiguration *KeyAccessConfiguration +} + +type CreateCustomerManagedKeyRequest struct { + AccountId *string + // (-- The key information. Exactly one of aws_key_info, gcp_key_info, or + // azure_key_info must be set, matching the cloud of the account. --) + KeyInfo isCreateCustomerManagedKeyRequest_KeyInfo + // The cases that the key can be used for. + UseCases []CmkUseCase +} + +type isCreateCustomerManagedKeyRequest_KeyInfo interface { + isCreateCustomerManagedKeyRequest_KeyInfo() +} + +// CreateCustomerManagedKeyRequest_KeyInfo_AwsKeyInfo selects AwsKeyInfo for CreateCustomerManagedKeyRequest.KeyInfo. +type CreateCustomerManagedKeyRequest_KeyInfo_AwsKeyInfo struct { + AwsKeyInfo CreateAwsKeyInfo +} + +func (*CreateCustomerManagedKeyRequest_KeyInfo_AwsKeyInfo) isCreateCustomerManagedKeyRequest_KeyInfo() { +} + +// CreateCustomerManagedKeyRequest_KeyInfo_GcpKeyInfo selects GcpKeyInfo for CreateCustomerManagedKeyRequest.KeyInfo. +type CreateCustomerManagedKeyRequest_KeyInfo_GcpKeyInfo struct { + GcpKeyInfo CreateGcpKeyInfo +} + +func (*CreateCustomerManagedKeyRequest_KeyInfo_GcpKeyInfo) isCreateCustomerManagedKeyRequest_KeyInfo() { +} + +// CreateCustomerManagedKeyRequest_KeyInfo_AzureKeyInfo selects AzureKeyInfo for CreateCustomerManagedKeyRequest.KeyInfo. +type CreateCustomerManagedKeyRequest_KeyInfo_AzureKeyInfo struct { + AzureKeyInfo CreateAzureKeyInfo +} + +func (*CreateCustomerManagedKeyRequest_KeyInfo_AzureKeyInfo) isCreateCustomerManagedKeyRequest_KeyInfo() { +} + +type CreateGcpKeyInfo struct { + // Globally unique kms key resource id of the form + // projects/testProjectId/locations/us-east4/keyRings/gcpCmkKeyRing/cryptoKeys/cmk-eastus4 + KmsKeyId *string + // Globally unique service account email that has access to the KMS key. The + // service account exists within the Databricks CP project. + GcpServiceAccount *GcpServiceAccount + // When true, will not use OAuth to grant the service account + // access to the KMS key. The customer is responsible for granting access + // manually. + Manual *bool +} + +type CustomerManagedKey struct { + // ID of the encryption key configuration object. + CustomerManagedKeyId *string + // Time in epoch milliseconds when the customer key was created. + CreationTime *int64 + // The account ID that holds the customer-managed key. + AccountId *string + // (-- The key information, if aws_key_info is defined, it's a AWS Databricks + // object. If azure_key_info is defined, it's an Azure Databricks customer key + // object. --) + KeyInfo isCustomerManagedKey_KeyInfo + // The cases that the key can be used for. + UseCases []CmkUseCase +} + +type isCustomerManagedKey_KeyInfo interface { + isCustomerManagedKey_KeyInfo() +} + +// CustomerManagedKey_KeyInfo_AwsKeyInfo selects AwsKeyInfo for CustomerManagedKey.KeyInfo. +type CustomerManagedKey_KeyInfo_AwsKeyInfo struct { + AwsKeyInfo AwsKeyInfo +} + +func (*CustomerManagedKey_KeyInfo_AwsKeyInfo) isCustomerManagedKey_KeyInfo() {} + +// CustomerManagedKey_KeyInfo_AzureKeyInfo selects AzureKeyInfo for CustomerManagedKey.KeyInfo. +type CustomerManagedKey_KeyInfo_AzureKeyInfo struct { + AzureKeyInfo AzureKeyInfo +} + +func (*CustomerManagedKey_KeyInfo_AzureKeyInfo) isCustomerManagedKey_KeyInfo() {} + +// CustomerManagedKey_KeyInfo_GcpKeyInfo selects GcpKeyInfo for CustomerManagedKey.KeyInfo. +type CustomerManagedKey_KeyInfo_GcpKeyInfo struct { + GcpKeyInfo GcpKeyInfo +} + +func (*CustomerManagedKey_KeyInfo_GcpKeyInfo) isCustomerManagedKey_KeyInfo() {} + +type DeleteCustomerManagedKeyRequest struct { + // encryption key configuration ID. + CustomerManagedKeyId *string + AccountId *string +} + +type GcpKeyInfo struct { + // Globally unique kms key resource id of the form + // projects/testProjectId/locations/us-east4/keyRings/gcpCmkKeyRing/cryptoKeys/cmk-eastus4 + KmsKeyId *string + // Globally unique service account email that has access to the KMS key. The + // service account exists within the Databricks CP project. + GcpServiceAccount *GcpServiceAccount + // When true, will not use OAuth to grant the service account + // access to the KMS key. The customer is responsible for granting access + // manually. + Manual *bool +} + +type GcpServiceAccount struct { + ServiceAccountEmail *string +} + +type GetCustomerManagedKeyRequest struct { + // encryption key configuration ID. + CustomerManagedKeyId *string + AccountId *string +} + +// The credential ID that is used to access the key vault.. +type KeyAccessConfiguration struct { + CredentialId *string +} + +type ListCustomerManagedKeyRequest struct { + AccountId *string +} + +type ListCustomerManagedKeyResponse struct { + CustomerManagedKeys []CustomerManagedKey +} diff --git a/keyconfigurations/v1/wire.go b/keyconfigurations/v1/wire.go new file mode 100755 index 0000000..d04f117 --- /dev/null +++ b/keyconfigurations/v1/wire.go @@ -0,0 +1,310 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package keyconfigurations + +import ( + "fmt" +) + +type awsKeyInfoWire struct { + KeyArn *string `json:"key_arn,omitempty"` + KeyAlias *string `json:"key_alias,omitempty"` + KeyRegion *string `json:"key_region,omitempty"` + ReuseKeyForClusterVolumes *bool `json:"reuse_key_for_cluster_volumes,omitempty"` +} + +func awsKeyInfoFromWire(w *awsKeyInfoWire) (*AwsKeyInfo, error) { + if w == nil { + return nil, nil + } + return &AwsKeyInfo{ + KeyArn: w.KeyArn, + KeyAlias: w.KeyAlias, + KeyRegion: w.KeyRegion, + ReuseKeyForClusterVolumes: w.ReuseKeyForClusterVolumes, + }, nil +} + +type azureKeyInfoWire struct { + KeyVaultUri *string `json:"key_vault_uri,omitempty"` + KeyName *string `json:"key_name,omitempty"` + Version *string `json:"version,omitempty"` + TenantId *string `json:"tenant_id,omitempty"` + DiskEncryptionSetId *string `json:"disk_encryption_set_id,omitempty"` + KeyAccessConfiguration *keyAccessConfigurationWire `json:"key_access_configuration,omitempty"` +} + +func azureKeyInfoFromWire(w *azureKeyInfoWire) (*AzureKeyInfo, error) { + if w == nil { + return nil, nil + } + keyAccessConfigurationPublicValue, err := keyAccessConfigurationFromWire(w.KeyAccessConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AzureKeyInfo.KeyAccessConfiguration", err) + } + return &AzureKeyInfo{ + KeyVaultUri: w.KeyVaultUri, + KeyName: w.KeyName, + Version: w.Version, + TenantId: w.TenantId, + DiskEncryptionSetId: w.DiskEncryptionSetId, + KeyAccessConfiguration: keyAccessConfigurationPublicValue, + }, nil +} + +type createAwsKeyInfoWire struct { + KeyArn *string `json:"key_arn,omitempty"` + KeyAlias *string `json:"key_alias,omitempty"` + KeyRegion *string `json:"key_region,omitempty"` + ReuseKeyForClusterVolumes *bool `json:"reuse_key_for_cluster_volumes,omitempty"` +} + +func createAwsKeyInfoToWire(v *CreateAwsKeyInfo) (*createAwsKeyInfoWire, error) { + if v == nil { + return nil, nil + } + return &createAwsKeyInfoWire{ + KeyArn: v.KeyArn, + KeyAlias: v.KeyAlias, + KeyRegion: v.KeyRegion, + ReuseKeyForClusterVolumes: v.ReuseKeyForClusterVolumes, + }, nil +} + +type createAzureKeyInfoWire struct { + KeyVaultUri *string `json:"key_vault_uri,omitempty"` + KeyName *string `json:"key_name,omitempty"` + Version *string `json:"version,omitempty"` + TenantId *string `json:"tenant_id,omitempty"` + DiskEncryptionSetId *string `json:"disk_encryption_set_id,omitempty"` + KeyAccessConfiguration *keyAccessConfigurationWire `json:"key_access_configuration,omitempty"` +} + +func createAzureKeyInfoToWire(v *CreateAzureKeyInfo) (*createAzureKeyInfoWire, error) { + if v == nil { + return nil, nil + } + keyAccessConfigurationWireValue, err := keyAccessConfigurationToWire(v.KeyAccessConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAzureKeyInfo.KeyAccessConfiguration", err) + } + return &createAzureKeyInfoWire{ + KeyVaultUri: v.KeyVaultUri, + KeyName: v.KeyName, + Version: v.Version, + TenantId: v.TenantId, + DiskEncryptionSetId: v.DiskEncryptionSetId, + KeyAccessConfiguration: keyAccessConfigurationWireValue, + }, nil +} + +type createCustomerManagedKeyRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + AwsKeyInfo *createAwsKeyInfoWire `json:"aws_key_info,omitempty"` + GcpKeyInfo *createGcpKeyInfoWire `json:"gcp_key_info,omitempty"` + AzureKeyInfo *createAzureKeyInfoWire `json:"azure_key_info,omitempty"` + UseCases []CmkUseCase `json:"use_cases,omitempty"` +} + +func createCustomerManagedKeyRequestToWire(v *CreateCustomerManagedKeyRequest) (*createCustomerManagedKeyRequestWire, error) { + if v == nil { + return nil, nil + } + var keyInfoAwsKeyInfoWire *createAwsKeyInfoWire + var keyInfoGcpKeyInfoWire *createGcpKeyInfoWire + var keyInfoAzureKeyInfoWire *createAzureKeyInfoWire + switch value := v.KeyInfo.(type) { + case nil: + case *CreateCustomerManagedKeyRequest_KeyInfo_AwsKeyInfo: + if value != nil { + keyInfoAwsKeyInfoConverted, err := createAwsKeyInfoToWire(&value.AwsKeyInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCustomerManagedKeyRequest.KeyInfo.AwsKeyInfo", err) + } + keyInfoAwsKeyInfoWire = keyInfoAwsKeyInfoConverted + } + case *CreateCustomerManagedKeyRequest_KeyInfo_GcpKeyInfo: + if value != nil { + keyInfoGcpKeyInfoConverted, err := createGcpKeyInfoToWire(&value.GcpKeyInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCustomerManagedKeyRequest.KeyInfo.GcpKeyInfo", err) + } + keyInfoGcpKeyInfoWire = keyInfoGcpKeyInfoConverted + } + case *CreateCustomerManagedKeyRequest_KeyInfo_AzureKeyInfo: + if value != nil { + keyInfoAzureKeyInfoConverted, err := createAzureKeyInfoToWire(&value.AzureKeyInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCustomerManagedKeyRequest.KeyInfo.AzureKeyInfo", err) + } + keyInfoAzureKeyInfoWire = keyInfoAzureKeyInfoConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreateCustomerManagedKeyRequest.KeyInfo", value) + } + return &createCustomerManagedKeyRequestWire{ + AccountId: v.AccountId, + AwsKeyInfo: keyInfoAwsKeyInfoWire, + GcpKeyInfo: keyInfoGcpKeyInfoWire, + AzureKeyInfo: keyInfoAzureKeyInfoWire, + UseCases: v.UseCases, + }, nil +} + +type createGcpKeyInfoWire struct { + KmsKeyId *string `json:"kms_key_id,omitempty"` + GcpServiceAccount *gcpServiceAccountWire `json:"gcp_service_account,omitempty"` + Manual *bool `json:"manual,omitempty"` +} + +func createGcpKeyInfoToWire(v *CreateGcpKeyInfo) (*createGcpKeyInfoWire, error) { + if v == nil { + return nil, nil + } + gcpServiceAccountWireValue, err := gcpServiceAccountToWire(v.GcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateGcpKeyInfo.GcpServiceAccount", err) + } + return &createGcpKeyInfoWire{ + KmsKeyId: v.KmsKeyId, + GcpServiceAccount: gcpServiceAccountWireValue, + Manual: v.Manual, + }, nil +} + +type customerManagedKeyWire struct { + CustomerManagedKeyId *string `json:"customer_managed_key_id,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + AccountId *string `json:"account_id,omitempty"` + AwsKeyInfo *awsKeyInfoWire `json:"aws_key_info,omitempty"` + AzureKeyInfo *azureKeyInfoWire `json:"azure_key_info,omitempty"` + GcpKeyInfo *gcpKeyInfoWire `json:"gcp_key_info,omitempty"` + UseCases []CmkUseCase `json:"use_cases,omitempty"` +} + +func customerManagedKeyFromWire(w *customerManagedKeyWire) (*CustomerManagedKey, error) { + if w == nil { + return nil, nil + } + keyInfoMembers := 0 + if w.AwsKeyInfo != nil { + keyInfoMembers++ + } + if w.AzureKeyInfo != nil { + keyInfoMembers++ + } + if w.GcpKeyInfo != nil { + keyInfoMembers++ + } + if keyInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "CustomerManagedKey.KeyInfo") + } + var keyInfoSelection isCustomerManagedKey_KeyInfo + switch { + case w.AwsKeyInfo != nil: + keyInfoAwsKeyInfoConverted, err := awsKeyInfoFromWire(w.AwsKeyInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerManagedKey.KeyInfo.AwsKeyInfo", err) + } + keyInfoSelection = &CustomerManagedKey_KeyInfo_AwsKeyInfo{AwsKeyInfo: *keyInfoAwsKeyInfoConverted} + case w.AzureKeyInfo != nil: + keyInfoAzureKeyInfoConverted, err := azureKeyInfoFromWire(w.AzureKeyInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerManagedKey.KeyInfo.AzureKeyInfo", err) + } + keyInfoSelection = &CustomerManagedKey_KeyInfo_AzureKeyInfo{AzureKeyInfo: *keyInfoAzureKeyInfoConverted} + case w.GcpKeyInfo != nil: + keyInfoGcpKeyInfoConverted, err := gcpKeyInfoFromWire(w.GcpKeyInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerManagedKey.KeyInfo.GcpKeyInfo", err) + } + keyInfoSelection = &CustomerManagedKey_KeyInfo_GcpKeyInfo{GcpKeyInfo: *keyInfoGcpKeyInfoConverted} + } + return &CustomerManagedKey{ + CustomerManagedKeyId: w.CustomerManagedKeyId, + CreationTime: w.CreationTime, + AccountId: w.AccountId, + UseCases: w.UseCases, + KeyInfo: keyInfoSelection, + }, nil +} + +type gcpKeyInfoWire struct { + KmsKeyId *string `json:"kms_key_id,omitempty"` + GcpServiceAccount *gcpServiceAccountWire `json:"gcp_service_account,omitempty"` + Manual *bool `json:"manual,omitempty"` +} + +func gcpKeyInfoFromWire(w *gcpKeyInfoWire) (*GcpKeyInfo, error) { + if w == nil { + return nil, nil + } + gcpServiceAccountPublicValue, err := gcpServiceAccountFromWire(w.GcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GcpKeyInfo.GcpServiceAccount", err) + } + return &GcpKeyInfo{ + KmsKeyId: w.KmsKeyId, + GcpServiceAccount: gcpServiceAccountPublicValue, + Manual: w.Manual, + }, nil +} + +type gcpServiceAccountWire struct { + ServiceAccountEmail *string `json:"service_account_email,omitempty"` +} + +func gcpServiceAccountToWire(v *GcpServiceAccount) (*gcpServiceAccountWire, error) { + if v == nil { + return nil, nil + } + return &gcpServiceAccountWire{ + ServiceAccountEmail: v.ServiceAccountEmail, + }, nil +} + +func gcpServiceAccountFromWire(w *gcpServiceAccountWire) (*GcpServiceAccount, error) { + if w == nil { + return nil, nil + } + return &GcpServiceAccount{ + ServiceAccountEmail: w.ServiceAccountEmail, + }, nil +} + +type keyAccessConfigurationWire struct { + CredentialId *string `json:"credential_id,omitempty"` +} + +func keyAccessConfigurationToWire(v *KeyAccessConfiguration) (*keyAccessConfigurationWire, error) { + if v == nil { + return nil, nil + } + return &keyAccessConfigurationWire{ + CredentialId: v.CredentialId, + }, nil +} + +func keyAccessConfigurationFromWire(w *keyAccessConfigurationWire) (*KeyAccessConfiguration, error) { + if w == nil { + return nil, nil + } + return &KeyAccessConfiguration{ + CredentialId: w.CredentialId, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/knowledgeassistants/.package.json b/knowledgeassistants/.package.json new file mode 100644 index 0000000..bf2b1d1 --- /dev/null +++ b/knowledgeassistants/.package.json @@ -0,0 +1,3 @@ +{ + "package": "knowledgeassistants" +} diff --git a/knowledgeassistants/CHANGELOG.md b/knowledgeassistants/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/knowledgeassistants/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/knowledgeassistants/README.md b/knowledgeassistants/README.md new file mode 100644 index 0000000..9ca581e --- /dev/null +++ b/knowledgeassistants/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/knowledgeassistants + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/knowledgeassistants@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/knowledgeassistants/v1" + +client, err := knowledgeassistants.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/knowledgeassistants/go.mod b/knowledgeassistants/go.mod new file mode 100644 index 0000000..18fc919 --- /dev/null +++ b/knowledgeassistants/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/knowledgeassistants + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/knowledgeassistants/internal/version.go b/knowledgeassistants/internal/version.go new file mode 100644 index 0000000..609c1b3 --- /dev/null +++ b/knowledgeassistants/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-knowledgeassistants" + +const Version = "0.0.1-dev.1" diff --git a/knowledgeassistants/v1/client.go b/knowledgeassistants/v1/client.go new file mode 100755 index 0000000..7484144 --- /dev/null +++ b/knowledgeassistants/v1/client.go @@ -0,0 +1,1233 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package knowledgeassistants + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/knowledgeassistants/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates an example for a Knowledge Assistant. +func (c *internalClient) CreateExample(ctx context.Context, req *CreateExampleRequest, opts ...call.Option) (*Example, error) { + wireReq, err := createExampleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Example) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Parent) + pb.literal("/examples") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Example + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp exampleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = exampleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a Knowledge Assistant. +func (c *internalClient) CreateKnowledgeAssistant(ctx context.Context, req *CreateKnowledgeAssistantRequest, opts ...call.Option) (*KnowledgeAssistant, error) { + wireReq, err := createKnowledgeAssistantRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.KnowledgeAssistant) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/knowledge-assistants" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *KnowledgeAssistant + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp knowledgeAssistantWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = knowledgeAssistantFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a Knowledge Source under a Knowledge Assistant. +func (c *internalClient) CreateKnowledgeSource(ctx context.Context, req *CreateKnowledgeSourceRequest, opts ...call.Option) (*KnowledgeSource, error) { + wireReq, err := createKnowledgeSourceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.KnowledgeSource) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Parent) + pb.literal("/knowledge-sources") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *KnowledgeSource + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp knowledgeSourceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = knowledgeSourceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes an example from a Knowledge Assistant. +func (c *internalClient) DeleteExample(ctx context.Context, req *DeleteExampleRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Deletes a Knowledge Assistant. +func (c *internalClient) DeleteKnowledgeAssistant(ctx context.Context, req *DeleteKnowledgeAssistantRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Deletes a Knowledge Source. +func (c *internalClient) DeleteKnowledgeSource(ctx context.Context, req *DeleteKnowledgeSourceRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets an example from a Knowledge Assistant. +func (c *internalClient) GetExample(ctx context.Context, req *GetExampleRequest, opts ...call.Option) (*Example, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Example + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp exampleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = exampleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a Knowledge Assistant. +func (c *internalClient) GetKnowledgeAssistant(ctx context.Context, req *GetKnowledgeAssistantRequest, opts ...call.Option) (*KnowledgeAssistant, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *KnowledgeAssistant + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp knowledgeAssistantWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = knowledgeAssistantFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a Knowledge Source. +func (c *internalClient) GetKnowledgeSource(ctx context.Context, req *GetKnowledgeSourceRequest, opts ...call.Option) (*KnowledgeSource, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *KnowledgeSource + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp knowledgeSourceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = knowledgeSourceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists examples under a Knowledge Assistant. +func (c *internalClient) ListExamples(ctx context.Context, req *ListExamplesRequest, opts ...call.Option) (*ListExamplesResponse, error) { + wireReq, err := listExamplesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Parent) + pb.literal("/examples") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListExamplesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listExamplesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listExamplesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListExamplesIter returns an iterator that iterates +// over the results of ListExamples. +// +// For example: +// +// for item, err := range c.ListExamplesIter(ctx, &ListExamplesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListExamples call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListExamples directly. +func (c *internalClient) ListExamplesIter(ctx context.Context, req *ListExamplesRequest, opts ...call.Option) iter.Seq2[*Example, error] { + return func(yield func(*Example, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListExamplesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListExamples(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Examples { + if !yield(&resp.Examples[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List Knowledge Assistants +func (c *internalClient) ListKnowledgeAssistants(ctx context.Context, req *ListKnowledgeAssistantsRequest, opts ...call.Option) (*ListKnowledgeAssistantsResponse, error) { + wireReq, err := listKnowledgeAssistantsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/knowledge-assistants" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListKnowledgeAssistantsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listKnowledgeAssistantsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listKnowledgeAssistantsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListKnowledgeAssistantsIter returns an iterator that iterates +// over the results of ListKnowledgeAssistants. +// +// For example: +// +// for item, err := range c.ListKnowledgeAssistantsIter(ctx, &ListKnowledgeAssistantsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListKnowledgeAssistants call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListKnowledgeAssistants directly. +func (c *internalClient) ListKnowledgeAssistantsIter(ctx context.Context, req *ListKnowledgeAssistantsRequest, opts ...call.Option) iter.Seq2[*KnowledgeAssistant, error] { + return func(yield func(*KnowledgeAssistant, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListKnowledgeAssistantsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListKnowledgeAssistants(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.KnowledgeAssistants { + if !yield(&resp.KnowledgeAssistants[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Lists Knowledge Sources under a Knowledge Assistant. +func (c *internalClient) ListKnowledgeSources(ctx context.Context, req *ListKnowledgeSourcesRequest, opts ...call.Option) (*ListKnowledgeSourcesResponse, error) { + wireReq, err := listKnowledgeSourcesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Parent) + pb.literal("/knowledge-sources") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListKnowledgeSourcesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listKnowledgeSourcesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listKnowledgeSourcesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListKnowledgeSourcesIter returns an iterator that iterates +// over the results of ListKnowledgeSources. +// +// For example: +// +// for item, err := range c.ListKnowledgeSourcesIter(ctx, &ListKnowledgeSourcesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListKnowledgeSources call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListKnowledgeSources directly. +func (c *internalClient) ListKnowledgeSourcesIter(ctx context.Context, req *ListKnowledgeSourcesRequest, opts ...call.Option) iter.Seq2[*KnowledgeSource, error] { + return func(yield func(*KnowledgeSource, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListKnowledgeSourcesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListKnowledgeSources(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.KnowledgeSources { + if !yield(&resp.KnowledgeSources[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Sync all non-index Knowledge Sources for a Knowledge Assistant (index sources +// do not require sync) +func (c *internalClient) SyncKnowledgeSources(ctx context.Context, req *SyncKnowledgeSourcesRequest, opts ...call.Option) error { + wireReq, err := syncKnowledgeSourcesRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + pb.literal("/knowledge-sources:sync") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Updates an example in a Knowledge Assistant. +func (c *internalClient) UpdateExample(ctx context.Context, req *UpdateExampleRequest, opts ...call.Option) (*Example, error) { + wireReq, err := updateExampleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Example) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Example + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp exampleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = exampleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a Knowledge Assistant. +func (c *internalClient) UpdateKnowledgeAssistant(ctx context.Context, req *UpdateKnowledgeAssistantRequest, opts ...call.Option) (*KnowledgeAssistant, error) { + wireReq, err := updateKnowledgeAssistantRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.KnowledgeAssistant) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.KnowledgeAssistant.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *KnowledgeAssistant + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp knowledgeAssistantWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = knowledgeAssistantFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a Knowledge Source. +func (c *internalClient) UpdateKnowledgeSource(ctx context.Context, req *UpdateKnowledgeSourceRequest, opts ...call.Option) (*KnowledgeSource, error) { + wireReq, err := updateKnowledgeSourceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.KnowledgeSource) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *KnowledgeSource + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp knowledgeSourceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = knowledgeSourceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/knowledgeassistants/v1/genhelper.go b/knowledgeassistants/v1/genhelper.go new file mode 100755 index 0000000..70db819 --- /dev/null +++ b/knowledgeassistants/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package knowledgeassistants + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/knowledgeassistants/v1/model.go b/knowledgeassistants/v1/model.go new file mode 100755 index 0000000..fa7f971 --- /dev/null +++ b/knowledgeassistants/v1/model.go @@ -0,0 +1,326 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package knowledgeassistants + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type KnowledgeAssistant_State string + +const ( + KnowledgeAssistant_State_Unspecified KnowledgeAssistant_State = "" + KnowledgeAssistant_State_Creating KnowledgeAssistant_State = "CREATING" + KnowledgeAssistant_State_Active KnowledgeAssistant_State = "ACTIVE" + KnowledgeAssistant_State_Failed KnowledgeAssistant_State = "FAILED" +) + +type KnowledgeSource_State string + +const ( + KnowledgeSource_State_Unspecified KnowledgeSource_State = "" + KnowledgeSource_State_Updating KnowledgeSource_State = "UPDATING" + KnowledgeSource_State_Updated KnowledgeSource_State = "UPDATED" + KnowledgeSource_State_FailedUpdate KnowledgeSource_State = "FAILED_UPDATE" +) + +// Create an example.. +type CreateExampleRequest struct { + // Parent resource where this example will be created. Format: + // knowledge-assistants/{knowledge_assistant_id} + Parent *string + // The example to create under the parent Knowledge Assistant. + Example *Example +} + +type CreateKnowledgeAssistantRequest struct { + // The Knowledge Assistant to create. + KnowledgeAssistant *KnowledgeAssistant +} + +type CreateKnowledgeSourceRequest struct { + // Parent resource where this source will be created. Format: + // knowledge-assistants/{knowledge_assistant_id} + Parent *string + KnowledgeSource *KnowledgeSource +} + +// Delete an example.. +type DeleteExampleRequest struct { + // The resource name of the example to delete. Format: + // knowledge-assistants/{knowledge_assistant_id}/examples/{example_id} + Name *string +} + +// A request to delete a Knowledge Assistant.. +type DeleteKnowledgeAssistantRequest struct { + // The resource name of the knowledge assistant to be deleted. Format: + // knowledge-assistants/{knowledge_assistant_id} + Name *string +} + +type DeleteKnowledgeSourceRequest struct { + // The resource name of the Knowledge Source to delete. Format: + // knowledge-assistants/{knowledge_assistant_id}/knowledge-sources/{knowledge_source_id} + Name *string +} + +// An example associated with a Knowledge Assistant. Contains a question and +// guidelines for how the assistant should respond.. +type Example struct { + // Full resource name: + // knowledge-assistants/{knowledge_assistant_id}/examples/{example_id} + Name *string `fieldmask:"name"` + // The example question. + Question *string `fieldmask:"question"` + // Guidelines for answering the question. Optional — examples may be created + // with just a question; the front-end form does not require guidelines. + Guidelines []string `fieldmask:"guidelines"` + // The universally unique identifier (UUID) of the example. + ExampleId *string `fieldmask:"example_id"` + // Timestamp when this example was created. + CreateTime *types.Time `fieldmask:"create_time"` + // Timestamp when this example was last updated. + UpdateTime *types.Time `fieldmask:"update_time"` +} + +// FileTableSpec specifies a file table source configuration.. +type FileTableSpec struct { + // Full UC name of the table, in the format of {CATALOG}.{SCHEMA}.{TABLE_NAME}. + TableName *string `fieldmask:"table_name"` + // The name of the column containing BINARY file content to be indexed. + FileCol *string `fieldmask:"file_col"` +} + +// FilesSpec specifies a files source configuration.. +type FilesSpec struct { + // A UC volume path that includes a list of files. + Path *string `fieldmask:"path"` +} + +// Get an example.. +type GetExampleRequest struct { + // The resource name of the example. Format: + // knowledge-assistants/{knowledge_assistant_id}/examples/{example_id} + Name *string +} + +// A request to retrieve a Knowledge Assistant.. +type GetKnowledgeAssistantRequest struct { + // The resource name of the knowledge assistant. Format: + // knowledge-assistants/{knowledge_assistant_id} + Name *string +} + +type GetKnowledgeSourceRequest struct { + // The resource name of the Knowledge Source. Format: + // knowledge-assistants/{knowledge_assistant_id}/knowledge-sources/{knowledge_source_id} + Name *string +} + +// IndexSpec specifies a vector search index source configuration.. +type IndexSpec struct { + // Full UC name of the vector search index, in the format of + // {CATALOG}.{SCHEMA}.{INDEX_NAME}. + IndexName *string `fieldmask:"index_name"` + // The column that includes the document text for retrieval. + TextCol *string `fieldmask:"text_col"` + // The column that specifies a link or reference to where the information came + // from. + DocUriCol *string `fieldmask:"doc_uri_col"` +} + +// Entity message that represents a knowledge assistant. Note: REQUIRED +// annotations below represent create-time requirements. For updates, required +// fields are determined by the update mask.. +type KnowledgeAssistant struct { + // The resource name of the Knowledge Assistant. Format: + // knowledge-assistants/{knowledge_assistant_id} + Name *string `fieldmask:"name"` + // State of the Knowledge Assistant. Not returned in List responses. + State KnowledgeAssistant_State `fieldmask:"state"` + // Deprecated: use knowledge_assistant_id instead. + Id *string `fieldmask:"id"` + // The display name of the Knowledge Assistant, unique at workspace level. + // Required when creating a Knowledge Assistant. When updating a Knowledge + // Assistant, optional unless included in update_mask. + DisplayName *string `fieldmask:"display_name"` + // Description of what this agent can do (user-facing). Required when creating a + // Knowledge Assistant. When updating a Knowledge Assistant, optional unless + // included in update_mask. + Description *string `fieldmask:"description"` + // Additional global instructions on how the agent should generate answers. + // Optional on create and update. When updating a Knowledge Assistant, include + // this field in update_mask to modify it. + Instructions *string `fieldmask:"instructions"` + // The creator of the Knowledge Assistant. + Creator *string `fieldmask:"creator"` + // Creation timestamp. + CreateTime *types.Time `fieldmask:"create_time"` + // The name of the knowledge assistant agent endpoint. + EndpointName *string `fieldmask:"endpoint_name"` + // The MLflow experiment ID. + ExperimentId *string `fieldmask:"experiment_id"` + // Error details when the Knowledge Assistant is in FAILED state. + ErrorInfo *string `fieldmask:"error_info"` +} + +// KnowledgeSource represents a source of knowledge for the KnowledgeAssistant. +// Used in create/update requests and returned in Get/List responses. Note: +// REQUIRED annotations below represent create-time requirements. For updates, +// required fields are determined by the update mask.. +type KnowledgeSource struct { + // Full resource name: + // knowledge-assistants/{knowledge_assistant_id}/knowledge-sources/{knowledge_source_id} + Name *string `fieldmask:"name"` + // Human-readable display name of the knowledge source. Required when creating a + // Knowledge Source. When updating a Knowledge Source, optional unless included + // in update_mask. + DisplayName *string `fieldmask:"display_name"` + // Description of the knowledge source. Required when creating a Knowledge + // Source. When updating a Knowledge Source, optional unless included in + // update_mask. + Description *string `fieldmask:"description"` + // The type of the source: "index", "files", or "file_table". Required when + // creating a Knowledge Source. When updating a Knowledge Source, this field is + // ignored. + SourceType *string `fieldmask:"source_type"` + // Specification for the knowledge source type. + Spec isKnowledgeSource_Spec + State KnowledgeSource_State `fieldmask:"state"` + Id *string `fieldmask:"id"` + // Timestamp representing the cutoff before which content in this knowledge + // source is being ingested. + KnowledgeCutoffTime *types.Time `fieldmask:"knowledge_cutoff_time"` + // Timestamp when this knowledge source was created. + CreateTime *types.Time `fieldmask:"create_time"` + _ [0]knowledgeSourceSpecFieldMaskMetadata `fieldmask_oneof:"Spec"` +} + +type isKnowledgeSource_Spec interface { + isKnowledgeSource_Spec() +} + +// KnowledgeSource_Spec_Index selects Index for KnowledgeSource.Spec. +type KnowledgeSource_Spec_Index struct { + Index IndexSpec `fieldmask:"index"` +} + +func (*KnowledgeSource_Spec_Index) isKnowledgeSource_Spec() {} + +// KnowledgeSource_Spec_Files selects Files for KnowledgeSource.Spec. +type KnowledgeSource_Spec_Files struct { + Files FilesSpec `fieldmask:"files"` +} + +func (*KnowledgeSource_Spec_Files) isKnowledgeSource_Spec() {} + +// KnowledgeSource_Spec_FileTable selects FileTable for KnowledgeSource.Spec. +type KnowledgeSource_Spec_FileTable struct { + FileTable FileTableSpec `fieldmask:"file_table"` +} + +func (*KnowledgeSource_Spec_FileTable) isKnowledgeSource_Spec() {} + +type knowledgeSourceSpecFieldMaskMetadata struct { + *KnowledgeSource_Spec_Index + *KnowledgeSource_Spec_Files + *KnowledgeSource_Spec_FileTable +} + +// List examples.. +type ListExamplesRequest struct { + // Parent resource to list from. Format: + // knowledge-assistants/{knowledge_assistant_id} + Parent *string + // The maximum number of examples to return. If unspecified, at most 100 + // examples will be returned. The maximum value is 100; values above 100 will be + // coerced to 100. + PageSize *int + // A page token, received from a previous `ListExamples` call. Provide this to + // retrieve the subsequent page. If unspecified, the first page will be + // returned. + PageToken *string +} + +// A list of Knowledge Assistant examples.. +type ListExamplesResponse struct { + Examples []Example + NextPageToken *string +} + +// A request to list Knowledge Assistants.. +type ListKnowledgeAssistantsRequest struct { + // The maximum number of knowledge assistants to return. If unspecified, at most + // 100 knowledge assistants will be returned. The maximum value is 100; values + // above 100 will be coerced to 100. + PageSize *int + // A page token, received from a previous `ListKnowledgeAssistants` call. + // Provide this to retrieve the subsequent page. If unspecified, the first page + // will be returned. + PageToken *string +} + +// A list of Knowledge Assistants.. +type ListKnowledgeAssistantsResponse struct { + KnowledgeAssistants []KnowledgeAssistant + // A token that can be sent as `page_token` to retrieve the next page. If this + // field is omitted, there are no subsequent pages. + NextPageToken *string +} + +type ListKnowledgeSourcesRequest struct { + // Parent resource to list from. Format: + // knowledge-assistants/{knowledge_assistant_id} + Parent *string + PageSize *int + PageToken *string +} + +type ListKnowledgeSourcesResponse struct { + KnowledgeSources []KnowledgeSource + NextPageToken *string +} + +type SyncKnowledgeSourcesRequest struct { + // The resource name of the Knowledge Assistant. Format: + // knowledge-assistants/{knowledge_assistant_id} + Name *string +} + +// Update an example.. +type UpdateExampleRequest struct { + // The resource name of the example to update. Format: + // knowledge-assistants/{knowledge_assistant_id}/examples/{example_id} + Name *string + Example *Example + // Comma-delimited list of fields to update on the example. Allowed values: + // `question`, `guidelines`. Examples: - `question` - `question,guidelines` + UpdateMask *types.FieldMask[Example] +} + +type UpdateKnowledgeAssistantRequest struct { + // The Knowledge Assistant update payload. Only fields listed in update_mask are + // updated. REQUIRED annotations on Knowledge Assistant fields describe + // create-time requirements and do not mean all those fields are required for + // update. + KnowledgeAssistant *KnowledgeAssistant + // Comma-delimited list of fields to update on the Knowledge Assistant. Allowed + // values: `display_name`, `description`, `instructions`. Examples: - + // `display_name` - `description,instructions` + UpdateMask *types.FieldMask[KnowledgeAssistant] +} + +type UpdateKnowledgeSourceRequest struct { + // The resource name of the Knowledge Source to update. Format: + // knowledge-assistants/{knowledge_assistant_id}/knowledge-sources/{knowledge_source_id} + Name *string + // The Knowledge Source update payload. Only fields listed in update_mask are + // updated. REQUIRED annotations on Knowledge Source fields describe create-time + // requirements and do not mean all those fields are required for update. + KnowledgeSource *KnowledgeSource + // Comma-delimited list of fields to update on the Knowledge Source. Allowed + // values: `display_name`, `description`. Examples: - `display_name` - + // `display_name,description` + UpdateMask *types.FieldMask[KnowledgeSource] +} diff --git a/knowledgeassistants/v1/wire.go b/knowledgeassistants/v1/wire.go new file mode 100755 index 0000000..e4c990e --- /dev/null +++ b/knowledgeassistants/v1/wire.go @@ -0,0 +1,547 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package knowledgeassistants + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createExampleRequestWire struct { + Parent *string `json:"parent,omitempty"` + Example *exampleWire `json:"example,omitempty"` +} + +func createExampleRequestToWire(v *CreateExampleRequest) (*createExampleRequestWire, error) { + if v == nil { + return nil, nil + } + exampleWireValue, err := exampleToWire(v.Example) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExampleRequest.Example", err) + } + return &createExampleRequestWire{ + Parent: v.Parent, + Example: exampleWireValue, + }, nil +} + +type createKnowledgeAssistantRequestWire struct { + KnowledgeAssistant *knowledgeAssistantWire `json:"knowledge_assistant,omitempty"` +} + +func createKnowledgeAssistantRequestToWire(v *CreateKnowledgeAssistantRequest) (*createKnowledgeAssistantRequestWire, error) { + if v == nil { + return nil, nil + } + knowledgeAssistantWireValue, err := knowledgeAssistantToWire(v.KnowledgeAssistant) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateKnowledgeAssistantRequest.KnowledgeAssistant", err) + } + return &createKnowledgeAssistantRequestWire{ + KnowledgeAssistant: knowledgeAssistantWireValue, + }, nil +} + +type createKnowledgeSourceRequestWire struct { + Parent *string `json:"parent,omitempty"` + KnowledgeSource *knowledgeSourceWire `json:"knowledge_source,omitempty"` +} + +func createKnowledgeSourceRequestToWire(v *CreateKnowledgeSourceRequest) (*createKnowledgeSourceRequestWire, error) { + if v == nil { + return nil, nil + } + knowledgeSourceWireValue, err := knowledgeSourceToWire(v.KnowledgeSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateKnowledgeSourceRequest.KnowledgeSource", err) + } + return &createKnowledgeSourceRequestWire{ + Parent: v.Parent, + KnowledgeSource: knowledgeSourceWireValue, + }, nil +} + +type exampleWire struct { + Name *string `json:"name,omitempty"` + Question *string `json:"question,omitempty"` + Guidelines []string `json:"guidelines,omitempty"` + ExampleId *string `json:"example_id,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` +} + +func exampleToWire(v *Example) (*exampleWire, error) { + if v == nil { + return nil, nil + } + return &exampleWire{ + Name: v.Name, + Question: v.Question, + Guidelines: v.Guidelines, + ExampleId: v.ExampleId, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + }, nil +} + +func exampleFromWire(w *exampleWire) (*Example, error) { + if w == nil { + return nil, nil + } + return &Example{ + Name: w.Name, + Question: w.Question, + Guidelines: w.Guidelines, + ExampleId: w.ExampleId, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + }, nil +} + +type fileTableSpecWire struct { + TableName *string `json:"table_name,omitempty"` + FileCol *string `json:"file_col,omitempty"` +} + +func fileTableSpecToWire(v *FileTableSpec) (*fileTableSpecWire, error) { + if v == nil { + return nil, nil + } + return &fileTableSpecWire{ + TableName: v.TableName, + FileCol: v.FileCol, + }, nil +} + +func fileTableSpecFromWire(w *fileTableSpecWire) (*FileTableSpec, error) { + if w == nil { + return nil, nil + } + return &FileTableSpec{ + TableName: w.TableName, + FileCol: w.FileCol, + }, nil +} + +type filesSpecWire struct { + Path *string `json:"path,omitempty"` +} + +func filesSpecToWire(v *FilesSpec) (*filesSpecWire, error) { + if v == nil { + return nil, nil + } + return &filesSpecWire{ + Path: v.Path, + }, nil +} + +func filesSpecFromWire(w *filesSpecWire) (*FilesSpec, error) { + if w == nil { + return nil, nil + } + return &FilesSpec{ + Path: w.Path, + }, nil +} + +type indexSpecWire struct { + IndexName *string `json:"index_name,omitempty"` + TextCol *string `json:"text_col,omitempty"` + DocUriCol *string `json:"doc_uri_col,omitempty"` +} + +func indexSpecToWire(v *IndexSpec) (*indexSpecWire, error) { + if v == nil { + return nil, nil + } + return &indexSpecWire{ + IndexName: v.IndexName, + TextCol: v.TextCol, + DocUriCol: v.DocUriCol, + }, nil +} + +func indexSpecFromWire(w *indexSpecWire) (*IndexSpec, error) { + if w == nil { + return nil, nil + } + return &IndexSpec{ + IndexName: w.IndexName, + TextCol: w.TextCol, + DocUriCol: w.DocUriCol, + }, nil +} + +type knowledgeAssistantWire struct { + Name *string `json:"name,omitempty"` + State KnowledgeAssistant_State `json:"state,omitempty"` + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Description *string `json:"description,omitempty"` + Instructions *string `json:"instructions,omitempty"` + Creator *string `json:"creator,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + ExperimentId *string `json:"experiment_id,omitempty"` + ErrorInfo *string `json:"error_info,omitempty"` +} + +func knowledgeAssistantToWire(v *KnowledgeAssistant) (*knowledgeAssistantWire, error) { + if v == nil { + return nil, nil + } + return &knowledgeAssistantWire{ + Name: v.Name, + State: v.State, + Id: v.Id, + DisplayName: v.DisplayName, + Description: v.Description, + Instructions: v.Instructions, + Creator: v.Creator, + CreateTime: v.CreateTime, + EndpointName: v.EndpointName, + ExperimentId: v.ExperimentId, + ErrorInfo: v.ErrorInfo, + }, nil +} + +func knowledgeAssistantFromWire(w *knowledgeAssistantWire) (*KnowledgeAssistant, error) { + if w == nil { + return nil, nil + } + return &KnowledgeAssistant{ + Name: w.Name, + State: w.State, + Id: w.Id, + DisplayName: w.DisplayName, + Description: w.Description, + Instructions: w.Instructions, + Creator: w.Creator, + CreateTime: w.CreateTime, + EndpointName: w.EndpointName, + ExperimentId: w.ExperimentId, + ErrorInfo: w.ErrorInfo, + }, nil +} + +type knowledgeSourceWire struct { + Name *string `json:"name,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Description *string `json:"description,omitempty"` + SourceType *string `json:"source_type,omitempty"` + Index *indexSpecWire `json:"index,omitempty"` + Files *filesSpecWire `json:"files,omitempty"` + FileTable *fileTableSpecWire `json:"file_table,omitempty"` + State KnowledgeSource_State `json:"state,omitempty"` + Id *string `json:"id,omitempty"` + KnowledgeCutoffTime *types.Time `json:"knowledge_cutoff_time,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` +} + +func knowledgeSourceToWire(v *KnowledgeSource) (*knowledgeSourceWire, error) { + if v == nil { + return nil, nil + } + var specIndexWire *indexSpecWire + var specFilesWire *filesSpecWire + var specFileTableWire *fileTableSpecWire + switch value := v.Spec.(type) { + case nil: + case *KnowledgeSource_Spec_Index: + if value != nil { + specIndexConverted, err := indexSpecToWire(&value.Index) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KnowledgeSource.Spec.Index", err) + } + specIndexWire = specIndexConverted + } + case *KnowledgeSource_Spec_Files: + if value != nil { + specFilesConverted, err := filesSpecToWire(&value.Files) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KnowledgeSource.Spec.Files", err) + } + specFilesWire = specFilesConverted + } + case *KnowledgeSource_Spec_FileTable: + if value != nil { + specFileTableConverted, err := fileTableSpecToWire(&value.FileTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KnowledgeSource.Spec.FileTable", err) + } + specFileTableWire = specFileTableConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "KnowledgeSource.Spec", value) + } + return &knowledgeSourceWire{ + Name: v.Name, + DisplayName: v.DisplayName, + Description: v.Description, + SourceType: v.SourceType, + Index: specIndexWire, + Files: specFilesWire, + FileTable: specFileTableWire, + State: v.State, + Id: v.Id, + KnowledgeCutoffTime: v.KnowledgeCutoffTime, + CreateTime: v.CreateTime, + }, nil +} + +func knowledgeSourceFromWire(w *knowledgeSourceWire) (*KnowledgeSource, error) { + if w == nil { + return nil, nil + } + specMembers := 0 + if w.Index != nil { + specMembers++ + } + if w.Files != nil { + specMembers++ + } + if w.FileTable != nil { + specMembers++ + } + if specMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "KnowledgeSource.Spec") + } + var specSelection isKnowledgeSource_Spec + switch { + case w.Index != nil: + specIndexConverted, err := indexSpecFromWire(w.Index) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KnowledgeSource.Spec.Index", err) + } + specSelection = &KnowledgeSource_Spec_Index{Index: *specIndexConverted} + case w.Files != nil: + specFilesConverted, err := filesSpecFromWire(w.Files) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KnowledgeSource.Spec.Files", err) + } + specSelection = &KnowledgeSource_Spec_Files{Files: *specFilesConverted} + case w.FileTable != nil: + specFileTableConverted, err := fileTableSpecFromWire(w.FileTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KnowledgeSource.Spec.FileTable", err) + } + specSelection = &KnowledgeSource_Spec_FileTable{FileTable: *specFileTableConverted} + } + return &KnowledgeSource{ + Name: w.Name, + DisplayName: w.DisplayName, + Description: w.Description, + SourceType: w.SourceType, + State: w.State, + Id: w.Id, + KnowledgeCutoffTime: w.KnowledgeCutoffTime, + CreateTime: w.CreateTime, + Spec: specSelection, + }, nil +} + +type listExamplesRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listExamplesRequestToWire(v *ListExamplesRequest) (*listExamplesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listExamplesRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listExamplesResponseWire struct { + Examples []exampleWire `json:"examples,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listExamplesResponseFromWire(w *listExamplesResponseWire) (*ListExamplesResponse, error) { + if w == nil { + return nil, nil + } + examplesPublicValue, err := convertSlice(w.Examples, exampleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListExamplesResponse.Examples", err) + } + return &ListExamplesResponse{ + Examples: examplesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listKnowledgeAssistantsRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listKnowledgeAssistantsRequestToWire(v *ListKnowledgeAssistantsRequest) (*listKnowledgeAssistantsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listKnowledgeAssistantsRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listKnowledgeAssistantsResponseWire struct { + KnowledgeAssistants []knowledgeAssistantWire `json:"knowledge_assistants,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listKnowledgeAssistantsResponseFromWire(w *listKnowledgeAssistantsResponseWire) (*ListKnowledgeAssistantsResponse, error) { + if w == nil { + return nil, nil + } + knowledgeAssistantsPublicValue, err := convertSlice(w.KnowledgeAssistants, knowledgeAssistantFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListKnowledgeAssistantsResponse.KnowledgeAssistants", err) + } + return &ListKnowledgeAssistantsResponse{ + KnowledgeAssistants: knowledgeAssistantsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listKnowledgeSourcesRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listKnowledgeSourcesRequestToWire(v *ListKnowledgeSourcesRequest) (*listKnowledgeSourcesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listKnowledgeSourcesRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listKnowledgeSourcesResponseWire struct { + KnowledgeSources []knowledgeSourceWire `json:"knowledge_sources,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listKnowledgeSourcesResponseFromWire(w *listKnowledgeSourcesResponseWire) (*ListKnowledgeSourcesResponse, error) { + if w == nil { + return nil, nil + } + knowledgeSourcesPublicValue, err := convertSlice(w.KnowledgeSources, knowledgeSourceFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListKnowledgeSourcesResponse.KnowledgeSources", err) + } + return &ListKnowledgeSourcesResponse{ + KnowledgeSources: knowledgeSourcesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type syncKnowledgeSourcesRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func syncKnowledgeSourcesRequestToWire(v *SyncKnowledgeSourcesRequest) (*syncKnowledgeSourcesRequestWire, error) { + if v == nil { + return nil, nil + } + return &syncKnowledgeSourcesRequestWire{ + Name: v.Name, + }, nil +} + +type updateExampleRequestWire struct { + Name *string `json:"name,omitempty"` + Example *exampleWire `json:"example,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateExampleRequestToWire(v *UpdateExampleRequest) (*updateExampleRequestWire, error) { + if v == nil { + return nil, nil + } + exampleWireValue, err := exampleToWire(v.Example) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExampleRequest.Example", err) + } + return &updateExampleRequestWire{ + Name: v.Name, + Example: exampleWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateKnowledgeAssistantRequestWire struct { + KnowledgeAssistant *knowledgeAssistantWire `json:"knowledge_assistant,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateKnowledgeAssistantRequestToWire(v *UpdateKnowledgeAssistantRequest) (*updateKnowledgeAssistantRequestWire, error) { + if v == nil { + return nil, nil + } + knowledgeAssistantWireValue, err := knowledgeAssistantToWire(v.KnowledgeAssistant) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateKnowledgeAssistantRequest.KnowledgeAssistant", err) + } + return &updateKnowledgeAssistantRequestWire{ + KnowledgeAssistant: knowledgeAssistantWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateKnowledgeSourceRequestWire struct { + Name *string `json:"name,omitempty"` + KnowledgeSource *knowledgeSourceWire `json:"knowledge_source,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateKnowledgeSourceRequestToWire(v *UpdateKnowledgeSourceRequest) (*updateKnowledgeSourceRequestWire, error) { + if v == nil { + return nil, nil + } + knowledgeSourceWireValue, err := knowledgeSourceToWire(v.KnowledgeSource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateKnowledgeSourceRequest.KnowledgeSource", err) + } + return &updateKnowledgeSourceRequestWire{ + Name: v.Name, + KnowledgeSource: knowledgeSourceWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/lakeview/.package.json b/lakeview/.package.json new file mode 100644 index 0000000..da48ca6 --- /dev/null +++ b/lakeview/.package.json @@ -0,0 +1,3 @@ +{ + "package": "lakeview" +} diff --git a/lakeview/CHANGELOG.md b/lakeview/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/lakeview/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/lakeview/README.md b/lakeview/README.md new file mode 100644 index 0000000..1a905a7 --- /dev/null +++ b/lakeview/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/lakeview + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/lakeview@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/lakeview/v1" + +client, err := lakeview.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/lakeview/go.mod b/lakeview/go.mod new file mode 100644 index 0000000..3ef74fe --- /dev/null +++ b/lakeview/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/lakeview + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/lakeview/internal/version.go b/lakeview/internal/version.go new file mode 100644 index 0000000..cc4cd89 --- /dev/null +++ b/lakeview/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-lakeview" + +const Version = "0.0.1-dev.1" diff --git a/lakeview/v1/client.go b/lakeview/v1/client.go new file mode 100755 index 0000000..d63f81e --- /dev/null +++ b/lakeview/v1/client.go @@ -0,0 +1,1542 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package lakeview + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/lakeview/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a draft dashboard. +func (c *internalClient) CreateDashboard(ctx context.Context, req *CreateDashboardRequest, opts ...call.Option) (*Dashboard, error) { + wireReq, err := createDashboardRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Dashboard) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/lakeview/dashboards" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "dataset_catalog", wireReq.DatasetCatalog); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "dataset_schema", wireReq.DatasetSchema); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Dashboard + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp dashboardWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = dashboardFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create dashboard schedule. +func (c *internalClient) CreateSchedule(ctx context.Context, req *CreateScheduleRequest, opts ...call.Option) (*Schedule, error) { + wireReq, err := createScheduleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Schedule) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.Schedule.DashboardId) + pb.literal("/schedules") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Schedule + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp scheduleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = scheduleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create schedule subscription. +func (c *internalClient) CreateSubscription(ctx context.Context, req *CreateSubscriptionRequest, opts ...call.Option) (*Subscription, error) { + wireReq, err := createSubscriptionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Subscription) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.Subscription.DashboardId) + pb.literal("/schedules/") + pb.singleSegment(*req.Subscription.ScheduleId) + pb.literal("/subscriptions") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Subscription + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp subscriptionWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = subscriptionFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete dashboard schedule. +func (c *internalClient) DeleteSchedule(ctx context.Context, req *DeleteScheduleRequest, opts ...call.Option) error { + wireReq, err := deleteScheduleRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/schedules/") + pb.singleSegment(*req.ScheduleId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Delete schedule subscription. +func (c *internalClient) DeleteSubscription(ctx context.Context, req *DeleteSubscriptionRequest, opts ...call.Option) error { + wireReq, err := deleteSubscriptionRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/schedules/") + pb.singleSegment(*req.ScheduleId) + pb.literal("/subscriptions/") + pb.singleSegment(*req.SubscriptionId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "etag", wireReq.Etag); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Get a draft dashboard. +func (c *internalClient) GetDashboard(ctx context.Context, req *GetDashboardRequest, opts ...call.Option) (*Dashboard, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Dashboard + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp dashboardWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = dashboardFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get the current published dashboard. +func (c *internalClient) GetPublishedDashboard(ctx context.Context, req *GetPublishedDashboardRequest, opts ...call.Option) (*PublishedDashboard, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/published") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PublishedDashboard + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp publishedDashboardWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = publishedDashboardFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a required authorization details and scopes of a published dashboard to +// mint an OAuth token. +func (c *internalClient) GetPublishedDashboardTokenInfo(ctx context.Context, req *GetPublishedDashboardTokenInfoRequest, opts ...call.Option) (*GetPublishedDashboardTokenInfoResponse, error) { + wireReq, err := getPublishedDashboardTokenInfoRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/published/tokeninfo") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "external_value", wireReq.ExternalValue); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "external_viewer_id", wireReq.ExternalViewerId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPublishedDashboardTokenInfoResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPublishedDashboardTokenInfoResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPublishedDashboardTokenInfoResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get dashboard schedule. +func (c *internalClient) GetSchedule(ctx context.Context, req *GetScheduleRequest, opts ...call.Option) (*Schedule, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/schedules/") + pb.singleSegment(*req.ScheduleId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Schedule + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp scheduleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = scheduleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get schedule subscription. +func (c *internalClient) GetSubscription(ctx context.Context, req *GetSubscriptionRequest, opts ...call.Option) (*Subscription, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/schedules/") + pb.singleSegment(*req.ScheduleId) + pb.literal("/subscriptions/") + pb.singleSegment(*req.SubscriptionId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Subscription + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp subscriptionWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = subscriptionFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List dashboards. +func (c *internalClient) ListDashboards(ctx context.Context, req *ListDashboardsRequest, opts ...call.Option) (*ListDashboardsResponse, error) { + wireReq, err := listDashboardsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/lakeview/dashboards" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "show_trashed", wireReq.ShowTrashed); err != nil { + return nil, err + } + if wireReq.View != "" { + if err := addQueryValue(queryParams, "view", wireReq.View); err != nil { + return nil, err + } + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListDashboardsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listDashboardsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listDashboardsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListDashboardsIter returns an iterator that iterates +// over the results of ListDashboards. +// +// For example: +// +// for item, err := range c.ListDashboardsIter(ctx, &ListDashboardsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListDashboards call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListDashboards directly. +func (c *internalClient) ListDashboardsIter(ctx context.Context, req *ListDashboardsRequest, opts ...call.Option) iter.Seq2[*Dashboard, error] { + return func(yield func(*Dashboard, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListDashboardsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListDashboards(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Dashboards { + if !yield(&resp.Dashboards[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List dashboard schedules. +func (c *internalClient) ListSchedules(ctx context.Context, req *ListSchedulesRequest, opts ...call.Option) (*ListSchedulesResponse, error) { + wireReq, err := listSchedulesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/schedules") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListSchedulesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listSchedulesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listSchedulesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListSchedulesIter returns an iterator that iterates +// over the results of ListSchedules. +// +// For example: +// +// for item, err := range c.ListSchedulesIter(ctx, &ListSchedulesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListSchedules call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListSchedules directly. +func (c *internalClient) ListSchedulesIter(ctx context.Context, req *ListSchedulesRequest, opts ...call.Option) iter.Seq2[*Schedule, error] { + return func(yield func(*Schedule, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListSchedulesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListSchedules(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Schedules { + if !yield(&resp.Schedules[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List schedule subscriptions. +func (c *internalClient) ListSubscriptions(ctx context.Context, req *ListSubscriptionsRequest, opts ...call.Option) (*ListSubscriptionsResponse, error) { + wireReq, err := listSubscriptionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/schedules/") + pb.singleSegment(*req.ScheduleId) + pb.literal("/subscriptions") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListSubscriptionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listSubscriptionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listSubscriptionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListSubscriptionsIter returns an iterator that iterates +// over the results of ListSubscriptions. +// +// For example: +// +// for item, err := range c.ListSubscriptionsIter(ctx, &ListSubscriptionsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListSubscriptions call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListSubscriptions directly. +func (c *internalClient) ListSubscriptionsIter(ctx context.Context, req *ListSubscriptionsRequest, opts ...call.Option) iter.Seq2[*Subscription, error] { + return func(yield func(*Subscription, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListSubscriptionsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListSubscriptions(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Subscriptions { + if !yield(&resp.Subscriptions[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Migrates a classic SQL dashboard to Lakeview. +func (c *internalClient) MigrateDashboard(ctx context.Context, req *MigrateDashboardRequest, opts ...call.Option) (*Dashboard, error) { + wireReq, err := migrateDashboardRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/lakeview/dashboards/migrate" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Dashboard + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp dashboardWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = dashboardFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Publish the current draft dashboard. +func (c *internalClient) PublishDashboard(ctx context.Context, req *PublishDashboardRequest, opts ...call.Option) (*PublishedDashboard, error) { + wireReq, err := publishDashboardRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/published") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PublishedDashboard + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp publishedDashboardWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = publishedDashboardFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Revert a dashboard's definition in draft mode to the last published version. +func (c *internalClient) RevertDashboard(ctx context.Context, req *RevertDashboardRequest, opts ...call.Option) (*RevertDashboardResponse, error) { + wireReq, err := revertDashboardRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/revert") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RevertDashboardResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp revertDashboardResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = revertDashboardResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Trash a dashboard. +func (c *internalClient) TrashDashboard(ctx context.Context, req *TrashDashboardRequest, opts ...call.Option) (*TrashDashboardResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TrashDashboardResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &TrashDashboardResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Unpublish the dashboard. +func (c *internalClient) UnpublishDashboard(ctx context.Context, req *UnpublishDashboardRequest, opts ...call.Option) (*UnpublishDashboardResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.DashboardId) + pb.literal("/published") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UnpublishDashboardResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UnpublishDashboardResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a draft dashboard. +func (c *internalClient) UpdateDashboard(ctx context.Context, req *UpdateDashboardRequest, opts ...call.Option) (*Dashboard, error) { + wireReq, err := updateDashboardRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Dashboard) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.Dashboard.DashboardId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "dataset_catalog", wireReq.DatasetCatalog); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "dataset_schema", wireReq.DatasetSchema); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Dashboard + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp dashboardWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = dashboardFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update dashboard schedule. +func (c *internalClient) UpdateSchedule(ctx context.Context, req *UpdateScheduleRequest, opts ...call.Option) (*Schedule, error) { + wireReq, err := updateScheduleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Schedule) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lakeview/dashboards/") + pb.singleSegment(*req.Schedule.DashboardId) + pb.literal("/schedules/") + pb.singleSegment(*req.Schedule.ScheduleId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Schedule + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp scheduleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = scheduleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/lakeview/v1/genhelper.go b/lakeview/v1/genhelper.go new file mode 100755 index 0000000..dc476ae --- /dev/null +++ b/lakeview/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package lakeview + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/lakeview/v1/model.go b/lakeview/v1/model.go new file mode 100755 index 0000000..d34aafd --- /dev/null +++ b/lakeview/v1/model.go @@ -0,0 +1,409 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package lakeview + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type DashboardView string + +const ( + DashboardView_Unspecified DashboardView = "" + // Includes summary metadata from the dashboard. + DashboardView_DashboardViewBasic DashboardView = "DASHBOARD_VIEW_BASIC" +) + +type LifecycleState string + +const ( + LifecycleState_Unspecified LifecycleState = "" + // The dashboard is in an active state (not-trashed). + LifecycleState_Active LifecycleState = "ACTIVE" + // The dashboard is in a trashed state. + LifecycleState_Trashed LifecycleState = "TRASHED" +) + +type SchedulePauseStatus string + +const ( + SchedulePauseStatus_Unspecified SchedulePauseStatus = "" + SchedulePauseStatus_Unpaused SchedulePauseStatus = "UNPAUSED" + SchedulePauseStatus_Paused SchedulePauseStatus = "PAUSED" +) + +type AuthorizationDetails struct { + // The type of authorization downscoping policy. Ex: `workspace_rule_set` + // defines access rules for a specific workspace resource + Type *string + // The resource name to which the authorization rule applies. This field is + // specific to `workspace_rule_set` constraint. Format: + // `workspaces/{workspace_id}/dashboards/{dashboard_id}` + ResourceName *string + // The acl path of the tree store resource resource. + ResourceLegacyAclPath *string + // Represents downscoped permission rules with specific access rights. This + // field is specific to `workspace_rule_set` constraint. + GrantRules []AuthorizationDetails_GrantRule +} + +type AuthorizationDetails_GrantRule struct { + // Permission sets for dashboard are defined in + // iam-common/rbac-common/permission-sets/definitions/TreeStoreBasePermissionSets + // Ex: `permissionSets/dashboard.runner` + PermissionSet *string +} + +type CreateDashboardRequest struct { + Dashboard *Dashboard + // Sets the default catalog for all datasets in this dashboard. Does not impact + // table references that use fully qualified catalog names (ex: + // samples.nyctaxi.trips). Leave blank to keep each dataset’s existing + // configuration. + DatasetCatalog *string + // Sets the default schema for all datasets in this dashboard. Does not impact + // table references that use fully qualified schema names (ex: nyctaxi.trips). + // Leave blank to keep each dataset’s existing configuration. + DatasetSchema *string +} + +type CreateScheduleRequest struct { + // The schedule to create. A dashboard is limited to 10 schedules. + Schedule *Schedule +} + +type CreateSubscriptionRequest struct { + // The subscription to create. A schedule is limited to 100 subscriptions. + Subscription *Subscription +} + +type CronSchedule struct { + // A cron expression using quartz syntax. EX: `0 0 8 * * ?` represents everyday + // at 8am. See [Cron Trigger] for details. + // + // [Cron Trigger]: http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html + QuartzCronExpression *string + // A Java timezone id. The schedule will be resolved with respect to this + // timezone. See [Java TimeZone] for details. + // + // [Java TimeZone]: https://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html + TimezoneId *string +} + +type Dashboard struct { + // UUID identifying the dashboard. + DashboardId *string + // The display name of the dashboard. + DisplayName *string + // The workspace path of the dashboard asset, including the file name. Exported + // dashboards always have the file extension `.lvdash.json`. This field is + // excluded in List Dashboards responses. + Path *string + // The timestamp of when the dashboard was created. + CreateTime *types.Time + // The timestamp of when the dashboard was last updated by the user. This field + // is excluded in List Dashboards responses. + UpdateTime *types.Time + // The warehouse ID used to run the dashboard. + WarehouseId *string + // The etag for the dashboard. Can be optionally provided on updates to ensure + // that the dashboard has not been modified since the last read. This field is + // excluded in List Dashboards responses. + Etag *string + // The contents of the dashboard in serialized string form. This field is + // excluded in List Dashboards responses. Use the [get dashboard API] to + // retrieve an example response, which includes the `serialized_dashboard` + // field. This field provides the structure of the JSON string that represents + // the dashboard's layout and components. + // + // [get dashboard API]: https://docs.databricks.com/api/workspace/lakeview/get + SerializedDashboard *string + // The state of the dashboard resource. Used for tracking trashed status. + LifecycleState LifecycleState + // The workspace path of the folder containing the dashboard. Includes leading + // slash and no trailing slash. This field is excluded in List Dashboards + // responses. + ParentPath *string +} + +type DeleteScheduleRequest struct { + // UUID identifying the schedule. + ScheduleId *string + // UUID identifying the dashboard to which the schedule belongs. + DashboardId *string + // The etag for the schedule. Optionally, it can be provided to verify that the + // schedule has not been modified from its last retrieval. + Etag *string +} + +type DeleteSubscriptionRequest struct { + // UUID identifying the subscription. + SubscriptionId *string + // UUID identifying the schedule which the subscription belongs. + ScheduleId *string + // UUID identifying the dashboard which the subscription belongs. + DashboardId *string + // The etag for the subscription. Can be optionally provided to ensure that the + // subscription has not been modified since the last read. + Etag *string +} + +type GetDashboardRequest struct { + // UUID identifying the dashboard. + DashboardId *string +} + +type GetPublishedDashboardRequest struct { + // UUID identifying the published dashboard. + DashboardId *string +} + +type GetPublishedDashboardTokenInfoRequest struct { + // UUID identifying the published dashboard. + DashboardId *string + // Provided external value to be included in the custom claim. + ExternalValue *string + // Provided external viewer id to be included in the custom claim. + ExternalViewerId *string +} + +type GetPublishedDashboardTokenInfoResponse struct { + // Custom claim generated from external_value and external_viewer_id. Format: + // `urn:aibi:external_data:::` + CustomClaim *string + // Scope defining access permissions. + Scope *string + // Authorization constraints for accessing the published dashboard. Currently + // includes `workspace_rule_set` and could be enriched with + // `unity_catalog_privileges` before oAuth token generation. + AuthorizationDetails []AuthorizationDetails +} + +type GetScheduleRequest struct { + // UUID identifying the schedule. + ScheduleId *string + // UUID identifying the dashboard to which the schedule belongs. + DashboardId *string +} + +type GetSubscriptionRequest struct { + // UUID identifying the subscription. + SubscriptionId *string + // UUID identifying the schedule which the subscription belongs. + ScheduleId *string + // UUID identifying the dashboard which the subscription belongs. + DashboardId *string +} + +type ListDashboardsRequest struct { + // The number of dashboards to return per page. + PageSize *int + // A page token, received from a previous `ListDashboards` call. This token can + // be used to retrieve the subsequent page. + PageToken *string + // The flag to include dashboards located in the trash. If unspecified, only + // active dashboards will be returned. + ShowTrashed *bool + // `DASHBOARD_VIEW_BASIC` only includes summary metadata from the dashboard. + View DashboardView +} + +type ListDashboardsResponse struct { + Dashboards []Dashboard + // A token, which can be sent as `page_token` to retrieve the next page. If this + // field is omitted, there are no subsequent dashboards. + NextPageToken *string +} + +type ListSchedulesRequest struct { + // UUID identifying the dashboard to which the schedules belongs. + DashboardId *string + // The number of schedules to return per page. + PageSize *int + // A page token, received from a previous `ListSchedules` call. Use this to + // retrieve the subsequent page. + PageToken *string +} + +type ListSchedulesResponse struct { + Schedules []Schedule + // A token that can be used as a `page_token` in subsequent requests to retrieve + // the next page of results. If this field is omitted, there are no subsequent + // schedules. + NextPageToken *string +} + +type ListSubscriptionsRequest struct { + // UUID identifying the dashboard which the subscriptions belongs. + DashboardId *string + // UUID identifying the schedule which the subscriptions belongs. + ScheduleId *string + // The number of subscriptions to return per page. + PageSize *int + // A page token, received from a previous `ListSubscriptions` call. Use this to + // retrieve the subsequent page. + PageToken *string +} + +type ListSubscriptionsResponse struct { + Subscriptions []Subscription + // A token that can be used as a `page_token` in subsequent requests to retrieve + // the next page of results. If this field is omitted, there are no subsequent + // subscriptions. + NextPageToken *string +} + +type MigrateDashboardRequest struct { + // UUID of the dashboard to be migrated. + SourceDashboardId *string + // Display name for the new Lakeview dashboard. + DisplayName *string + // The workspace path of the folder to contain the migrated Lakeview dashboard. + ParentPath *string + // Flag to indicate if mustache parameter syntax ({{ param }}) should be + // auto-updated to named syntax (:param) when converting datasets in the + // dashboard. + UpdateParameterSyntax *bool +} + +type PublishDashboardRequest struct { + // UUID identifying the dashboard to be published. + DashboardId *string + // Flag to indicate if the publisher's credentials should be embedded in the + // published dashboard. These embedded credentials will be used to execute the + // published dashboard's queries. + EmbedCredentials *bool + // The ID of the warehouse that can be used to override the warehouse which was + // set in the draft. + WarehouseId *string +} + +type PublishedDashboard struct { + // The display name of the published dashboard. + DisplayName *string + // The warehouse ID used to run the published dashboard. + WarehouseId *string + // Indicates whether credentials are embedded in the published dashboard. + EmbedCredentials *bool + // The timestamp of when the published dashboard was last revised. + RevisionCreateTime *types.Time +} + +// Request to revert a dashboard draft to its last published state.. +type RevertDashboardRequest struct { + // UUID identifying the dashboard. + DashboardId *string + // The etag for the dashboard. Optionally, it can be provided to verify that the + // dashboard has not been modified from its last retrieval. + Etag *string +} + +// Response to revert a dashboard draft to its last published state.. +type RevertDashboardResponse struct { + // The reverted dashboard. + Dashboard *Dashboard +} + +type Schedule struct { + // UUID identifying the schedule. + ScheduleId *string + // UUID identifying the dashboard to which the schedule belongs. + DashboardId *string + // The cron expression describing the frequency of the periodic refresh for this + // schedule. + CronSchedule *CronSchedule + // The status indicates whether this schedule is paused or not. + PauseStatus SchedulePauseStatus + // The display name for schedule. + DisplayName *string + // The etag for the schedule. Must be left empty on create, must be provided on + // updates to ensure that the schedule has not been modified since the last + // read, and can be optionally provided on delete. + Etag *string + // A timestamp indicating when the schedule was created. + CreateTime *types.Time + // A timestamp indicating when the schedule was last updated. + UpdateTime *types.Time + // The warehouse id to run the dashboard with for the schedule. + WarehouseId *string +} + +type Subscription struct { + // UUID identifying the subscription. + SubscriptionId *string + // UUID identifying the schedule to which the subscription belongs. + ScheduleId *string + // UUID identifying the dashboard to which the subscription belongs. + DashboardId *string + // Subscriber details for users and destinations to be added as subscribers to + // the schedule. + Subscriber *Subscription_Subscriber + // UserId of the user who adds subscribers (users or notification destinations) + // to the dashboard's schedule. + CreatedByUserId *int64 + // The etag for the subscription. Must be left empty on create, can be + // optionally provided on delete to ensure that the subscription has not been + // deleted since the last read. + Etag *string + // A timestamp indicating when the subscription was created. + CreateTime *types.Time + // A timestamp indicating when the subscription was last updated. + UpdateTime *types.Time + // Controls whether notifications are sent to the subscriber for scheduled + // dashboard refreshes. If not defined, defaults to false in the backend to + // match the current behavior (refresh and notify) + SkipNotify *bool +} + +type Subscription_Subscriber struct { + // The user to receive the subscription email. This parameter is mutually + // exclusive with `destination_subscriber`. + UserSubscriber *Subscription_Subscriber_User + // The destination to receive the subscription email. This parameter is mutually + // exclusive with `user_subscriber`. + DestinationSubscriber *Subscription_Subscriber_Destination +} + +type Subscription_Subscriber_Destination struct { + // The canonical identifier of the destination to receive email notification. + DestinationId *string +} + +type Subscription_Subscriber_User struct { + // UserId of the subscriber. + UserId *int64 +} + +type TrashDashboardRequest struct { + // UUID identifying the dashboard. + DashboardId *string +} + +type TrashDashboardResponse struct { +} + +type UnpublishDashboardRequest struct { + // UUID identifying the published dashboard. + DashboardId *string +} + +type UnpublishDashboardResponse struct { +} + +type UpdateDashboardRequest struct { + Dashboard *Dashboard + // Sets the default catalog for all datasets in this dashboard. Does not impact + // table references that use fully qualified catalog names (ex: + // samples.nyctaxi.trips). Leave blank to keep each dataset’s existing + // configuration. + DatasetCatalog *string + // Sets the default schema for all datasets in this dashboard. Does not impact + // table references that use fully qualified schema names (ex: nyctaxi.trips). + // Leave blank to keep each dataset’s existing configuration. + DatasetSchema *string +} + +type UpdateScheduleRequest struct { + // The schedule to update. + Schedule *Schedule +} diff --git a/lakeview/v1/wire.go b/lakeview/v1/wire.go new file mode 100755 index 0000000..ac6b124 --- /dev/null +++ b/lakeview/v1/wire.go @@ -0,0 +1,693 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package lakeview + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +type authorizationDetailsWire struct { + Type *string `json:"type,omitempty"` + ResourceName *string `json:"resource_name,omitempty"` + ResourceLegacyAclPath *string `json:"resource_legacy_acl_path,omitempty"` + GrantRules []authorizationDetails_GrantRuleWire `json:"grant_rules,omitempty"` +} + +func authorizationDetailsFromWire(w *authorizationDetailsWire) (*AuthorizationDetails, error) { + if w == nil { + return nil, nil + } + grantRulesPublicValue, err := convertSlice(w.GrantRules, authorizationDetails_GrantRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AuthorizationDetails.GrantRules", err) + } + return &AuthorizationDetails{ + Type: w.Type, + ResourceName: w.ResourceName, + ResourceLegacyAclPath: w.ResourceLegacyAclPath, + GrantRules: grantRulesPublicValue, + }, nil +} + +type authorizationDetails_GrantRuleWire struct { + PermissionSet *string `json:"permission_set,omitempty"` +} + +func authorizationDetails_GrantRuleFromWire(w *authorizationDetails_GrantRuleWire) (*AuthorizationDetails_GrantRule, error) { + if w == nil { + return nil, nil + } + return &AuthorizationDetails_GrantRule{ + PermissionSet: w.PermissionSet, + }, nil +} + +type createDashboardRequestWire struct { + Dashboard *dashboardWire `json:"dashboard,omitempty"` + DatasetCatalog *string `json:"dataset_catalog,omitempty"` + DatasetSchema *string `json:"dataset_schema,omitempty"` +} + +func createDashboardRequestToWire(v *CreateDashboardRequest) (*createDashboardRequestWire, error) { + if v == nil { + return nil, nil + } + dashboardWireValue, err := dashboardToWire(v.Dashboard) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateDashboardRequest.Dashboard", err) + } + return &createDashboardRequestWire{ + Dashboard: dashboardWireValue, + DatasetCatalog: v.DatasetCatalog, + DatasetSchema: v.DatasetSchema, + }, nil +} + +type createScheduleRequestWire struct { + Schedule *scheduleWire `json:"schedule,omitempty"` +} + +func createScheduleRequestToWire(v *CreateScheduleRequest) (*createScheduleRequestWire, error) { + if v == nil { + return nil, nil + } + scheduleWireValue, err := scheduleToWire(v.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateScheduleRequest.Schedule", err) + } + return &createScheduleRequestWire{ + Schedule: scheduleWireValue, + }, nil +} + +type createSubscriptionRequestWire struct { + Subscription *subscriptionWire `json:"subscription,omitempty"` +} + +func createSubscriptionRequestToWire(v *CreateSubscriptionRequest) (*createSubscriptionRequestWire, error) { + if v == nil { + return nil, nil + } + subscriptionWireValue, err := subscriptionToWire(v.Subscription) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateSubscriptionRequest.Subscription", err) + } + return &createSubscriptionRequestWire{ + Subscription: subscriptionWireValue, + }, nil +} + +type cronScheduleWire struct { + QuartzCronExpression *string `json:"quartz_cron_expression,omitempty"` + TimezoneId *string `json:"timezone_id,omitempty"` +} + +func cronScheduleToWire(v *CronSchedule) (*cronScheduleWire, error) { + if v == nil { + return nil, nil + } + return &cronScheduleWire{ + QuartzCronExpression: v.QuartzCronExpression, + TimezoneId: v.TimezoneId, + }, nil +} + +func cronScheduleFromWire(w *cronScheduleWire) (*CronSchedule, error) { + if w == nil { + return nil, nil + } + return &CronSchedule{ + QuartzCronExpression: w.QuartzCronExpression, + TimezoneId: w.TimezoneId, + }, nil +} + +type dashboardWire struct { + DashboardId *string `json:"dashboard_id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Path *string `json:"path,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + Etag *string `json:"etag,omitempty"` + SerializedDashboard *string `json:"serialized_dashboard,omitempty"` + LifecycleState LifecycleState `json:"lifecycle_state,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` +} + +func dashboardToWire(v *Dashboard) (*dashboardWire, error) { + if v == nil { + return nil, nil + } + return &dashboardWire{ + DashboardId: v.DashboardId, + DisplayName: v.DisplayName, + Path: v.Path, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + WarehouseId: v.WarehouseId, + Etag: v.Etag, + SerializedDashboard: v.SerializedDashboard, + LifecycleState: v.LifecycleState, + ParentPath: v.ParentPath, + }, nil +} + +func dashboardFromWire(w *dashboardWire) (*Dashboard, error) { + if w == nil { + return nil, nil + } + return &Dashboard{ + DashboardId: w.DashboardId, + DisplayName: w.DisplayName, + Path: w.Path, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + WarehouseId: w.WarehouseId, + Etag: w.Etag, + SerializedDashboard: w.SerializedDashboard, + LifecycleState: w.LifecycleState, + ParentPath: w.ParentPath, + }, nil +} + +type deleteScheduleRequestWire struct { + ScheduleId *string `json:"schedule_id,omitempty"` + DashboardId *string `json:"dashboard_id,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +func deleteScheduleRequestToWire(v *DeleteScheduleRequest) (*deleteScheduleRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteScheduleRequestWire{ + ScheduleId: v.ScheduleId, + DashboardId: v.DashboardId, + Etag: v.Etag, + }, nil +} + +type deleteSubscriptionRequestWire struct { + SubscriptionId *string `json:"subscription_id,omitempty"` + ScheduleId *string `json:"schedule_id,omitempty"` + DashboardId *string `json:"dashboard_id,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +func deleteSubscriptionRequestToWire(v *DeleteSubscriptionRequest) (*deleteSubscriptionRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteSubscriptionRequestWire{ + SubscriptionId: v.SubscriptionId, + ScheduleId: v.ScheduleId, + DashboardId: v.DashboardId, + Etag: v.Etag, + }, nil +} + +type getPublishedDashboardTokenInfoRequestWire struct { + DashboardId *string `json:"dashboard_id,omitempty"` + ExternalValue *string `json:"external_value,omitempty"` + ExternalViewerId *string `json:"external_viewer_id,omitempty"` +} + +func getPublishedDashboardTokenInfoRequestToWire(v *GetPublishedDashboardTokenInfoRequest) (*getPublishedDashboardTokenInfoRequestWire, error) { + if v == nil { + return nil, nil + } + return &getPublishedDashboardTokenInfoRequestWire{ + DashboardId: v.DashboardId, + ExternalValue: v.ExternalValue, + ExternalViewerId: v.ExternalViewerId, + }, nil +} + +type getPublishedDashboardTokenInfoResponseWire struct { + CustomClaim *string `json:"custom_claim,omitempty"` + Scope *string `json:"scope,omitempty"` + AuthorizationDetails []authorizationDetailsWire `json:"authorization_details,omitempty"` +} + +func getPublishedDashboardTokenInfoResponseFromWire(w *getPublishedDashboardTokenInfoResponseWire) (*GetPublishedDashboardTokenInfoResponse, error) { + if w == nil { + return nil, nil + } + authorizationDetailsPublicValue, err := convertSlice(w.AuthorizationDetails, authorizationDetailsFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPublishedDashboardTokenInfoResponse.AuthorizationDetails", err) + } + return &GetPublishedDashboardTokenInfoResponse{ + CustomClaim: w.CustomClaim, + Scope: w.Scope, + AuthorizationDetails: authorizationDetailsPublicValue, + }, nil +} + +type listDashboardsRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` + ShowTrashed *bool `json:"show_trashed,omitempty"` + View DashboardView `json:"view,omitempty"` +} + +func listDashboardsRequestToWire(v *ListDashboardsRequest) (*listDashboardsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listDashboardsRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + ShowTrashed: v.ShowTrashed, + View: v.View, + }, nil +} + +type listDashboardsResponseWire struct { + Dashboards []dashboardWire `json:"dashboards,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listDashboardsResponseFromWire(w *listDashboardsResponseWire) (*ListDashboardsResponse, error) { + if w == nil { + return nil, nil + } + dashboardsPublicValue, err := convertSlice(w.Dashboards, dashboardFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListDashboardsResponse.Dashboards", err) + } + return &ListDashboardsResponse{ + Dashboards: dashboardsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listSchedulesRequestWire struct { + DashboardId *string `json:"dashboard_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listSchedulesRequestToWire(v *ListSchedulesRequest) (*listSchedulesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSchedulesRequestWire{ + DashboardId: v.DashboardId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listSchedulesResponseWire struct { + Schedules []scheduleWire `json:"schedules,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listSchedulesResponseFromWire(w *listSchedulesResponseWire) (*ListSchedulesResponse, error) { + if w == nil { + return nil, nil + } + schedulesPublicValue, err := convertSlice(w.Schedules, scheduleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListSchedulesResponse.Schedules", err) + } + return &ListSchedulesResponse{ + Schedules: schedulesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listSubscriptionsRequestWire struct { + DashboardId *string `json:"dashboard_id,omitempty"` + ScheduleId *string `json:"schedule_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listSubscriptionsRequestToWire(v *ListSubscriptionsRequest) (*listSubscriptionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSubscriptionsRequestWire{ + DashboardId: v.DashboardId, + ScheduleId: v.ScheduleId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listSubscriptionsResponseWire struct { + Subscriptions []subscriptionWire `json:"subscriptions,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listSubscriptionsResponseFromWire(w *listSubscriptionsResponseWire) (*ListSubscriptionsResponse, error) { + if w == nil { + return nil, nil + } + subscriptionsPublicValue, err := convertSlice(w.Subscriptions, subscriptionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListSubscriptionsResponse.Subscriptions", err) + } + return &ListSubscriptionsResponse{ + Subscriptions: subscriptionsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type migrateDashboardRequestWire struct { + SourceDashboardId *string `json:"source_dashboard_id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + UpdateParameterSyntax *bool `json:"update_parameter_syntax,omitempty"` +} + +func migrateDashboardRequestToWire(v *MigrateDashboardRequest) (*migrateDashboardRequestWire, error) { + if v == nil { + return nil, nil + } + return &migrateDashboardRequestWire{ + SourceDashboardId: v.SourceDashboardId, + DisplayName: v.DisplayName, + ParentPath: v.ParentPath, + UpdateParameterSyntax: v.UpdateParameterSyntax, + }, nil +} + +type publishDashboardRequestWire struct { + DashboardId *string `json:"dashboard_id,omitempty"` + EmbedCredentials *bool `json:"embed_credentials,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` +} + +func publishDashboardRequestToWire(v *PublishDashboardRequest) (*publishDashboardRequestWire, error) { + if v == nil { + return nil, nil + } + return &publishDashboardRequestWire{ + DashboardId: v.DashboardId, + EmbedCredentials: v.EmbedCredentials, + WarehouseId: v.WarehouseId, + }, nil +} + +type publishedDashboardWire struct { + DisplayName *string `json:"display_name,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + EmbedCredentials *bool `json:"embed_credentials,omitempty"` + RevisionCreateTime *types.Time `json:"revision_create_time,omitempty"` +} + +func publishedDashboardFromWire(w *publishedDashboardWire) (*PublishedDashboard, error) { + if w == nil { + return nil, nil + } + return &PublishedDashboard{ + DisplayName: w.DisplayName, + WarehouseId: w.WarehouseId, + EmbedCredentials: w.EmbedCredentials, + RevisionCreateTime: w.RevisionCreateTime, + }, nil +} + +type revertDashboardRequestWire struct { + DashboardId *string `json:"dashboard_id,omitempty"` + Etag *string `json:"etag,omitempty"` +} + +func revertDashboardRequestToWire(v *RevertDashboardRequest) (*revertDashboardRequestWire, error) { + if v == nil { + return nil, nil + } + return &revertDashboardRequestWire{ + DashboardId: v.DashboardId, + Etag: v.Etag, + }, nil +} + +type revertDashboardResponseWire struct { + Dashboard *dashboardWire `json:"dashboard,omitempty"` +} + +func revertDashboardResponseFromWire(w *revertDashboardResponseWire) (*RevertDashboardResponse, error) { + if w == nil { + return nil, nil + } + dashboardPublicValue, err := dashboardFromWire(w.Dashboard) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RevertDashboardResponse.Dashboard", err) + } + return &RevertDashboardResponse{ + Dashboard: dashboardPublicValue, + }, nil +} + +type scheduleWire struct { + ScheduleId *string `json:"schedule_id,omitempty"` + DashboardId *string `json:"dashboard_id,omitempty"` + CronSchedule *cronScheduleWire `json:"cron_schedule,omitempty"` + PauseStatus SchedulePauseStatus `json:"pause_status,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Etag *string `json:"etag,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` +} + +func scheduleToWire(v *Schedule) (*scheduleWire, error) { + if v == nil { + return nil, nil + } + cronScheduleWireValue, err := cronScheduleToWire(v.CronSchedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Schedule.CronSchedule", err) + } + return &scheduleWire{ + ScheduleId: v.ScheduleId, + DashboardId: v.DashboardId, + CronSchedule: cronScheduleWireValue, + PauseStatus: v.PauseStatus, + DisplayName: v.DisplayName, + Etag: v.Etag, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + WarehouseId: v.WarehouseId, + }, nil +} + +func scheduleFromWire(w *scheduleWire) (*Schedule, error) { + if w == nil { + return nil, nil + } + cronSchedulePublicValue, err := cronScheduleFromWire(w.CronSchedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Schedule.CronSchedule", err) + } + return &Schedule{ + ScheduleId: w.ScheduleId, + DashboardId: w.DashboardId, + CronSchedule: cronSchedulePublicValue, + PauseStatus: w.PauseStatus, + DisplayName: w.DisplayName, + Etag: w.Etag, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + WarehouseId: w.WarehouseId, + }, nil +} + +type subscriptionWire struct { + SubscriptionId *string `json:"subscription_id,omitempty"` + ScheduleId *string `json:"schedule_id,omitempty"` + DashboardId *string `json:"dashboard_id,omitempty"` + Subscriber *subscription_SubscriberWire `json:"subscriber,omitempty"` + CreatedByUserId *int64 `json:"created_by_user_id,omitempty"` + Etag *string `json:"etag,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + SkipNotify *bool `json:"skip_notify,omitempty"` +} + +func subscriptionToWire(v *Subscription) (*subscriptionWire, error) { + if v == nil { + return nil, nil + } + subscriberWireValue, err := subscription_SubscriberToWire(v.Subscriber) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Subscription.Subscriber", err) + } + return &subscriptionWire{ + SubscriptionId: v.SubscriptionId, + ScheduleId: v.ScheduleId, + DashboardId: v.DashboardId, + Subscriber: subscriberWireValue, + CreatedByUserId: v.CreatedByUserId, + Etag: v.Etag, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + SkipNotify: v.SkipNotify, + }, nil +} + +func subscriptionFromWire(w *subscriptionWire) (*Subscription, error) { + if w == nil { + return nil, nil + } + subscriberPublicValue, err := subscription_SubscriberFromWire(w.Subscriber) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Subscription.Subscriber", err) + } + return &Subscription{ + SubscriptionId: w.SubscriptionId, + ScheduleId: w.ScheduleId, + DashboardId: w.DashboardId, + Subscriber: subscriberPublicValue, + CreatedByUserId: w.CreatedByUserId, + Etag: w.Etag, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + SkipNotify: w.SkipNotify, + }, nil +} + +type subscription_SubscriberWire struct { + UserSubscriber *subscription_Subscriber_UserWire `json:"user_subscriber,omitempty"` + DestinationSubscriber *subscription_Subscriber_DestinationWire `json:"destination_subscriber,omitempty"` +} + +func subscription_SubscriberToWire(v *Subscription_Subscriber) (*subscription_SubscriberWire, error) { + if v == nil { + return nil, nil + } + userSubscriberWireValue, err := subscription_Subscriber_UserToWire(v.UserSubscriber) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Subscription_Subscriber.UserSubscriber", err) + } + destinationSubscriberWireValue, err := subscription_Subscriber_DestinationToWire(v.DestinationSubscriber) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Subscription_Subscriber.DestinationSubscriber", err) + } + return &subscription_SubscriberWire{ + UserSubscriber: userSubscriberWireValue, + DestinationSubscriber: destinationSubscriberWireValue, + }, nil +} + +func subscription_SubscriberFromWire(w *subscription_SubscriberWire) (*Subscription_Subscriber, error) { + if w == nil { + return nil, nil + } + userSubscriberPublicValue, err := subscription_Subscriber_UserFromWire(w.UserSubscriber) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Subscription_Subscriber.UserSubscriber", err) + } + destinationSubscriberPublicValue, err := subscription_Subscriber_DestinationFromWire(w.DestinationSubscriber) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Subscription_Subscriber.DestinationSubscriber", err) + } + return &Subscription_Subscriber{ + UserSubscriber: userSubscriberPublicValue, + DestinationSubscriber: destinationSubscriberPublicValue, + }, nil +} + +type subscription_Subscriber_DestinationWire struct { + DestinationId *string `json:"destination_id,omitempty"` +} + +func subscription_Subscriber_DestinationToWire(v *Subscription_Subscriber_Destination) (*subscription_Subscriber_DestinationWire, error) { + if v == nil { + return nil, nil + } + return &subscription_Subscriber_DestinationWire{ + DestinationId: v.DestinationId, + }, nil +} + +func subscription_Subscriber_DestinationFromWire(w *subscription_Subscriber_DestinationWire) (*Subscription_Subscriber_Destination, error) { + if w == nil { + return nil, nil + } + return &Subscription_Subscriber_Destination{ + DestinationId: w.DestinationId, + }, nil +} + +type subscription_Subscriber_UserWire struct { + UserId *int64 `json:"user_id,omitempty"` +} + +func subscription_Subscriber_UserToWire(v *Subscription_Subscriber_User) (*subscription_Subscriber_UserWire, error) { + if v == nil { + return nil, nil + } + return &subscription_Subscriber_UserWire{ + UserId: v.UserId, + }, nil +} + +func subscription_Subscriber_UserFromWire(w *subscription_Subscriber_UserWire) (*Subscription_Subscriber_User, error) { + if w == nil { + return nil, nil + } + return &Subscription_Subscriber_User{ + UserId: w.UserId, + }, nil +} + +type updateDashboardRequestWire struct { + Dashboard *dashboardWire `json:"dashboard,omitempty"` + DatasetCatalog *string `json:"dataset_catalog,omitempty"` + DatasetSchema *string `json:"dataset_schema,omitempty"` +} + +func updateDashboardRequestToWire(v *UpdateDashboardRequest) (*updateDashboardRequestWire, error) { + if v == nil { + return nil, nil + } + dashboardWireValue, err := dashboardToWire(v.Dashboard) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateDashboardRequest.Dashboard", err) + } + return &updateDashboardRequestWire{ + Dashboard: dashboardWireValue, + DatasetCatalog: v.DatasetCatalog, + DatasetSchema: v.DatasetSchema, + }, nil +} + +type updateScheduleRequestWire struct { + Schedule *scheduleWire `json:"schedule,omitempty"` +} + +func updateScheduleRequestToWire(v *UpdateScheduleRequest) (*updateScheduleRequestWire, error) { + if v == nil { + return nil, nil + } + scheduleWireValue, err := scheduleToWire(v.Schedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateScheduleRequest.Schedule", err) + } + return &updateScheduleRequestWire{ + Schedule: scheduleWireValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/logdelivery/.package.json b/logdelivery/.package.json new file mode 100644 index 0000000..c73e8c3 --- /dev/null +++ b/logdelivery/.package.json @@ -0,0 +1,3 @@ +{ + "package": "logdelivery" +} diff --git a/logdelivery/CHANGELOG.md b/logdelivery/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/logdelivery/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/logdelivery/README.md b/logdelivery/README.md new file mode 100644 index 0000000..de1aa38 --- /dev/null +++ b/logdelivery/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/logdelivery + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/logdelivery@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/logdelivery/v1" + +client, err := logdelivery.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/logdelivery/go.mod b/logdelivery/go.mod new file mode 100644 index 0000000..7e83bb1 --- /dev/null +++ b/logdelivery/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/logdelivery + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/logdelivery/internal/version.go b/logdelivery/internal/version.go new file mode 100644 index 0000000..0740296 --- /dev/null +++ b/logdelivery/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-logdelivery" + +const Version = "0.0.1-dev.1" diff --git a/logdelivery/v1/client.go b/logdelivery/v1/client.go new file mode 100755 index 0000000..34b4c4b --- /dev/null +++ b/logdelivery/v1/client.go @@ -0,0 +1,430 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package logdelivery + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/logdelivery/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new log delivery configuration to enable delivery of +// the specified type of logs to your storage location. This requires that you +// already created a [credential object](:method:Credentials/Create) (which +// encapsulates a cross-account service IAM role) and a [storage configuration +// object](:method:Storage/Create) (which encapsulates an S3 bucket). +// +// For full details, including the required IAM role policies and bucket +// policies, see [Deliver and access billable usage logs] or [Configure audit +// logging]. +// +// **Note**: There is a limit on the number of log delivery configurations +// available per account (each limit applies separately to each log type +// including billable usage and audit logs). You can create a maximum of two +// enabled account-level delivery configurations (configurations without a +// workspace filter) per type. Additionally, you can create two enabled +// workspace-level delivery configurations per workspace for each log type, +// which means that the same workspace ID can occur in the workspace filter for +// no more than two delivery configurations per log type. +// +// You cannot delete a log delivery configuration, but you can disable it (see +// [Enable or disable log delivery +// configuration](:method:LogDelivery/PatchStatus)). +// +// [Configure audit logging]: https://docs.databricks.com/administration-guide/account-settings/audit-logs.html +// [Deliver and access billable usage logs]: https://docs.databricks.com/administration-guide/account-settings/billable-usage-delivery.html +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateLogDeliveryConfiguration(ctx context.Context, req *CreateLogDeliveryConfigurationRequest, opts ...call.Option) (*CreateLogDeliveryConfigurationResponse, error) { + wireReq, err := createLogDeliveryConfigurationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/log-delivery") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateLogDeliveryConfigurationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createLogDeliveryConfigurationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createLogDeliveryConfigurationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a log delivery configuration object for an account, both +// specified by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetLogDeliveryConfiguration(ctx context.Context, req *GetLogDeliveryConfigurationRequest, opts ...call.Option) (*GetLogDeliveryConfigurationResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/log-delivery/") + pb.singleSegment(*req.ConfigId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetLogDeliveryConfigurationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getLogDeliveryConfigurationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getLogDeliveryConfigurationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets all log delivery configurations associated with an account +// specified by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListLogDeliveryConfiguration(ctx context.Context, req *ListLogDeliveryConfigurationRequest, opts ...call.Option) (*ListLogDeliveryConfigurationResponse, error) { + wireReq, err := listLogDeliveryConfigurationRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/log-delivery") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "credentials_id", wireReq.CredentialsId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "storage_configuration_id", wireReq.StorageConfigurationId); err != nil { + return nil, err + } + if wireReq.Status != "" { + if err := addQueryValue(queryParams, "status", wireReq.Status); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListLogDeliveryConfigurationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listLogDeliveryConfigurationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listLogDeliveryConfigurationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListLogDeliveryConfigurationIter returns an iterator that iterates +// over the results of ListLogDeliveryConfiguration. +// +// For example: +// +// for item, err := range c.ListLogDeliveryConfigurationIter(ctx, &ListLogDeliveryConfigurationRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListLogDeliveryConfiguration call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListLogDeliveryConfiguration directly. +func (c *internalClient) ListLogDeliveryConfigurationIter(ctx context.Context, req *ListLogDeliveryConfigurationRequest, opts ...call.Option) iter.Seq2[*LogDeliveryConfiguration, error] { + return func(yield func(*LogDeliveryConfiguration, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListLogDeliveryConfigurationRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListLogDeliveryConfiguration(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.LogDeliveryConfigurations { + if !yield(&resp.LogDeliveryConfigurations[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Enables or disables a log delivery configuration. Deletion of delivery +// configurations is not supported, so disable log delivery configurations that +// are no longer needed. Note that you can't re-enable a delivery configuration +// if this would violate the delivery configuration limits described under +// [Create log delivery](:method:LogDelivery/Create). +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateLogDeliveryConfiguration(ctx context.Context, req *UpdateLogDeliveryConfigurationRequest, opts ...call.Option) (*UpdateLogDeliveryConfigurationResponse, error) { + wireReq, err := updateLogDeliveryConfigurationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/log-delivery/") + pb.singleSegment(*req.ConfigId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateLogDeliveryConfigurationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateLogDeliveryConfigurationResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/logdelivery/v1/genhelper.go b/logdelivery/v1/genhelper.go new file mode 100755 index 0000000..1eb8ded --- /dev/null +++ b/logdelivery/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package logdelivery + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/logdelivery/v1/model.go b/logdelivery/v1/model.go new file mode 100755 index 0000000..887ba48 --- /dev/null +++ b/logdelivery/v1/model.go @@ -0,0 +1,308 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package logdelivery + +// * Log Delivery Status +// +// `ENABLED`: All dependencies have executed and succeeded `DISABLED`: At least +// one dependency has succeeded +type LogDeliveryConfigStatus string + +const ( + LogDeliveryConfigStatus_Unspecified LogDeliveryConfigStatus = "" + // Configuration is enabled + LogDeliveryConfigStatus_Enabled LogDeliveryConfigStatus = "ENABLED" + // Configuration is disabled + LogDeliveryConfigStatus_Disabled LogDeliveryConfigStatus = "DISABLED" +) + +// * Log Delivery Output Format +type LogDeliveryOutputFormat string + +const ( + LogDeliveryOutputFormat_Unspecified LogDeliveryOutputFormat = "" + // Deliver CSV files + LogDeliveryOutputFormat_Csv LogDeliveryOutputFormat = "CSV" + // Deliver JSON files + LogDeliveryOutputFormat_Json LogDeliveryOutputFormat = "JSON" +) + +// * The status string for log delivery. Possible values are: `CREATED`: There +// were no log delivery attempts since the config was created. `SUCCEEDED`: The +// latest attempt of log delivery has succeeded completely. `USER_FAILURE`: The +// latest attempt of log delivery failed because of misconfiguration of customer +// provided permissions on role or storage. `SYSTEM_FAILURE`: The latest attempt +// of log delivery failed because of an internal error. Contact +// support if it doesn't go away soon. `NOT_FOUND`: The log delivery status as +// the configuration has been disabled since the release of this feature or +// there are no workspaces in the account. +type LogDeliveryStatusEnum string + +const ( + LogDeliveryStatusEnum_Unspecified LogDeliveryStatusEnum = "" + // Configuration is just created and logs haven't delivered yet + LogDeliveryStatusEnum_Created LogDeliveryStatusEnum = "CREATED" + // Configuration has succeeded in the last run + LogDeliveryStatusEnum_Succeeded LogDeliveryStatusEnum = "SUCCEEDED" + // Configuration has failed in the last run due to user failure + LogDeliveryStatusEnum_UserFailure LogDeliveryStatusEnum = "USER_FAILURE" + // Configuration has failed in the last run due to system failure + LogDeliveryStatusEnum_SystemFailure LogDeliveryStatusEnum = "SYSTEM_FAILURE" + // Status not found + LogDeliveryStatusEnum_NotFound LogDeliveryStatusEnum = "NOT_FOUND" +) + +// * Log Delivery Type +type LogDeliveryType string + +const ( + LogDeliveryType_Unspecified LogDeliveryType = "" + // Deliver Billable Usage logs + LogDeliveryType_BillableUsage LogDeliveryType = "BILLABLE_USAGE" + // Deliver Audit Logs + LogDeliveryType_AuditLogs LogDeliveryType = "AUDIT_LOGS" +) + +// * Log Delivery Configuration. +type CreateLogDeliveryConfigurationParams struct { + // The unique UUID of log delivery configuration + ConfigId *string + // The optional human-readable name of the log delivery configuration. Defaults + // to empty. + ConfigName *string + // Log delivery type. Supported values are: * `BILLABLE_USAGE` — Configure + // [billable usage log delivery]. For the CSV schema, see the [View billable + // usage]. * `AUDIT_LOGS` — Configure [audit log delivery]. For the JSON + // schema, see [Configure audit logging] + // + // [Configure audit logging]: https://docs.databricks.com/administration-guide/account-settings/audit-logs.html + // [View billable usage]: https://docs.databricks.com/administration-guide/account-settings/usage.html + // [audit log delivery]: https://docs.databricks.com/administration-guide/account-settings/audit-logs.html + // [billable usage log delivery]: https://docs.databricks.com/administration-guide/account-settings/billable-usage-delivery.html + LogType LogDeliveryType + // The file type of log delivery. * If `log_type` is `BILLABLE_USAGE`, this + // value must be `CSV`. Only the CSV (comma-separated values) format is + // supported. For the schema, see the [View billable usage] * If `log_type` is + // `AUDIT_LOGS`, this value must be `JSON`. Only the JSON (JavaScript Object + // Notation) format is supported. For the schema, see the [Configuring audit + // logs]. + // + // [Configuring audit logs]: https://docs.databricks.com/administration-guide/account-settings/audit-logs.html + // [View billable usage]: https://docs.databricks.com/administration-guide/account-settings/usage.html + OutputFormat LogDeliveryOutputFormat + // account ID. + AccountId *string + // The ID for a method:credentials/create that represents the AWS IAM role with + // policy and trust relationship as described in the main billable usage + // documentation page. See [Configure billable usage delivery]. + // + // [Configure billable usage delivery]: https://docs.databricks.com/administration-guide/account-settings/billable-usage-delivery.html + CredentialsId *string + // The ID for a method:storage/create that represents the S3 bucket with bucket + // policy as described in the main billable usage documentation page. See + // [Configure billable usage delivery]. + // + // [Configure billable usage delivery]: https://docs.databricks.com/administration-guide/account-settings/billable-usage-delivery.html + StorageConfigurationId *string + // Optional filter that specifies workspace IDs to deliver logs for. By default + // the workspace filter is empty and log delivery applies at the account level, + // delivering workspace-level logs for all workspaces in your account, plus + // account level logs. You can optionally set this field to an array of + // workspace IDs (each one is an `int64`) to which log delivery should apply, in + // which case only workspace-level logs relating to the specified workspaces are + // delivered. If you plan to use different log delivery configurations for + // different workspaces, set this field explicitly. Be aware that delivery + // configurations mentioning specific workspaces won't apply to new workspaces + // created in the future, and delivery won't include account level logs. For + // some types of deployments there is only one workspace per + // account ID, so this field is unnecessary. + WorkspaceIdsFilter []int64 + // The optional delivery path prefix within Amazon S3 storage. Defaults to + // empty, which means that logs are delivered to the root of the bucket. This + // must be a valid S3 object key. This must not start or end with a slash + // character. + DeliveryPathPrefix *string + // This field applies only if log_type is BILLABLE_USAGE. This is the optional + // start month and year for delivery, specified in YYYY-MM format. Defaults to + // current year and month. BILLABLE_USAGE logs are not available for usage + // before March 2019 (2019-03). + DeliveryStartTime *string + // Status of log delivery configuration. Set to `ENABLED` (enabled) or + // `DISABLED` (disabled). Defaults to `ENABLED`. You can [enable or disable the + // configuration](#operation/patch-log-delivery-config-status) later. Deletion + // of a configuration is not supported, so disable a log delivery configuration + // that is no longer needed. + Status LogDeliveryConfigStatus + // Time in epoch milliseconds when the log delivery configuration was created. + CreationTime *int64 + // Time in epoch milliseconds when the log delivery configuration was updated. + UpdateTime *int64 + // The LogDeliveryStatus of this log delivery configuration + LogDeliveryStatus *LogDeliveryStatus +} + +// * Properties of the new log delivery configuration.. +type CreateLogDeliveryConfigurationRequest struct { + LogDeliveryConfiguration *CreateLogDeliveryConfigurationParams +} + +type CreateLogDeliveryConfigurationResponse struct { + // The created log delivery configuration + LogDeliveryConfiguration *LogDeliveryConfiguration +} + +// * Get Log Delivery Configuration. +type GetLogDeliveryConfigurationRequest struct { + // The log delivery configuration id of customer + ConfigId *string + // account ID. + AccountId *string +} + +type GetLogDeliveryConfigurationResponse struct { + // The fetched log delivery configuration + LogDeliveryConfiguration *LogDeliveryConfiguration +} + +// * List Log Delivery Configuration. +type ListLogDeliveryConfigurationRequest struct { + // account ID. + AccountId *string + // The Credentials id to filter the search results with + CredentialsId *string + // The Storage Configuration id to filter the search results with + StorageConfigurationId *string + // The log delivery status to filter the search results with + Status LogDeliveryConfigStatus + // A page token received from a previous get all budget configurations call. + // This token can be used to retrieve the subsequent page. Requests first page + // if absent. + PageToken *string +} + +type ListLogDeliveryConfigurationResponse struct { + // Log delivery configurations were returned successfully. + LogDeliveryConfigurations []LogDeliveryConfiguration + // Token which can be sent as `page_token` to retrieve the next page of results. + // If this field is omitted, there are no subsequent budgets. + NextPageToken *string +} + +// * Log Delivery Configuration. +type LogDeliveryConfiguration struct { + // The unique UUID of log delivery configuration + ConfigId *string + // The optional human-readable name of the log delivery configuration. Defaults + // to empty. + ConfigName *string + // Log delivery type. Supported values are: * `BILLABLE_USAGE` — Configure + // [billable usage log delivery]. For the CSV schema, see the [View billable + // usage]. * `AUDIT_LOGS` — Configure [audit log delivery]. For the JSON + // schema, see [Configure audit logging] + // + // [Configure audit logging]: https://docs.databricks.com/administration-guide/account-settings/audit-logs.html + // [View billable usage]: https://docs.databricks.com/administration-guide/account-settings/usage.html + // [audit log delivery]: https://docs.databricks.com/administration-guide/account-settings/audit-logs.html + // [billable usage log delivery]: https://docs.databricks.com/administration-guide/account-settings/billable-usage-delivery.html + LogType LogDeliveryType + // The file type of log delivery. * If `log_type` is `BILLABLE_USAGE`, this + // value must be `CSV`. Only the CSV (comma-separated values) format is + // supported. For the schema, see the [View billable usage] * If `log_type` is + // `AUDIT_LOGS`, this value must be `JSON`. Only the JSON (JavaScript Object + // Notation) format is supported. For the schema, see the [Configuring audit + // logs]. + // + // [Configuring audit logs]: https://docs.databricks.com/administration-guide/account-settings/audit-logs.html + // [View billable usage]: https://docs.databricks.com/administration-guide/account-settings/usage.html + OutputFormat LogDeliveryOutputFormat + // account ID. + AccountId *string + // The ID for a method:credentials/create that represents the AWS IAM role with + // policy and trust relationship as described in the main billable usage + // documentation page. See [Configure billable usage delivery]. + // + // [Configure billable usage delivery]: https://docs.databricks.com/administration-guide/account-settings/billable-usage-delivery.html + CredentialsId *string + // The ID for a method:storage/create that represents the S3 bucket with bucket + // policy as described in the main billable usage documentation page. See + // [Configure billable usage delivery]. + // + // [Configure billable usage delivery]: https://docs.databricks.com/administration-guide/account-settings/billable-usage-delivery.html + StorageConfigurationId *string + // Optional filter that specifies workspace IDs to deliver logs for. By default + // the workspace filter is empty and log delivery applies at the account level, + // delivering workspace-level logs for all workspaces in your account, plus + // account level logs. You can optionally set this field to an array of + // workspace IDs (each one is an `int64`) to which log delivery should apply, in + // which case only workspace-level logs relating to the specified workspaces are + // delivered. If you plan to use different log delivery configurations for + // different workspaces, set this field explicitly. Be aware that delivery + // configurations mentioning specific workspaces won't apply to new workspaces + // created in the future, and delivery won't include account level logs. For + // some types of deployments there is only one workspace per + // account ID, so this field is unnecessary. + WorkspaceIdsFilter []int64 + // The optional delivery path prefix within Amazon S3 storage. Defaults to + // empty, which means that logs are delivered to the root of the bucket. This + // must be a valid S3 object key. This must not start or end with a slash + // character. + DeliveryPathPrefix *string + // This field applies only if log_type is BILLABLE_USAGE. This is the optional + // start month and year for delivery, specified in YYYY-MM format. Defaults to + // current year and month. BILLABLE_USAGE logs are not available for usage + // before March 2019 (2019-03). + DeliveryStartTime *string + // Status of log delivery configuration. Set to `ENABLED` (enabled) or + // `DISABLED` (disabled). Defaults to `ENABLED`. You can [enable or disable the + // configuration](#operation/patch-log-delivery-config-status) later. Deletion + // of a configuration is not supported, so disable a log delivery configuration + // that is no longer needed. + Status LogDeliveryConfigStatus + // Time in epoch milliseconds when the log delivery configuration was created. + CreationTime *int64 + // Time in epoch milliseconds when the log delivery configuration was updated. + UpdateTime *int64 + // The LogDeliveryStatus of this log delivery configuration + LogDeliveryStatus *LogDeliveryStatus +} + +type LogDeliveryStatus struct { + // Enum that describes the status. Possible values are: * `CREATED`: There were + // no log delivery attempts since the config was created. * `SUCCEEDED`: The + // latest attempt of log delivery has succeeded completely. * `USER_FAILURE`: + // The latest attempt of log delivery failed because of misconfiguration of + // customer provided permissions on role or storage. * `SYSTEM_FAILURE`: The + // latest attempt of log delivery failed because of an internal + // error. Contact support if it doesn't go away soon. * `NOT_FOUND`: The log + // delivery status as the configuration has been disabled since the release of + // this feature or there are no workspaces in the account. + Status LogDeliveryStatusEnum + // The UTC time for the latest log delivery attempt. + LastAttemptTime *string + // The UTC time for the latest successful log delivery. + LastSuccessfulAttemptTime *string + // Informative message about the latest log delivery attempt. If the log + // delivery fails with USER_FAILURE, error details will be provided for fixing + // misconfigurations in cloud permissions. + Message *string +} + +// * Update Log Delivery Configuration. +type UpdateLogDeliveryConfigurationRequest struct { + // The log delivery configuration id of customer + ConfigId *string + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console]. + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Status of log delivery configuration. Set to `ENABLED` (enabled) or + // `DISABLED` (disabled). Defaults to `ENABLED`. You can [enable or disable the + // configuration](#operation/patch-log-delivery-config-status) later. Deletion + // of a configuration is not supported, so disable a log delivery configuration + // that is no longer needed. + Status LogDeliveryConfigStatus +} + +type UpdateLogDeliveryConfigurationResponse struct { +} diff --git a/logdelivery/v1/wire.go b/logdelivery/v1/wire.go new file mode 100755 index 0000000..377b12b --- /dev/null +++ b/logdelivery/v1/wire.go @@ -0,0 +1,247 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package logdelivery + +import ( + "fmt" +) + +type createLogDeliveryConfigurationParamsWire struct { + ConfigId *string `json:"config_id,omitempty"` + ConfigName *string `json:"config_name,omitempty"` + LogType LogDeliveryType `json:"log_type,omitempty"` + OutputFormat LogDeliveryOutputFormat `json:"output_format,omitempty"` + AccountId *string `json:"account_id,omitempty"` + CredentialsId *string `json:"credentials_id,omitempty"` + StorageConfigurationId *string `json:"storage_configuration_id,omitempty"` + WorkspaceIdsFilter []int64 `json:"workspace_ids_filter,omitempty"` + DeliveryPathPrefix *string `json:"delivery_path_prefix,omitempty"` + DeliveryStartTime *string `json:"delivery_start_time,omitempty"` + Status LogDeliveryConfigStatus `json:"status,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + UpdateTime *int64 `json:"update_time,omitempty"` + LogDeliveryStatus *logDeliveryStatusWire `json:"log_delivery_status,omitempty"` +} + +func createLogDeliveryConfigurationParamsToWire(v *CreateLogDeliveryConfigurationParams) (*createLogDeliveryConfigurationParamsWire, error) { + if v == nil { + return nil, nil + } + logDeliveryStatusWireValue, err := logDeliveryStatusToWire(v.LogDeliveryStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateLogDeliveryConfigurationParams.LogDeliveryStatus", err) + } + return &createLogDeliveryConfigurationParamsWire{ + ConfigId: v.ConfigId, + ConfigName: v.ConfigName, + LogType: v.LogType, + OutputFormat: v.OutputFormat, + AccountId: v.AccountId, + CredentialsId: v.CredentialsId, + StorageConfigurationId: v.StorageConfigurationId, + WorkspaceIdsFilter: v.WorkspaceIdsFilter, + DeliveryPathPrefix: v.DeliveryPathPrefix, + DeliveryStartTime: v.DeliveryStartTime, + Status: v.Status, + CreationTime: v.CreationTime, + UpdateTime: v.UpdateTime, + LogDeliveryStatus: logDeliveryStatusWireValue, + }, nil +} + +type createLogDeliveryConfigurationRequestWire struct { + LogDeliveryConfiguration *createLogDeliveryConfigurationParamsWire `json:"log_delivery_configuration,omitempty"` +} + +func createLogDeliveryConfigurationRequestToWire(v *CreateLogDeliveryConfigurationRequest) (*createLogDeliveryConfigurationRequestWire, error) { + if v == nil { + return nil, nil + } + logDeliveryConfigurationWireValue, err := createLogDeliveryConfigurationParamsToWire(v.LogDeliveryConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateLogDeliveryConfigurationRequest.LogDeliveryConfiguration", err) + } + return &createLogDeliveryConfigurationRequestWire{ + LogDeliveryConfiguration: logDeliveryConfigurationWireValue, + }, nil +} + +type createLogDeliveryConfigurationResponseWire struct { + LogDeliveryConfiguration *logDeliveryConfigurationWire `json:"log_delivery_configuration,omitempty"` +} + +func createLogDeliveryConfigurationResponseFromWire(w *createLogDeliveryConfigurationResponseWire) (*CreateLogDeliveryConfigurationResponse, error) { + if w == nil { + return nil, nil + } + logDeliveryConfigurationPublicValue, err := logDeliveryConfigurationFromWire(w.LogDeliveryConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateLogDeliveryConfigurationResponse.LogDeliveryConfiguration", err) + } + return &CreateLogDeliveryConfigurationResponse{ + LogDeliveryConfiguration: logDeliveryConfigurationPublicValue, + }, nil +} + +type getLogDeliveryConfigurationResponseWire struct { + LogDeliveryConfiguration *logDeliveryConfigurationWire `json:"log_delivery_configuration,omitempty"` +} + +func getLogDeliveryConfigurationResponseFromWire(w *getLogDeliveryConfigurationResponseWire) (*GetLogDeliveryConfigurationResponse, error) { + if w == nil { + return nil, nil + } + logDeliveryConfigurationPublicValue, err := logDeliveryConfigurationFromWire(w.LogDeliveryConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetLogDeliveryConfigurationResponse.LogDeliveryConfiguration", err) + } + return &GetLogDeliveryConfigurationResponse{ + LogDeliveryConfiguration: logDeliveryConfigurationPublicValue, + }, nil +} + +type listLogDeliveryConfigurationRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + CredentialsId *string `json:"credentials_id,omitempty"` + StorageConfigurationId *string `json:"storage_configuration_id,omitempty"` + Status LogDeliveryConfigStatus `json:"status,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listLogDeliveryConfigurationRequestToWire(v *ListLogDeliveryConfigurationRequest) (*listLogDeliveryConfigurationRequestWire, error) { + if v == nil { + return nil, nil + } + return &listLogDeliveryConfigurationRequestWire{ + AccountId: v.AccountId, + CredentialsId: v.CredentialsId, + StorageConfigurationId: v.StorageConfigurationId, + Status: v.Status, + PageToken: v.PageToken, + }, nil +} + +type listLogDeliveryConfigurationResponseWire struct { + LogDeliveryConfigurations []logDeliveryConfigurationWire `json:"log_delivery_configurations,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listLogDeliveryConfigurationResponseFromWire(w *listLogDeliveryConfigurationResponseWire) (*ListLogDeliveryConfigurationResponse, error) { + if w == nil { + return nil, nil + } + logDeliveryConfigurationsPublicValue, err := convertSlice(w.LogDeliveryConfigurations, logDeliveryConfigurationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListLogDeliveryConfigurationResponse.LogDeliveryConfigurations", err) + } + return &ListLogDeliveryConfigurationResponse{ + LogDeliveryConfigurations: logDeliveryConfigurationsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type logDeliveryConfigurationWire struct { + ConfigId *string `json:"config_id,omitempty"` + ConfigName *string `json:"config_name,omitempty"` + LogType LogDeliveryType `json:"log_type,omitempty"` + OutputFormat LogDeliveryOutputFormat `json:"output_format,omitempty"` + AccountId *string `json:"account_id,omitempty"` + CredentialsId *string `json:"credentials_id,omitempty"` + StorageConfigurationId *string `json:"storage_configuration_id,omitempty"` + WorkspaceIdsFilter []int64 `json:"workspace_ids_filter,omitempty"` + DeliveryPathPrefix *string `json:"delivery_path_prefix,omitempty"` + DeliveryStartTime *string `json:"delivery_start_time,omitempty"` + Status LogDeliveryConfigStatus `json:"status,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + UpdateTime *int64 `json:"update_time,omitempty"` + LogDeliveryStatus *logDeliveryStatusWire `json:"log_delivery_status,omitempty"` +} + +func logDeliveryConfigurationFromWire(w *logDeliveryConfigurationWire) (*LogDeliveryConfiguration, error) { + if w == nil { + return nil, nil + } + logDeliveryStatusPublicValue, err := logDeliveryStatusFromWire(w.LogDeliveryStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LogDeliveryConfiguration.LogDeliveryStatus", err) + } + return &LogDeliveryConfiguration{ + ConfigId: w.ConfigId, + ConfigName: w.ConfigName, + LogType: w.LogType, + OutputFormat: w.OutputFormat, + AccountId: w.AccountId, + CredentialsId: w.CredentialsId, + StorageConfigurationId: w.StorageConfigurationId, + WorkspaceIdsFilter: w.WorkspaceIdsFilter, + DeliveryPathPrefix: w.DeliveryPathPrefix, + DeliveryStartTime: w.DeliveryStartTime, + Status: w.Status, + CreationTime: w.CreationTime, + UpdateTime: w.UpdateTime, + LogDeliveryStatus: logDeliveryStatusPublicValue, + }, nil +} + +type logDeliveryStatusWire struct { + Status LogDeliveryStatusEnum `json:"status,omitempty"` + LastAttemptTime *string `json:"last_attempt_time,omitempty"` + LastSuccessfulAttemptTime *string `json:"last_successful_attempt_time,omitempty"` + Message *string `json:"message,omitempty"` +} + +func logDeliveryStatusToWire(v *LogDeliveryStatus) (*logDeliveryStatusWire, error) { + if v == nil { + return nil, nil + } + return &logDeliveryStatusWire{ + Status: v.Status, + LastAttemptTime: v.LastAttemptTime, + LastSuccessfulAttemptTime: v.LastSuccessfulAttemptTime, + Message: v.Message, + }, nil +} + +func logDeliveryStatusFromWire(w *logDeliveryStatusWire) (*LogDeliveryStatus, error) { + if w == nil { + return nil, nil + } + return &LogDeliveryStatus{ + Status: w.Status, + LastAttemptTime: w.LastAttemptTime, + LastSuccessfulAttemptTime: w.LastSuccessfulAttemptTime, + Message: w.Message, + }, nil +} + +type updateLogDeliveryConfigurationRequestWire struct { + ConfigId *string `json:"config_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + Status LogDeliveryConfigStatus `json:"status,omitempty"` +} + +func updateLogDeliveryConfigurationRequestToWire(v *UpdateLogDeliveryConfigurationRequest) (*updateLogDeliveryConfigurationRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateLogDeliveryConfigurationRequestWire{ + ConfigId: v.ConfigId, + AccountId: v.AccountId, + Status: v.Status, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/marketplaces/.package.json b/marketplaces/.package.json new file mode 100644 index 0000000..6bd9f08 --- /dev/null +++ b/marketplaces/.package.json @@ -0,0 +1,3 @@ +{ + "package": "marketplaces" +} diff --git a/marketplaces/CHANGELOG.md b/marketplaces/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/marketplaces/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/marketplaces/README.md b/marketplaces/README.md new file mode 100644 index 0000000..4131de6 --- /dev/null +++ b/marketplaces/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/marketplaces + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/marketplaces@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/marketplaces/v1" + +client, err := marketplaces.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/marketplaces/go.mod b/marketplaces/go.mod new file mode 100644 index 0000000..665baa3 --- /dev/null +++ b/marketplaces/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/marketplaces + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/marketplaces/internal/version.go b/marketplaces/internal/version.go new file mode 100644 index 0000000..f06a22d --- /dev/null +++ b/marketplaces/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-marketplaces" + +const Version = "0.0.1-dev.1" diff --git a/marketplaces/v1/client.go b/marketplaces/v1/client.go new file mode 100755 index 0000000..2a0ec9e --- /dev/null +++ b/marketplaces/v1/client.go @@ -0,0 +1,4071 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package marketplaces + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/marketplaces/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Batch get a published listing in the Databricks Marketplace that the consumer +// has access to. +func (c *internalClient) BatchGetListings(ctx context.Context, req *BatchGetListingsRequest, opts ...call.Option) (*BatchGetListingsResponse, error) { + wireReq, err := batchGetListingsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/marketplace-consumer/listings:batchGet" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "ids", wireReq.Ids); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *BatchGetListingsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp batchGetListingsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = batchGetListingsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Batch get a provider in the Databricks Marketplace with at least one visible +// listing. +func (c *internalClient) BatchGetProviders(ctx context.Context, req *BatchGetProvidersRequest, opts ...call.Option) (*BatchGetProvidersResponse, error) { + wireReq, err := batchGetProvidersRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/marketplace-consumer/providers:batchGet" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "ids", wireReq.Ids); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *BatchGetProvidersResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp batchGetProvidersResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = batchGetProvidersResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a personalization request for a listing. +func (c *internalClient) CreatePersonalizationRequest(ctx context.Context, req *CreatePersonalizationRequest, opts ...call.Option) (*CreatePersonalizationResponse, error) { + wireReq, err := createPersonalizationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/marketplace-consumer/listings/") + pb.singleSegment(*req.ListingId) + pb.literal("/personalization-requests") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreatePersonalizationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createPersonalizationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createPersonalizationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List all installations for a particular listing. +func (c *internalClient) GetInstallationDetails(ctx context.Context, req *GetInstallationDetailsRequest, opts ...call.Option) (*ListInstallationsResponse, error) { + wireReq, err := getInstallationDetailsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/marketplace-consumer/listings/") + pb.singleSegment(*req.ListingId) + pb.literal("/installations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListInstallationsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listInstallationsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listInstallationsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// GetInstallationDetailsIter returns an iterator that iterates +// over the results of GetInstallationDetails. +// +// For example: +// +// for item, err := range c.GetInstallationDetailsIter(ctx, &GetInstallationDetailsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each GetInstallationDetails call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// GetInstallationDetails directly. +func (c *internalClient) GetInstallationDetailsIter(ctx context.Context, req *GetInstallationDetailsRequest, opts ...call.Option) iter.Seq2[*InstallationDetail, error] { + return func(yield func(*InstallationDetail, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := GetInstallationDetailsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.GetInstallationDetails(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Installations { + if !yield(&resp.Installations[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get a high level preview of the metadata of listing installable content. +func (c *internalClient) GetListingContent(ctx context.Context, req *GetListingContentMetadataRequest, opts ...call.Option) (*GetListingContentMetadataResponse, error) { + wireReq, err := getListingContentMetadataRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/marketplace-consumer/listings/") + pb.singleSegment(*req.ListingId) + pb.literal("/content") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetListingContentMetadataResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getListingContentMetadataResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getListingContentMetadataResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// GetListingContentIter returns an iterator that iterates +// over the results of GetListingContent. +// +// For example: +// +// for item, err := range c.GetListingContentIter(ctx, &GetListingContentMetadataRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each GetListingContent call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// GetListingContent directly. +func (c *internalClient) GetListingContentIter(ctx context.Context, req *GetListingContentMetadataRequest, opts ...call.Option) iter.Seq2[*SharedDataObject, error] { + return func(yield func(*SharedDataObject, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := GetListingContentMetadataRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.GetListingContent(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.SharedDataObjects { + if !yield(&resp.SharedDataObjects[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get the personalization request for a listing. Each consumer can make at +// *most* one personalization request for a listing. +func (c *internalClient) GetPersonalizationRequestsForConsumer(ctx context.Context, req *GetPersonalizationRequestsForConsumerRequest, opts ...call.Option) (*GetPersonalizationRequestsForConsumerResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/marketplace-consumer/listings/") + pb.singleSegment(*req.ListingId) + pb.literal("/personalization-requests") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPersonalizationRequestsForConsumerResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPersonalizationRequestsForConsumerResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPersonalizationRequestsForConsumerResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a published listing in the Databricks Marketplace that the consumer has +// access to. +func (c *internalClient) GetPublishedListingForConsumer(ctx context.Context, req *GetPublishedListingForConsumerRequest, opts ...call.Option) (*GetPublishedListingForConsumerResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/marketplace-consumer/listings/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPublishedListingForConsumerResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPublishedListingForConsumerResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPublishedListingForConsumerResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a provider in the Databricks Marketplace with at least one visible +// listing. +func (c *internalClient) GetPublishedProviderForConsumer(ctx context.Context, req *GetPublishedProviderForConsumerRequest, opts ...call.Option) (*GetPublishedProviderForConsumerResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/marketplace-consumer/providers/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPublishedProviderForConsumerResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPublishedProviderForConsumerResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPublishedProviderForConsumerResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Install payload associated with a Databricks Marketplace listing. +func (c *internalClient) InstallListing(ctx context.Context, req *CreateInstallationRequest, opts ...call.Option) (*CreateInstallationResponse, error) { + wireReq, err := createInstallationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/marketplace-consumer/listings/") + pb.singleSegment(*req.ListingId) + pb.literal("/installations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateInstallationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createInstallationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createInstallationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List all installations across all listings. +func (c *internalClient) ListInstallations(ctx context.Context, req *ListInstallationsRequest, opts ...call.Option) (*ListAllInstallationsResponse, error) { + wireReq, err := listInstallationsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/marketplace-consumer/installations" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAllInstallationsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAllInstallationsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAllInstallationsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListInstallationsIter returns an iterator that iterates +// over the results of ListInstallations. +// +// For example: +// +// for item, err := range c.ListInstallationsIter(ctx, &ListInstallationsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListInstallations call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListInstallations directly. +func (c *internalClient) ListInstallationsIter(ctx context.Context, req *ListInstallationsRequest, opts ...call.Option) iter.Seq2[*InstallationDetail, error] { + return func(yield func(*InstallationDetail, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListInstallationsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListInstallations(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Installations { + if !yield(&resp.Installations[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get all listings fulfillments associated with a listing. A _fulfillment_ is a +// potential installation. Standard installations contain metadata about the +// attached share or git repo. Only one of these fields will be present. +// Personalized installations contain metadata about the attached share or git +// repo, as well as the Delta Sharing recipient type. +func (c *internalClient) ListListingFulfillments(ctx context.Context, req *ListListingFulfillmentsRequest, opts ...call.Option) (*ListFulfillmentsResponse, error) { + wireReq, err := listListingFulfillmentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/marketplace-consumer/listings/") + pb.singleSegment(*req.ListingId) + pb.literal("/fulfillments") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListFulfillmentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listFulfillmentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listFulfillmentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListListingFulfillmentsIter returns an iterator that iterates +// over the results of ListListingFulfillments. +// +// For example: +// +// for item, err := range c.ListListingFulfillmentsIter(ctx, &ListListingFulfillmentsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListListingFulfillments call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListListingFulfillments directly. +func (c *internalClient) ListListingFulfillmentsIter(ctx context.Context, req *ListListingFulfillmentsRequest, opts ...call.Option) iter.Seq2[*ListingFulfillment, error] { + return func(yield func(*ListingFulfillment, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListListingFulfillmentsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListListingFulfillments(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Fulfillments { + if !yield(&resp.Fulfillments[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List personalization requests for a consumer across all listings. +func (c *internalClient) ListPersonalizationRequestsForConsumer(ctx context.Context, req *ListPersonalizationRequestsForConsumerRequest, opts ...call.Option) (*GetAllPersonalizationRequestsForConsumerResponse, error) { + wireReq, err := listPersonalizationRequestsForConsumerRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/marketplace-consumer/personalization-requests" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetAllPersonalizationRequestsForConsumerResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getAllPersonalizationRequestsForConsumerResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getAllPersonalizationRequestsForConsumerResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListPersonalizationRequestsForConsumerIter returns an iterator that iterates +// over the results of ListPersonalizationRequestsForConsumer. +// +// For example: +// +// for item, err := range c.ListPersonalizationRequestsForConsumerIter(ctx, &ListPersonalizationRequestsForConsumerRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListPersonalizationRequestsForConsumer call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListPersonalizationRequestsForConsumer directly. +func (c *internalClient) ListPersonalizationRequestsForConsumerIter(ctx context.Context, req *ListPersonalizationRequestsForConsumerRequest, opts ...call.Option) iter.Seq2[*PersonalizationRequest, error] { + return func(yield func(*PersonalizationRequest, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListPersonalizationRequestsForConsumerRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListPersonalizationRequestsForConsumer(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.PersonalizationRequests { + if !yield(&resp.PersonalizationRequests[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List all published listings in the Databricks Marketplace that the consumer +// has access to. +func (c *internalClient) ListPublishedListingsForConsumer(ctx context.Context, req *ListPublishedListingsForConsumerRequest, opts ...call.Option) (*GetPublishedListingsForConsumerResponse, error) { + wireReq, err := listPublishedListingsForConsumerRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/marketplace-consumer/listings" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "assets", wireReq.Assets); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "categories", wireReq.Categories); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "tags", wireReq.Tags); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "is_free", wireReq.IsFree); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "is_private_exchange", wireReq.IsPrivateExchange); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "is_staff_pick", wireReq.IsStaffPick); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "provider_ids", wireReq.ProviderIds); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPublishedListingsForConsumerResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPublishedListingsForConsumerResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPublishedListingsForConsumerResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListPublishedListingsForConsumerIter returns an iterator that iterates +// over the results of ListPublishedListingsForConsumer. +// +// For example: +// +// for item, err := range c.ListPublishedListingsForConsumerIter(ctx, &ListPublishedListingsForConsumerRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListPublishedListingsForConsumer call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListPublishedListingsForConsumer directly. +func (c *internalClient) ListPublishedListingsForConsumerIter(ctx context.Context, req *ListPublishedListingsForConsumerRequest, opts ...call.Option) iter.Seq2[*Listing, error] { + return func(yield func(*Listing, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListPublishedListingsForConsumerRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListPublishedListingsForConsumer(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Listings { + if !yield(&resp.Listings[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List all providers in the Databricks Marketplace with at least one visible +// listing. +func (c *internalClient) ListPublishedProvidersForConsumer(ctx context.Context, req *ListPublishedProvidersForConsumerRequest, opts ...call.Option) (*ListPublishedProvidersForConsumerResponse, error) { + wireReq, err := listPublishedProvidersForConsumerRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/marketplace-consumer/providers" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "is_featured", wireReq.IsFeatured); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPublishedProvidersForConsumerResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listPublishedProvidersForConsumerResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listPublishedProvidersForConsumerResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListPublishedProvidersForConsumerIter returns an iterator that iterates +// over the results of ListPublishedProvidersForConsumer. +// +// For example: +// +// for item, err := range c.ListPublishedProvidersForConsumerIter(ctx, &ListPublishedProvidersForConsumerRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListPublishedProvidersForConsumer call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListPublishedProvidersForConsumer directly. +func (c *internalClient) ListPublishedProvidersForConsumerIter(ctx context.Context, req *ListPublishedProvidersForConsumerRequest, opts ...call.Option) iter.Seq2[*ProviderInfo, error] { + return func(yield func(*ProviderInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListPublishedProvidersForConsumerRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListPublishedProvidersForConsumer(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Providers { + if !yield(&resp.Providers[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Search published listings in the Databricks Marketplace that the consumer has +// access to. This query supports a variety of different search parameters and +// performs fuzzy matching. +func (c *internalClient) SearchPublishedListingsForConsumer(ctx context.Context, req *SearchPublishedListingsForConsumerRequest, opts ...call.Option) (*SearchPublishedListingsForConsumerResponse, error) { + wireReq, err := searchPublishedListingsForConsumerRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/marketplace-consumer/search-listings" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "query", wireReq.Query); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "is_free", wireReq.IsFree); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "is_private_exchange", wireReq.IsPrivateExchange); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "provider_ids", wireReq.ProviderIds); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "categories", wireReq.Categories); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "assets", wireReq.Assets); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SearchPublishedListingsForConsumerResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp searchPublishedListingsForConsumerResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = searchPublishedListingsForConsumerResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// SearchPublishedListingsForConsumerIter returns an iterator that iterates +// over the results of SearchPublishedListingsForConsumer. +// +// For example: +// +// for item, err := range c.SearchPublishedListingsForConsumerIter(ctx, &SearchPublishedListingsForConsumerRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each SearchPublishedListingsForConsumer call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// SearchPublishedListingsForConsumer directly. +func (c *internalClient) SearchPublishedListingsForConsumerIter(ctx context.Context, req *SearchPublishedListingsForConsumerRequest, opts ...call.Option) iter.Seq2[*Listing, error] { + return func(yield func(*Listing, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := SearchPublishedListingsForConsumerRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.SearchPublishedListingsForConsumer(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Listings { + if !yield(&resp.Listings[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Uninstall an installation associated with a Databricks Marketplace listing. +func (c *internalClient) UninstallListing(ctx context.Context, req *DeleteInstallationRequest, opts ...call.Option) (*DeleteInstallationResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/marketplace-consumer/listings/") + pb.singleSegment(*req.ListingId) + pb.literal("/installations/") + pb.singleSegment(*req.InstallationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteInstallationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteInstallationResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// This is a update API that will update the part of the fields defined in the +// installation table as well as interact with external services according to +// the fields not included in the installation table 1. the token will be rotate +// if the rotateToken flag is true 2. the token will be forcibly rotate if the +// rotateToken flag is true and the tokenInfo field is empty +func (c *internalClient) UpdateInstallationDetail(ctx context.Context, req *UpdateInstallationRequest, opts ...call.Option) (*UpdateInstallationResponse, error) { + wireReq, err := updateInstallationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/marketplace-consumer/listings/") + pb.singleSegment(*req.ListingId) + pb.literal("/installations/") + pb.singleSegment(*req.InstallationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateInstallationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateInstallationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateInstallationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Associate an exchange with a listing +func (c *internalClient) AddExchangeForListing(ctx context.Context, req *AddExchangeForListingRequest, opts ...call.Option) (*AddExchangeForListingResponse, error) { + wireReq, err := addExchangeForListingRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-exchange/exchanges-for-listing" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AddExchangeForListingResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp addExchangeForListingResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = addExchangeForListingResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create an exchange +func (c *internalClient) CreateExchange(ctx context.Context, req *CreateExchangeRequest, opts ...call.Option) (*CreateExchangeResponse, error) { + wireReq, err := createExchangeRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-exchange/exchanges" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateExchangeResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createExchangeResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createExchangeResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Add an exchange filter. +func (c *internalClient) CreateExchangeFilter(ctx context.Context, req *CreateExchangeFilterRequest, opts ...call.Option) (*CreateExchangeFilterResponse, error) { + wireReq, err := createExchangeFilterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-exchange/filters" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateExchangeFilterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createExchangeFilterResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createExchangeFilterResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a file. Currently, only provider icons and attached notebooks are +// supported. +func (c *internalClient) CreateFile(ctx context.Context, req *CreateFileRequest, opts ...call.Option) (*CreateFileResponse, error) { + wireReq, err := createFileRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-provider/files" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateFileResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createFileResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createFileResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a new listing +func (c *internalClient) CreateListing(ctx context.Context, req *CreateListingRequest, opts ...call.Option) (*CreateListingResponse, error) { + wireReq, err := createListingRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-provider/listing" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateListingResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createListingResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createListingResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a provider +func (c *internalClient) CreateProvider(ctx context.Context, req *CreateProviderRequest, opts ...call.Option) (*CreateProviderResponse, error) { + wireReq, err := createProviderRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-provider/provider" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateProviderResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createProviderResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createProviderResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create provider analytics dashboard. Returns Marketplace specific `id`. Not +// to be confused with the Lakeview dashboard id. +func (c *internalClient) CreateProviderAnalyticsDashboard(ctx context.Context, req *CreateProviderAnalyticsDashboardRequest, opts ...call.Option) (*CreateProviderAnalyticsDashboardResponse, error) { + wireReq, err := createProviderAnalyticsDashboardRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-provider/analytics_dashboard" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateProviderAnalyticsDashboardResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createProviderAnalyticsDashboardResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createProviderAnalyticsDashboardResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// This removes a listing from marketplace. +func (c *internalClient) DeleteExchange(ctx context.Context, req *DeleteExchangeRequest, opts ...call.Option) (*DeleteExchangeResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-exchange/exchanges/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteExchangeResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteExchangeResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete an exchange filter +func (c *internalClient) DeleteExchangeFilter(ctx context.Context, req *DeleteExchangeFilterRequest, opts ...call.Option) (*DeleteExchangeFilterResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-exchange/filters/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteExchangeFilterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteExchangeFilterResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a file +func (c *internalClient) DeleteFile(ctx context.Context, req *DeleteFileRequest, opts ...call.Option) (*DeleteFileResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-provider/files/") + pb.singleSegment(*req.FileId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteFileResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteFileResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a listing +func (c *internalClient) DeleteListing(ctx context.Context, req *DeleteListingRequest, opts ...call.Option) (*DeleteListingResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-provider/listings/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteListingResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteListingResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete provider +func (c *internalClient) DeleteProvider(ctx context.Context, req *DeleteProviderRequest, opts ...call.Option) (*DeleteProviderResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-provider/providers/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteProviderResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteProviderResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get an exchange. +func (c *internalClient) GetExchange(ctx context.Context, req *GetExchangeRequest, opts ...call.Option) (*GetExchangeResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-exchange/exchanges/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetExchangeResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getExchangeResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getExchangeResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a file +func (c *internalClient) GetFile(ctx context.Context, req *GetFileRequest, opts ...call.Option) (*GetFileResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-provider/files/") + pb.singleSegment(*req.FileId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetFileResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getFileResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getFileResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get latest version of provider analytics dashboard. +func (c *internalClient) GetLatestVersionProviderAnalyticsDashboard(ctx context.Context, req *GetLatestVersionProviderAnalyticsDashboardRequest, opts ...call.Option) (*GetLatestVersionProviderAnalyticsDashboardResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-provider/analytics_dashboard/latest" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetLatestVersionProviderAnalyticsDashboardResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getLatestVersionProviderAnalyticsDashboardResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getLatestVersionProviderAnalyticsDashboardResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a listing +func (c *internalClient) GetListing(ctx context.Context, req *GetListingRequest, opts ...call.Option) (*GetListingResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-provider/listings/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetListingResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getListingResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getListingResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List personalization requests to this provider. This will return all +// personalization requests, regardless of which listing they are for. +func (c *internalClient) GetPersonalizationRequestsForProvider(ctx context.Context, req *GetPersonalizationRequestsForProviderRequest, opts ...call.Option) (*GetPersonalizationRequestsForProviderResponse, error) { + wireReq, err := getPersonalizationRequestsForProviderRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-provider/personalization-requests" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPersonalizationRequestsForProviderResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPersonalizationRequestsForProviderResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPersonalizationRequestsForProviderResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// GetPersonalizationRequestsForProviderIter returns an iterator that iterates +// over the results of GetPersonalizationRequestsForProvider. +// +// For example: +// +// for item, err := range c.GetPersonalizationRequestsForProviderIter(ctx, &GetPersonalizationRequestsForProviderRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each GetPersonalizationRequestsForProvider call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// GetPersonalizationRequestsForProvider directly. +func (c *internalClient) GetPersonalizationRequestsForProviderIter(ctx context.Context, req *GetPersonalizationRequestsForProviderRequest, opts ...call.Option) iter.Seq2[*PersonalizationRequest, error] { + return func(yield func(*PersonalizationRequest, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := GetPersonalizationRequestsForProviderRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.GetPersonalizationRequestsForProvider(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.PersonalizationRequests { + if !yield(&resp.PersonalizationRequests[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get provider profile +func (c *internalClient) GetProvider(ctx context.Context, req *GetProviderRequest, opts ...call.Option) (*GetProviderResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-provider/providers/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetProviderResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getProviderResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getProviderResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List exchange filter +func (c *internalClient) ListExchangeFilters(ctx context.Context, req *ListExchangeFiltersRequest, opts ...call.Option) (*ListExchangeFiltersResponse, error) { + wireReq, err := listExchangeFiltersRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-exchange/filters" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "exchange_id", wireReq.ExchangeId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListExchangeFiltersResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listExchangeFiltersResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listExchangeFiltersResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListExchangeFiltersIter returns an iterator that iterates +// over the results of ListExchangeFilters. +// +// For example: +// +// for item, err := range c.ListExchangeFiltersIter(ctx, &ListExchangeFiltersRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListExchangeFilters call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListExchangeFilters directly. +func (c *internalClient) ListExchangeFiltersIter(ctx context.Context, req *ListExchangeFiltersRequest, opts ...call.Option) iter.Seq2[*ExchangeFilter, error] { + return func(yield func(*ExchangeFilter, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListExchangeFiltersRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListExchangeFilters(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Filters { + if !yield(&resp.Filters[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List exchanges visible to provider +func (c *internalClient) ListExchanges(ctx context.Context, req *ListExchangesRequest, opts ...call.Option) (*ListExchangesResponse, error) { + wireReq, err := listExchangesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-exchange/exchanges" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListExchangesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listExchangesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listExchangesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListExchangesIter returns an iterator that iterates +// over the results of ListExchanges. +// +// For example: +// +// for item, err := range c.ListExchangesIter(ctx, &ListExchangesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListExchanges call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListExchanges directly. +func (c *internalClient) ListExchangesIter(ctx context.Context, req *ListExchangesRequest, opts ...call.Option) iter.Seq2[*Exchange, error] { + return func(yield func(*Exchange, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListExchangesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListExchanges(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Exchanges { + if !yield(&resp.Exchanges[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List exchanges associated with a listing +func (c *internalClient) ListExchangesForListing(ctx context.Context, req *ListExchangesForListingRequest, opts ...call.Option) (*ListExchangesForListingResponse, error) { + wireReq, err := listExchangesForListingRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-exchange/exchanges-for-listing" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "listing_id", wireReq.ListingId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListExchangesForListingResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listExchangesForListingResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listExchangesForListingResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListExchangesForListingIter returns an iterator that iterates +// over the results of ListExchangesForListing. +// +// For example: +// +// for item, err := range c.ListExchangesForListingIter(ctx, &ListExchangesForListingRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListExchangesForListing call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListExchangesForListing directly. +func (c *internalClient) ListExchangesForListingIter(ctx context.Context, req *ListExchangesForListingRequest, opts ...call.Option) iter.Seq2[*ExchangeListing, error] { + return func(yield func(*ExchangeListing, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListExchangesForListingRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListExchangesForListing(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ExchangeListing { + if !yield(&resp.ExchangeListing[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List files attached to a parent entity. +func (c *internalClient) ListFiles(ctx context.Context, req *ListFilesRequest, opts ...call.Option) (*ListFilesResponse, error) { + wireReq, err := listFilesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-provider/files" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "file_parent", wireReq.FileParent); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListFilesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listFilesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listFilesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListFilesIter returns an iterator that iterates +// over the results of ListFiles. +// +// For example: +// +// for item, err := range c.ListFilesIter(ctx, &ListFilesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListFiles call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListFiles directly. +func (c *internalClient) ListFilesIter(ctx context.Context, req *ListFilesRequest, opts ...call.Option) iter.Seq2[*FileInfo, error] { + return func(yield func(*FileInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListFilesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListFiles(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.FileInfos { + if !yield(&resp.FileInfos[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List listings owned by this provider +func (c *internalClient) ListListings(ctx context.Context, req *ListListingsRequest, opts ...call.Option) (*GetListingsResponse, error) { + wireReq, err := listListingsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-provider/listings" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetListingsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getListingsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getListingsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListListingsIter returns an iterator that iterates +// over the results of ListListings. +// +// For example: +// +// for item, err := range c.ListListingsIter(ctx, &ListListingsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListListings call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListListings directly. +func (c *internalClient) ListListingsIter(ctx context.Context, req *ListListingsRequest, opts ...call.Option) iter.Seq2[*Listing, error] { + return func(yield func(*Listing, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListListingsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListListings(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Listings { + if !yield(&resp.Listings[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List listings associated with an exchange +func (c *internalClient) ListListingsForExchange(ctx context.Context, req *ListListingsForExchangeRequest, opts ...call.Option) (*ListListingsForExchangeResponse, error) { + wireReq, err := listListingsForExchangeRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-exchange/listings-for-exchange" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "exchange_id", wireReq.ExchangeId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListListingsForExchangeResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listListingsForExchangeResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listListingsForExchangeResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListListingsForExchangeIter returns an iterator that iterates +// over the results of ListListingsForExchange. +// +// For example: +// +// for item, err := range c.ListListingsForExchangeIter(ctx, &ListListingsForExchangeRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListListingsForExchange call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListListingsForExchange directly. +func (c *internalClient) ListListingsForExchangeIter(ctx context.Context, req *ListListingsForExchangeRequest, opts ...call.Option) iter.Seq2[*ExchangeListing, error] { + return func(yield func(*ExchangeListing, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListListingsForExchangeRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListListingsForExchange(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ExchangeListings { + if !yield(&resp.ExchangeListings[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get provider analytics dashboard. +func (c *internalClient) ListProviderAnalyticsDashboard(ctx context.Context, req *ListProviderAnalyticsDashboardRequest, opts ...call.Option) (*ListProviderAnalyticsDashboardResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-provider/analytics_dashboard" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListProviderAnalyticsDashboardResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listProviderAnalyticsDashboardResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listProviderAnalyticsDashboardResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List provider profiles for account. +func (c *internalClient) ListProviders(ctx context.Context, req *ListProvidersRequest, opts ...call.Option) (*ListProvidersResponse, error) { + wireReq, err := listProvidersRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/marketplace-provider/providers" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListProvidersResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listProvidersResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listProvidersResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListProvidersIter returns an iterator that iterates +// over the results of ListProviders. +// +// For example: +// +// for item, err := range c.ListProvidersIter(ctx, &ListProvidersRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListProviders call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListProviders directly. +func (c *internalClient) ListProvidersIter(ctx context.Context, req *ListProvidersRequest, opts ...call.Option) iter.Seq2[*ProviderInfo, error] { + return func(yield func(*ProviderInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListProvidersRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListProviders(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Providers { + if !yield(&resp.Providers[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Disassociate an exchange with a listing +func (c *internalClient) RemoveExchangeForListing(ctx context.Context, req *RemoveExchangeForListingRequest, opts ...call.Option) (*RemoveExchangeForListingResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-exchange/exchanges-for-listing/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RemoveExchangeForListingResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &RemoveExchangeForListingResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update an exchange +func (c *internalClient) UpdateExchange(ctx context.Context, req *UpdateExchangeRequest, opts ...call.Option) (*UpdateExchangeResponse, error) { + wireReq, err := updateExchangeRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-exchange/exchanges/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateExchangeResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateExchangeResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateExchangeResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update an exchange filter. +func (c *internalClient) UpdateExchangeFilter(ctx context.Context, req *UpdateExchangeFilterRequest, opts ...call.Option) (*UpdateExchangeFilterResponse, error) { + wireReq, err := updateExchangeFilterRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-exchange/filters/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateExchangeFilterResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateExchangeFilterResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateExchangeFilterResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a listing +func (c *internalClient) UpdateListing(ctx context.Context, req *UpdateListingRequest, opts ...call.Option) (*UpdateListingResponse, error) { + wireReq, err := updateListingRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-provider/listings/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateListingResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateListingResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateListingResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update personalization request. This method only permits updating the status +// of the request. +func (c *internalClient) UpdatePersonalizationRequestStatus(ctx context.Context, req *UpdatePersonalizationRequestStatusRequest, opts ...call.Option) (*UpdatePersonalizationRequestStatusResponse, error) { + wireReq, err := updatePersonalizationRequestStatusRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-provider/listings/") + pb.singleSegment(*req.ListingId) + pb.literal("/personalization-requests/") + pb.singleSegment(*req.RequestId) + pb.literal("/request-status") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdatePersonalizationRequestStatusResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updatePersonalizationRequestStatusResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updatePersonalizationRequestStatusResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update provider profile +func (c *internalClient) UpdateProvider(ctx context.Context, req *UpdateProviderRequest, opts ...call.Option) (*UpdateProviderResponse, error) { + wireReq, err := updateProviderRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-provider/providers/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateProviderResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateProviderResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateProviderResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update provider analytics dashboard. +func (c *internalClient) UpdateProviderAnalyticsDashboard(ctx context.Context, req *UpdateProviderAnalyticsDashboardRequest, opts ...call.Option) (*UpdateProviderAnalyticsDashboardResponse, error) { + wireReq, err := updateProviderAnalyticsDashboardRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/marketplace-provider/analytics_dashboard/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateProviderAnalyticsDashboardResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateProviderAnalyticsDashboardResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateProviderAnalyticsDashboardResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/marketplaces/v1/genhelper.go b/marketplaces/v1/genhelper.go new file mode 100755 index 0000000..aa6797f --- /dev/null +++ b/marketplaces/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package marketplaces + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/marketplaces/v1/model.go b/marketplaces/v1/model.go new file mode 100755 index 0000000..54361ad --- /dev/null +++ b/marketplaces/v1/model.go @@ -0,0 +1,975 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package marketplaces + +type AssetType string + +const ( + AssetType_Unspecified AssetType = "" + AssetType_AssetTypeGitRepo AssetType = "ASSET_TYPE_GIT_REPO" + AssetType_AssetTypeDataTable AssetType = "ASSET_TYPE_DATA_TABLE" + AssetType_AssetTypeModel AssetType = "ASSET_TYPE_MODEL" + AssetType_AssetTypeNotebook AssetType = "ASSET_TYPE_NOTEBOOK" + // (MP-2408): media-based assets generally involve volumes; however some volumes + // files (e.g. CSV) still correspond to datasets as such, add a new asset type + // to specify media + AssetType_AssetTypeMedia AssetType = "ASSET_TYPE_MEDIA" + AssetType_AssetTypePartnerIntegration AssetType = "ASSET_TYPE_PARTNER_INTEGRATION" + AssetType_AssetTypeApp AssetType = "ASSET_TYPE_APP" + AssetType_AssetTypeMcp AssetType = "ASSET_TYPE_MCP" +) + +type Category string + +const ( + Category_Unspecified Category = "" + Category_AdvertisingAndMarketing Category = "ADVERTISING_AND_MARKETING" + Category_ClimateAndEnvironment Category = "CLIMATE_AND_ENVIRONMENT" + Category_Commerce Category = "COMMERCE" + Category_Demographics Category = "DEMOGRAPHICS" + Category_Economics Category = "ECONOMICS" + Category_Education Category = "EDUCATION" + Category_Energy Category = "ENERGY" + Category_Financial Category = "FINANCIAL" + Category_Gaming Category = "GAMING" + Category_Geospatial Category = "GEOSPATIAL" + Category_Health Category = "HEALTH" + Category_LookupTables Category = "LOOKUP_TABLES" + Category_Manufacturing Category = "MANUFACTURING" + Category_Media Category = "MEDIA" + Category_Other Category = "OTHER" + Category_PublicSector Category = "PUBLIC_SECTOR" + Category_Retail Category = "RETAIL" + Category_Security Category = "SECURITY" + Category_ScienceAndResearch Category = "SCIENCE_AND_RESEARCH" + Category_Sports Category = "SPORTS" + Category_TransportationAndLogistics Category = "TRANSPORTATION_AND_LOGISTICS" + Category_TravelAndTourism Category = "TRAVEL_AND_TOURISM" +) + +type Cost string + +const ( + Cost_Unspecified Cost = "" + Cost_Free Cost = "FREE" + Cost_Paid Cost = "PAID" +) + +type DataRefresh string + +const ( + DataRefresh_Unspecified DataRefresh = "" + DataRefresh_None DataRefresh = "NONE" + DataRefresh_Second DataRefresh = "SECOND" + DataRefresh_Minute DataRefresh = "MINUTE" + DataRefresh_Hourly DataRefresh = "HOURLY" + DataRefresh_Daily DataRefresh = "DAILY" + DataRefresh_Weekly DataRefresh = "WEEKLY" + DataRefresh_Monthly DataRefresh = "MONTHLY" + DataRefresh_Quarterly DataRefresh = "QUARTERLY" + DataRefresh_Yearly DataRefresh = "YEARLY" +) + +type DeltaSharingRecipientType string + +const ( + DeltaSharingRecipientType_Unspecified DeltaSharingRecipientType = "" + DeltaSharingRecipientType_DeltaSharingRecipientTypeDatabricks DeltaSharingRecipientType = "DELTA_SHARING_RECIPIENT_TYPE_DATABRICKS" + DeltaSharingRecipientType_DeltaSharingRecipientTypeOpen DeltaSharingRecipientType = "DELTA_SHARING_RECIPIENT_TYPE_OPEN" +) + +type ExchangeFilterType string + +const ( + ExchangeFilterType_Unspecified ExchangeFilterType = "" + ExchangeFilterType_GlobalMetastoreId ExchangeFilterType = "GLOBAL_METASTORE_ID" +) + +type FileParentType string + +const ( + FileParentType_Unspecified FileParentType = "" + FileParentType_Provider FileParentType = "PROVIDER" + FileParentType_Listing FileParentType = "LISTING" + FileParentType_ListingResource FileParentType = "LISTING_RESOURCE" +) + +type FileStatus string + +const ( + FileStatus_Unspecified FileStatus = "" + // Published files have been sanitized by Marketplace backend and can be viewed + // by consumers. + FileStatus_FileStatusPublished FileStatus = "FILE_STATUS_PUBLISHED" + // Created files start in staging. These are viewable by provider APIs but not + // consumer APIs. + FileStatus_FileStatusStaging FileStatus = "FILE_STATUS_STAGING" + // Indicates this file is in the process of being sanitized. + FileStatus_FileStatusSanitizing FileStatus = "FILE_STATUS_SANITIZING" + // Something went wrong with sanitization, refer to the status message for more + // information. + FileStatus_FileStatusSanitizationFailed FileStatus = "FILE_STATUS_SANITIZATION_FAILED" +) + +type FulfillmentType string + +const ( + FulfillmentType_Unspecified FulfillmentType = "" + FulfillmentType_RequestAccess FulfillmentType = "REQUEST_ACCESS" + FulfillmentType_Install FulfillmentType = "INSTALL" +) + +type InstallationStatus string + +const ( + InstallationStatus_Unspecified InstallationStatus = "" + InstallationStatus_Installed InstallationStatus = "INSTALLED" + InstallationStatus_Failed InstallationStatus = "FAILED" +) + +type ListingShareType string + +const ( + ListingShareType_Unspecified ListingShareType = "" + ListingShareType_Sample ListingShareType = "SAMPLE" + ListingShareType_Full ListingShareType = "FULL" +) + +// Enums +type ListingStatus string + +const ( + ListingStatus_Unspecified ListingStatus = "" + ListingStatus_Draft ListingStatus = "DRAFT" + ListingStatus_Pending ListingStatus = "PENDING" + ListingStatus_Published ListingStatus = "PUBLISHED" + ListingStatus_Suspended ListingStatus = "SUSPENDED" +) + +type ListingTagType string + +const ( + ListingTagType_Unspecified ListingTagType = "" + ListingTagType_ListingTagTypeLanguage ListingTagType = "LISTING_TAG_TYPE_LANGUAGE" + ListingTagType_ListingTagTypeTask ListingTagType = "LISTING_TAG_TYPE_TASK" +) + +type ListingType string + +const ( + ListingType_Unspecified ListingType = "" + ListingType_Standard ListingType = "STANDARD" + ListingType_Personalized ListingType = "PERSONALIZED" +) + +type MarketplaceFileType string + +const ( + MarketplaceFileType_Unspecified MarketplaceFileType = "" + MarketplaceFileType_ProviderIcon MarketplaceFileType = "PROVIDER_ICON" + MarketplaceFileType_EmbeddedNotebook MarketplaceFileType = "EMBEDDED_NOTEBOOK" + MarketplaceFileType_App MarketplaceFileType = "APP" +) + +type PersonalizationRequestStatus string + +const ( + PersonalizationRequestStatus_Unspecified PersonalizationRequestStatus = "" + PersonalizationRequestStatus_New PersonalizationRequestStatus = "NEW" + // Pending already defined for ListingStatus + PersonalizationRequestStatus_RequestPending PersonalizationRequestStatus = "REQUEST_PENDING" + PersonalizationRequestStatus_Fulfilled PersonalizationRequestStatus = "FULFILLED" + PersonalizationRequestStatus_Denied PersonalizationRequestStatus = "DENIED" +) + +type Visibility string + +const ( + Visibility_Unspecified Visibility = "" + Visibility_Public Visibility = "PUBLIC" + Visibility_Private Visibility = "PRIVATE" +) + +type AddExchangeForListingRequest struct { + ListingId *string + ExchangeId *string +} + +type AddExchangeForListingResponse struct { + ExchangeForListing *ExchangeListing +} + +type BatchGetListingsRequest struct { + Ids []string +} + +type BatchGetListingsResponse struct { + Listings []Listing +} + +type BatchGetProvidersRequest struct { + Ids []string +} + +type BatchGetProvidersResponse struct { + Providers []ProviderInfo +} + +type ConsumerTerms struct { + Version *string +} + +// contact info for the consumer requesting data or performing a listing +// installation. +type ContactInfo struct { + FirstName *string + LastName *string + Email *string + Company *string +} + +type CreateExchangeFilterRequest struct { + Filter *ExchangeFilter +} + +type CreateExchangeFilterResponse struct { + FilterId *string +} + +type CreateExchangeRequest struct { + Exchange *Exchange +} + +type CreateExchangeResponse struct { + ExchangeId *string +} + +type CreateFileRequest struct { + FileParent *FileParent + MarketplaceFileType MarketplaceFileType + MimeType *string + DisplayName *string +} + +type CreateFileResponse struct { + // Pre-signed POST URL to blob storage + UploadUrl *string + FileInfo *FileInfo +} + +type CreateInstallationRequest struct { + ListingId *string + ShareName *string + CatalogName *string + // for git repo installations + RepoDetail *RepoInstallation + RecipientType DeltaSharingRecipientType + AcceptedConsumerTerms *ConsumerTerms +} + +type CreateInstallationResponse struct { + Installation *InstallationDetail +} + +type CreateListingRequest struct { + Listing *Listing +} + +type CreateListingResponse struct { + ListingId *string +} + +// Data request messages also creates a lead (maybe). +type CreatePersonalizationRequest struct { + ListingId *string + Comment *string + IntendedUse *string + FirstName *string + LastName *string + Company *string + IsFromLighthouse *bool + RecipientType DeltaSharingRecipientType + AcceptedConsumerTerms *ConsumerTerms +} + +type CreatePersonalizationResponse struct { + Id *string +} + +type CreateProviderAnalyticsDashboardRequest struct { +} + +type CreateProviderAnalyticsDashboardResponse struct { + Id *string +} + +type CreateProviderRequest struct { + Provider *ProviderInfo +} + +type CreateProviderResponse struct { + Id *string +} + +type DataRefreshInfo struct { + Interval *int64 + Unit DataRefresh +} + +type DeleteExchangeFilterRequest struct { + Id *string +} + +type DeleteExchangeFilterResponse struct { +} + +type DeleteExchangeRequest struct { + Id *string +} + +type DeleteExchangeResponse struct { +} + +type DeleteFileRequest struct { + FileId *string +} + +type DeleteFileResponse struct { +} + +type DeleteInstallationRequest struct { + ListingId *string + InstallationId *string +} + +type DeleteInstallationResponse struct { +} + +type DeleteListingRequest struct { + Id *string +} + +type DeleteListingResponse struct { +} + +type DeleteProviderRequest struct { + Id *string +} + +type DeleteProviderResponse struct { +} + +type Exchange struct { + Id *string + Name *string + Comment *string + Filters []ExchangeFilter + CreatedAt *int64 + CreatedBy *string + UpdatedAt *int64 + UpdatedBy *string + LinkedListings []ExchangeListing +} + +type ExchangeFilter struct { + Id *string + ExchangeId *string + FilterValue *string + Name *string + CreatedAt *int64 + CreatedBy *string + UpdatedAt *int64 + UpdatedBy *string + FilterType ExchangeFilterType +} + +type ExchangeListing struct { + Id *string + ExchangeId *string + ExchangeName *string + ListingId *string + ListingName *string + CreatedAt *int64 + CreatedBy *string +} + +type FileInfo struct { + Id *string + MarketplaceFileType MarketplaceFileType + FileParent *FileParent + MimeType *string + DownloadLink *string + CreatedAt *int64 + UpdatedAt *int64 + // Name displayed to users for applicable files, e.g. embedded notebooks + DisplayName *string + Status FileStatus + // Populated if status is in a failed state with more information on reason for + // the failure. + StatusMessage *string +} + +type FileParent struct { + ParentId *string + FileParentType FileParentType +} + +type GetAllPersonalizationRequestsForConsumerResponse struct { + PersonalizationRequests []PersonalizationRequest + NextPageToken *string +} + +type GetExchangeRequest struct { + Id *string +} + +type GetExchangeResponse struct { + Exchange *Exchange +} + +type GetFileRequest struct { + FileId *string +} + +type GetFileResponse struct { + FileInfo *FileInfo +} + +type GetInstallationDetailsRequest struct { + ListingId *string + PageToken *string + PageSize *int +} + +// this is effectively a static request for now and will return latest version +// of the dashboard template that exists on server.. +type GetLatestVersionProviderAnalyticsDashboardRequest struct { +} + +type GetLatestVersionProviderAnalyticsDashboardResponse struct { + // version here is latest logical version of the dashboard template + Version *int64 +} + +type GetListingContentMetadataRequest struct { + ListingId *string + PageToken *string + PageSize *int +} + +type GetListingContentMetadataResponse struct { + SharedDataObjects []SharedDataObject + NextPageToken *string +} + +type GetListingRequest struct { + Id *string +} + +type GetListingResponse struct { + Listing *Listing +} + +type GetListingsResponse struct { + Listings []Listing + NextPageToken *string +} + +type GetPersonalizationRequestsForConsumerRequest struct { + ListingId *string +} + +type GetPersonalizationRequestsForConsumerResponse struct { + PersonalizationRequests []PersonalizationRequest +} + +type GetPersonalizationRequestsForProviderRequest struct { + PageToken *string + PageSize *int +} + +type GetPersonalizationRequestsForProviderResponse struct { + PersonalizationRequests []PersonalizationRequest + NextPageToken *string +} + +type GetProviderRequest struct { + Id *string +} + +type GetProviderResponse struct { + Provider *ProviderInfo +} + +type GetPublishedListingForConsumerRequest struct { + Id *string +} + +type GetPublishedListingForConsumerResponse struct { + Listing *Listing +} + +type GetPublishedListingsForConsumerResponse struct { + Listings []Listing + NextPageToken *string +} + +type GetPublishedProviderForConsumerRequest struct { + Id *string +} + +type GetPublishedProviderForConsumerResponse struct { + Provider *ProviderInfo +} + +type InstallationDetail struct { + Id *string + ListingId *string + ShareName *string + CatalogName *string + InstalledOn *int64 + Status InstallationStatus + ErrorMessage *string + ListingName *string + RepoName *string + RepoPath *string + RecipientType DeltaSharingRecipientType + Tokens []TokenInfo + TokenDetail *TokenDetail +} + +type ListAllInstallationsResponse struct { + Installations []InstallationDetail + NextPageToken *string +} + +type ListExchangeFiltersRequest struct { + ExchangeId *string + PageToken *string + PageSize *int +} + +type ListExchangeFiltersResponse struct { + Filters []ExchangeFilter + NextPageToken *string +} + +type ListExchangesForListingRequest struct { + ListingId *string + PageToken *string + PageSize *int +} + +type ListExchangesForListingResponse struct { + ExchangeListing []ExchangeListing + NextPageToken *string +} + +type ListExchangesRequest struct { + PageToken *string + PageSize *int +} + +type ListExchangesResponse struct { + Exchanges []Exchange + NextPageToken *string +} + +type ListFilesRequest struct { + FileParent *FileParent + PageToken *string + PageSize *int +} + +type ListFilesResponse struct { + FileInfos []FileInfo + NextPageToken *string +} + +type ListFulfillmentsResponse struct { + Fulfillments []ListingFulfillment + NextPageToken *string +} + +type ListInstallationsRequest struct { + PageToken *string + PageSize *int +} + +type ListInstallationsResponse struct { + Installations []InstallationDetail + NextPageToken *string +} + +type ListListingFulfillmentsRequest struct { + ListingId *string + PageToken *string + PageSize *int +} + +type ListListingsForExchangeRequest struct { + ExchangeId *string + PageToken *string + PageSize *int +} + +type ListListingsForExchangeResponse struct { + ExchangeListings []ExchangeListing + NextPageToken *string +} + +type ListListingsRequest struct { + PageToken *string + PageSize *int +} + +type ListPersonalizationRequestsForConsumerRequest struct { + PageToken *string + PageSize *int +} + +type ListProviderAnalyticsDashboardRequest struct { +} + +type ListProviderAnalyticsDashboardResponse struct { + Id *string + Version *int64 + // dashboard_id will be used to open Lakeview dashboard. + DashboardId *string +} + +type ListProvidersRequest struct { + PageToken *string + PageSize *int +} + +type ListProvidersResponse struct { + Providers []ProviderInfo + NextPageToken *string +} + +// Listing messages. +type ListPublishedListingsForConsumerRequest struct { + PageToken *string + PageSize *int + // Matches any of the following asset types + Assets []AssetType + // Matches any of the following categories + Categories []Category + // Matches listings with this tag + Tags *ListingTag + // Filters each listing based on if it is free. + IsFree *bool + // Filters each listing based on if it is a private exchange. + IsPrivateExchange *bool + // Filters each listing based on whether it is a staff pick. + IsStaffPick *bool + // Matches any of the following provider ids + ProviderIds []string +} + +type ListPublishedProvidersForConsumerRequest struct { + PageToken *string + PageSize *int + IsFeatured *bool +} + +type ListPublishedProvidersForConsumerResponse struct { + Providers []ProviderInfo + NextPageToken *string +} + +type Listing struct { + Id *string + Summary *ListingSummary + Detail *ListingDetail +} + +type ListingDetail struct { + Description *string + TermsOfService *string + DocumentationLink *string + SupportLink *string + FileIds []string + PrivacyPolicyLink *string + EmbeddedNotebookFileInfos []FileInfo + // Which geo region the listing data is collected from + GeographicalCoverage *string + // Whether the dataset is free or paid + Cost Cost + // What the pricing model is (e.g. paid, subscription, paid upfront); should + // only be present if cost is paid + PricingModel *string + // How often data is updated + UpdateFrequency *DataRefreshInfo + // Smallest unit of time in the dataset + CollectionGranularity *DataRefreshInfo + // The starting date timestamp for when the data spans + CollectionDateStart *int64 + // The ending date timestamp for when the data spans + CollectionDateEnd *int64 + // Where/how the data is sourced + DataSource *string + // size of the dataset in GB + Size *float64 + // Type of assets included in the listing. eg. GIT_REPO, DATA_TABLE, MODEL, + // NOTEBOOK + Assets []AssetType + // ID 20, 21 removed don't use License of the data asset - Required for listings + // with model based assets + License *string + // Listing tags - Simple key value pair to annotate listings. When should I use + // tags vs dedicated fields? Using tags avoids the need to add new columns in + // the database for new annotations. However, this should be used sparingly + // since tags are stored as key value pair. Use tags only: 1. If the field is + // optional and won't need to have NOT NULL integrity check 2. The value is + // fairly fixed, static and low cardinality (eg. enums). 3. The value won't be + // used in filters or joins with other tables. + Tags []ListingTag +} + +type ListingFulfillment struct { + ListingId *string + FulfillmentType FulfillmentType + ShareInfo *ShareInfo + RepoInfo *RepoInfo + RecipientType DeltaSharingRecipientType +} + +type ListingSetting struct { + Visibility Visibility +} + +type ListingSummary struct { + Name *string + Subtitle *string + Status ListingStatus + Share *ShareInfo + ProviderRegion *RegionInfo + Setting *ListingSetting + CreatedAt *int64 + CreatedBy *string + UpdatedAt *int64 + UpdatedBy *string + PublishedAt *int64 + PublishedBy *string + Categories []Category + ListingType ListingType + CreatedById *int64 + UpdatedById *int64 + ProviderId *string + ExchangeIds []string + // if a git repo is being created, a listing will be initialized with this field + // as opposed to a share + GitRepo *RepoInfo +} + +type ListingTag struct { + // Tag name (enum) + TagName ListingTagType + // String representation of the tag value. Values should be string literals (no + // complex types) + TagValues []string +} + +type PersonalizationRequest struct { + Id *string + ConsumerRegion *RegionInfo + ContactInfo *ContactInfo + Comment *string + IntendedUse *string + Status PersonalizationRequestStatus + StatusMessage *string + // Share information is required for data listings but should be empty/ignored + // for non-data listings (MCP and App). + Share *ShareInfo + CreatedAt *int64 + ListingId *string + UpdatedAt *int64 + MetastoreId *string + ListingName *string + IsFromLighthouse *bool + ProviderId *string + RecipientType DeltaSharingRecipientType +} + +type ProviderInfo struct { + Id *string + Name *string + Description *string + IconFilePath *string + BusinessContactEmail *string + SupportContactEmail *string + // is_featured is accessible by consumers only + IsFeatured *bool + // published_by is only applicable to data aggregators (e.g. Crux) + PublishedBy *string + CompanyWebsiteLink *string + IconFileId *string + TermOfServiceLink *string + PrivacyPolicyLink *string + DarkModeIconFileId *string + DarkModeIconFilePath *string +} + +type RegionInfo struct { + Cloud *string + Region *string +} + +type RemoveExchangeForListingRequest struct { + Id *string +} + +type RemoveExchangeForListingResponse struct { +} + +type RepoInfo struct { + // the git repo url e.g. https://github.com/databrickslabs/dolly.git + GitRepoUrl *string +} + +type RepoInstallation struct { + // the user-specified repo name for their installed git repo listing + RepoName *string + // refers to the full url file path that navigates the user to the repo's + // entrypoint (e.g. a README.md file, or the repo file view in the unified UI) + // should just be a relative path + RepoPath *string +} + +type SearchPublishedListingsForConsumerRequest struct { + // Fuzzy matches query + Query *string + IsFree *bool + IsPrivateExchange *bool + // Matches any of the following provider ids + ProviderIds []string + // Matches any of the following categories + Categories []Category + // Matches any of the following asset types + Assets []AssetType + PageToken *string + PageSize *int +} + +type SearchPublishedListingsForConsumerResponse struct { + Listings []Listing + NextPageToken *string +} + +type ShareInfo struct { + Name *string + Type ListingShareType +} + +type SharedDataObject struct { + // Name of the shared object + Name *string + // The type of the data object. Could be one of: TABLE, SCHEMA, NOTEBOOK_FILE, + // MODEL, VOLUME + DataObjectType *string +} + +type TokenDetail struct { + // These field names must follow the delta sharing protocol. Original message: + // RetrieveToken.Response in managed-catalog/api/messages/recipient.proto + ShareCredentialsVersion *int + BearerToken *string + Endpoint *string + ExpirationTime *string +} + +type TokenInfo struct { + // Unique id of the Recipient Token. + Id *string + // Time at which this Recipient Token was created, in epoch milliseconds. + CreatedAt *int64 + // Username of Recipient Token creator. + CreatedBy *string + // Full activation url to retrieve the access token. It will be empty if the + // token is already retrieved. + ActivationUrl *string + // Expiration timestamp of the token in epoch milliseconds. + ExpirationTime *int64 + // Time at which this Recipient Token was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of Recipient Token updater. + UpdatedBy *string +} + +type UpdateExchangeFilterRequest struct { + Id *string + Filter *ExchangeFilter +} + +type UpdateExchangeFilterResponse struct { + Filter *ExchangeFilter +} + +type UpdateExchangeRequest struct { + Id *string + Exchange *Exchange +} + +type UpdateExchangeResponse struct { + Exchange *Exchange +} + +type UpdateInstallationRequest struct { + ListingId *string + InstallationId *string + Installation *InstallationDetail + RotateToken *bool +} + +type UpdateInstallationResponse struct { + Installation *InstallationDetail +} + +type UpdateListingRequest struct { + Id *string + Listing *Listing +} + +type UpdateListingResponse struct { + Listing *Listing +} + +type UpdatePersonalizationRequestStatusRequest struct { + ListingId *string + RequestId *string + Status PersonalizationRequestStatus + Reason *string + Share *ShareInfo +} + +type UpdatePersonalizationRequestStatusResponse struct { + Request *PersonalizationRequest +} + +type UpdateProviderAnalyticsDashboardRequest struct { + // id is immutable property and can't be updated. + Id *string + // this is the version of the dashboard template we want to update our user to + // current expectation is that it should be equal to latest version of the + // dashboard template + Version *int64 +} + +type UpdateProviderAnalyticsDashboardResponse struct { + // id & version should be the same as the request + Id *string + Version *int64 + // this is newly created Lakeview dashboard for the user + DashboardId *string +} + +type UpdateProviderRequest struct { + Id *string + Provider *ProviderInfo +} + +type UpdateProviderResponse struct { + Provider *ProviderInfo +} diff --git a/marketplaces/v1/wire.go b/marketplaces/v1/wire.go new file mode 100755 index 0000000..fa86c36 --- /dev/null +++ b/marketplaces/v1/wire.go @@ -0,0 +1,2380 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package marketplaces + +import ( + "fmt" +) + +type addExchangeForListingRequestWire struct { + ListingId *string `json:"listing_id,omitempty"` + ExchangeId *string `json:"exchange_id,omitempty"` +} + +func addExchangeForListingRequestToWire(v *AddExchangeForListingRequest) (*addExchangeForListingRequestWire, error) { + if v == nil { + return nil, nil + } + return &addExchangeForListingRequestWire{ + ListingId: v.ListingId, + ExchangeId: v.ExchangeId, + }, nil +} + +type addExchangeForListingResponseWire struct { + ExchangeForListing *exchangeListingWire `json:"exchange_for_listing,omitempty"` +} + +func addExchangeForListingResponseFromWire(w *addExchangeForListingResponseWire) (*AddExchangeForListingResponse, error) { + if w == nil { + return nil, nil + } + exchangeForListingPublicValue, err := exchangeListingFromWire(w.ExchangeForListing) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AddExchangeForListingResponse.ExchangeForListing", err) + } + return &AddExchangeForListingResponse{ + ExchangeForListing: exchangeForListingPublicValue, + }, nil +} + +type batchGetListingsRequestWire struct { + Ids []string `json:"ids,omitempty"` +} + +func batchGetListingsRequestToWire(v *BatchGetListingsRequest) (*batchGetListingsRequestWire, error) { + if v == nil { + return nil, nil + } + return &batchGetListingsRequestWire{ + Ids: v.Ids, + }, nil +} + +type batchGetListingsResponseWire struct { + Listings []listingWire `json:"listings,omitempty"` +} + +func batchGetListingsResponseFromWire(w *batchGetListingsResponseWire) (*BatchGetListingsResponse, error) { + if w == nil { + return nil, nil + } + listingsPublicValue, err := convertSlice(w.Listings, listingFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BatchGetListingsResponse.Listings", err) + } + return &BatchGetListingsResponse{ + Listings: listingsPublicValue, + }, nil +} + +type batchGetProvidersRequestWire struct { + Ids []string `json:"ids,omitempty"` +} + +func batchGetProvidersRequestToWire(v *BatchGetProvidersRequest) (*batchGetProvidersRequestWire, error) { + if v == nil { + return nil, nil + } + return &batchGetProvidersRequestWire{ + Ids: v.Ids, + }, nil +} + +type batchGetProvidersResponseWire struct { + Providers []providerInfoWire `json:"providers,omitempty"` +} + +func batchGetProvidersResponseFromWire(w *batchGetProvidersResponseWire) (*BatchGetProvidersResponse, error) { + if w == nil { + return nil, nil + } + providersPublicValue, err := convertSlice(w.Providers, providerInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BatchGetProvidersResponse.Providers", err) + } + return &BatchGetProvidersResponse{ + Providers: providersPublicValue, + }, nil +} + +type consumerTermsWire struct { + Version *string `json:"version,omitempty"` +} + +func consumerTermsToWire(v *ConsumerTerms) (*consumerTermsWire, error) { + if v == nil { + return nil, nil + } + return &consumerTermsWire{ + Version: v.Version, + }, nil +} + +type contactInfoWire struct { + FirstName *string `json:"first_name,omitempty"` + LastName *string `json:"last_name,omitempty"` + Email *string `json:"email,omitempty"` + Company *string `json:"company,omitempty"` +} + +func contactInfoFromWire(w *contactInfoWire) (*ContactInfo, error) { + if w == nil { + return nil, nil + } + return &ContactInfo{ + FirstName: w.FirstName, + LastName: w.LastName, + Email: w.Email, + Company: w.Company, + }, nil +} + +type createExchangeFilterRequestWire struct { + Filter *exchangeFilterWire `json:"filter,omitempty"` +} + +func createExchangeFilterRequestToWire(v *CreateExchangeFilterRequest) (*createExchangeFilterRequestWire, error) { + if v == nil { + return nil, nil + } + filterWireValue, err := exchangeFilterToWire(v.Filter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExchangeFilterRequest.Filter", err) + } + return &createExchangeFilterRequestWire{ + Filter: filterWireValue, + }, nil +} + +type createExchangeFilterResponseWire struct { + FilterId *string `json:"filter_id,omitempty"` +} + +func createExchangeFilterResponseFromWire(w *createExchangeFilterResponseWire) (*CreateExchangeFilterResponse, error) { + if w == nil { + return nil, nil + } + return &CreateExchangeFilterResponse{ + FilterId: w.FilterId, + }, nil +} + +type createExchangeRequestWire struct { + Exchange *exchangeWire `json:"exchange,omitempty"` +} + +func createExchangeRequestToWire(v *CreateExchangeRequest) (*createExchangeRequestWire, error) { + if v == nil { + return nil, nil + } + exchangeWireValue, err := exchangeToWire(v.Exchange) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExchangeRequest.Exchange", err) + } + return &createExchangeRequestWire{ + Exchange: exchangeWireValue, + }, nil +} + +type createExchangeResponseWire struct { + ExchangeId *string `json:"exchange_id,omitempty"` +} + +func createExchangeResponseFromWire(w *createExchangeResponseWire) (*CreateExchangeResponse, error) { + if w == nil { + return nil, nil + } + return &CreateExchangeResponse{ + ExchangeId: w.ExchangeId, + }, nil +} + +type createFileRequestWire struct { + FileParent *fileParentWire `json:"file_parent,omitempty"` + MarketplaceFileType MarketplaceFileType `json:"marketplace_file_type,omitempty"` + MimeType *string `json:"mime_type,omitempty"` + DisplayName *string `json:"display_name,omitempty"` +} + +func createFileRequestToWire(v *CreateFileRequest) (*createFileRequestWire, error) { + if v == nil { + return nil, nil + } + fileParentWireValue, err := fileParentToWire(v.FileParent) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateFileRequest.FileParent", err) + } + return &createFileRequestWire{ + FileParent: fileParentWireValue, + MarketplaceFileType: v.MarketplaceFileType, + MimeType: v.MimeType, + DisplayName: v.DisplayName, + }, nil +} + +type createFileResponseWire struct { + UploadUrl *string `json:"upload_url,omitempty"` + FileInfo *fileInfoWire `json:"file_info,omitempty"` +} + +func createFileResponseFromWire(w *createFileResponseWire) (*CreateFileResponse, error) { + if w == nil { + return nil, nil + } + fileInfoPublicValue, err := fileInfoFromWire(w.FileInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateFileResponse.FileInfo", err) + } + return &CreateFileResponse{ + UploadUrl: w.UploadUrl, + FileInfo: fileInfoPublicValue, + }, nil +} + +type createInstallationRequestWire struct { + ListingId *string `json:"listing_id,omitempty"` + ShareName *string `json:"share_name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + RepoDetail *repoInstallationWire `json:"repo_detail,omitempty"` + RecipientType DeltaSharingRecipientType `json:"recipient_type,omitempty"` + AcceptedConsumerTerms *consumerTermsWire `json:"accepted_consumer_terms,omitempty"` +} + +func createInstallationRequestToWire(v *CreateInstallationRequest) (*createInstallationRequestWire, error) { + if v == nil { + return nil, nil + } + repoDetailWireValue, err := repoInstallationToWire(v.RepoDetail) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInstallationRequest.RepoDetail", err) + } + acceptedConsumerTermsWireValue, err := consumerTermsToWire(v.AcceptedConsumerTerms) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInstallationRequest.AcceptedConsumerTerms", err) + } + return &createInstallationRequestWire{ + ListingId: v.ListingId, + ShareName: v.ShareName, + CatalogName: v.CatalogName, + RepoDetail: repoDetailWireValue, + RecipientType: v.RecipientType, + AcceptedConsumerTerms: acceptedConsumerTermsWireValue, + }, nil +} + +type createInstallationResponseWire struct { + Installation *installationDetailWire `json:"installation,omitempty"` +} + +func createInstallationResponseFromWire(w *createInstallationResponseWire) (*CreateInstallationResponse, error) { + if w == nil { + return nil, nil + } + installationPublicValue, err := installationDetailFromWire(w.Installation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInstallationResponse.Installation", err) + } + return &CreateInstallationResponse{ + Installation: installationPublicValue, + }, nil +} + +type createListingRequestWire struct { + Listing *listingWire `json:"listing,omitempty"` +} + +func createListingRequestToWire(v *CreateListingRequest) (*createListingRequestWire, error) { + if v == nil { + return nil, nil + } + listingWireValue, err := listingToWire(v.Listing) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateListingRequest.Listing", err) + } + return &createListingRequestWire{ + Listing: listingWireValue, + }, nil +} + +type createListingResponseWire struct { + ListingId *string `json:"listing_id,omitempty"` +} + +func createListingResponseFromWire(w *createListingResponseWire) (*CreateListingResponse, error) { + if w == nil { + return nil, nil + } + return &CreateListingResponse{ + ListingId: w.ListingId, + }, nil +} + +type createPersonalizationRequestWire struct { + ListingId *string `json:"listing_id,omitempty"` + Comment *string `json:"comment,omitempty"` + IntendedUse *string `json:"intended_use,omitempty"` + FirstName *string `json:"first_name,omitempty"` + LastName *string `json:"last_name,omitempty"` + Company *string `json:"company,omitempty"` + IsFromLighthouse *bool `json:"is_from_lighthouse,omitempty"` + RecipientType DeltaSharingRecipientType `json:"recipient_type,omitempty"` + AcceptedConsumerTerms *consumerTermsWire `json:"accepted_consumer_terms,omitempty"` +} + +func createPersonalizationRequestToWire(v *CreatePersonalizationRequest) (*createPersonalizationRequestWire, error) { + if v == nil { + return nil, nil + } + acceptedConsumerTermsWireValue, err := consumerTermsToWire(v.AcceptedConsumerTerms) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePersonalizationRequest.AcceptedConsumerTerms", err) + } + return &createPersonalizationRequestWire{ + ListingId: v.ListingId, + Comment: v.Comment, + IntendedUse: v.IntendedUse, + FirstName: v.FirstName, + LastName: v.LastName, + Company: v.Company, + IsFromLighthouse: v.IsFromLighthouse, + RecipientType: v.RecipientType, + AcceptedConsumerTerms: acceptedConsumerTermsWireValue, + }, nil +} + +type createPersonalizationResponseWire struct { + Id *string `json:"id,omitempty"` +} + +func createPersonalizationResponseFromWire(w *createPersonalizationResponseWire) (*CreatePersonalizationResponse, error) { + if w == nil { + return nil, nil + } + return &CreatePersonalizationResponse{ + Id: w.Id, + }, nil +} + +type createProviderAnalyticsDashboardRequestWire struct { +} + +func createProviderAnalyticsDashboardRequestToWire(v *CreateProviderAnalyticsDashboardRequest) (*createProviderAnalyticsDashboardRequestWire, error) { + if v == nil { + return nil, nil + } + return &createProviderAnalyticsDashboardRequestWire{}, nil +} + +type createProviderAnalyticsDashboardResponseWire struct { + Id *string `json:"id,omitempty"` +} + +func createProviderAnalyticsDashboardResponseFromWire(w *createProviderAnalyticsDashboardResponseWire) (*CreateProviderAnalyticsDashboardResponse, error) { + if w == nil { + return nil, nil + } + return &CreateProviderAnalyticsDashboardResponse{ + Id: w.Id, + }, nil +} + +type createProviderRequestWire struct { + Provider *providerInfoWire `json:"provider,omitempty"` +} + +func createProviderRequestToWire(v *CreateProviderRequest) (*createProviderRequestWire, error) { + if v == nil { + return nil, nil + } + providerWireValue, err := providerInfoToWire(v.Provider) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateProviderRequest.Provider", err) + } + return &createProviderRequestWire{ + Provider: providerWireValue, + }, nil +} + +type createProviderResponseWire struct { + Id *string `json:"id,omitempty"` +} + +func createProviderResponseFromWire(w *createProviderResponseWire) (*CreateProviderResponse, error) { + if w == nil { + return nil, nil + } + return &CreateProviderResponse{ + Id: w.Id, + }, nil +} + +type dataRefreshInfoWire struct { + Interval *int64 `json:"interval,omitempty"` + Unit DataRefresh `json:"unit,omitempty"` +} + +func dataRefreshInfoToWire(v *DataRefreshInfo) (*dataRefreshInfoWire, error) { + if v == nil { + return nil, nil + } + return &dataRefreshInfoWire{ + Interval: v.Interval, + Unit: v.Unit, + }, nil +} + +func dataRefreshInfoFromWire(w *dataRefreshInfoWire) (*DataRefreshInfo, error) { + if w == nil { + return nil, nil + } + return &DataRefreshInfo{ + Interval: w.Interval, + Unit: w.Unit, + }, nil +} + +type exchangeWire struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Comment *string `json:"comment,omitempty"` + Filters []exchangeFilterWire `json:"filters,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + LinkedListings []exchangeListingWire `json:"linked_listings,omitempty"` +} + +func exchangeToWire(v *Exchange) (*exchangeWire, error) { + if v == nil { + return nil, nil + } + filtersWireValue, err := convertSlice(v.Filters, exchangeFilterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Exchange.Filters", err) + } + linkedListingsWireValue, err := convertSlice(v.LinkedListings, exchangeListingToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Exchange.LinkedListings", err) + } + return &exchangeWire{ + Id: v.Id, + Name: v.Name, + Comment: v.Comment, + Filters: filtersWireValue, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + LinkedListings: linkedListingsWireValue, + }, nil +} + +func exchangeFromWire(w *exchangeWire) (*Exchange, error) { + if w == nil { + return nil, nil + } + filtersPublicValue, err := convertSlice(w.Filters, exchangeFilterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Exchange.Filters", err) + } + linkedListingsPublicValue, err := convertSlice(w.LinkedListings, exchangeListingFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Exchange.LinkedListings", err) + } + return &Exchange{ + Id: w.Id, + Name: w.Name, + Comment: w.Comment, + Filters: filtersPublicValue, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + LinkedListings: linkedListingsPublicValue, + }, nil +} + +type exchangeFilterWire struct { + Id *string `json:"id,omitempty"` + ExchangeId *string `json:"exchange_id,omitempty"` + FilterValue *string `json:"filter_value,omitempty"` + Name *string `json:"name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + FilterType ExchangeFilterType `json:"filter_type,omitempty"` +} + +func exchangeFilterToWire(v *ExchangeFilter) (*exchangeFilterWire, error) { + if v == nil { + return nil, nil + } + return &exchangeFilterWire{ + Id: v.Id, + ExchangeId: v.ExchangeId, + FilterValue: v.FilterValue, + Name: v.Name, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + FilterType: v.FilterType, + }, nil +} + +func exchangeFilterFromWire(w *exchangeFilterWire) (*ExchangeFilter, error) { + if w == nil { + return nil, nil + } + return &ExchangeFilter{ + Id: w.Id, + ExchangeId: w.ExchangeId, + FilterValue: w.FilterValue, + Name: w.Name, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + FilterType: w.FilterType, + }, nil +} + +type exchangeListingWire struct { + Id *string `json:"id,omitempty"` + ExchangeId *string `json:"exchange_id,omitempty"` + ExchangeName *string `json:"exchange_name,omitempty"` + ListingId *string `json:"listing_id,omitempty"` + ListingName *string `json:"listing_name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` +} + +func exchangeListingToWire(v *ExchangeListing) (*exchangeListingWire, error) { + if v == nil { + return nil, nil + } + return &exchangeListingWire{ + Id: v.Id, + ExchangeId: v.ExchangeId, + ExchangeName: v.ExchangeName, + ListingId: v.ListingId, + ListingName: v.ListingName, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + }, nil +} + +func exchangeListingFromWire(w *exchangeListingWire) (*ExchangeListing, error) { + if w == nil { + return nil, nil + } + return &ExchangeListing{ + Id: w.Id, + ExchangeId: w.ExchangeId, + ExchangeName: w.ExchangeName, + ListingId: w.ListingId, + ListingName: w.ListingName, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + }, nil +} + +type fileInfoWire struct { + Id *string `json:"id,omitempty"` + MarketplaceFileType MarketplaceFileType `json:"marketplace_file_type,omitempty"` + FileParent *fileParentWire `json:"file_parent,omitempty"` + MimeType *string `json:"mime_type,omitempty"` + DownloadLink *string `json:"download_link,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Status FileStatus `json:"status,omitempty"` + StatusMessage *string `json:"status_message,omitempty"` +} + +func fileInfoToWire(v *FileInfo) (*fileInfoWire, error) { + if v == nil { + return nil, nil + } + fileParentWireValue, err := fileParentToWire(v.FileParent) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileInfo.FileParent", err) + } + return &fileInfoWire{ + Id: v.Id, + MarketplaceFileType: v.MarketplaceFileType, + FileParent: fileParentWireValue, + MimeType: v.MimeType, + DownloadLink: v.DownloadLink, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + DisplayName: v.DisplayName, + Status: v.Status, + StatusMessage: v.StatusMessage, + }, nil +} + +func fileInfoFromWire(w *fileInfoWire) (*FileInfo, error) { + if w == nil { + return nil, nil + } + fileParentPublicValue, err := fileParentFromWire(w.FileParent) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileInfo.FileParent", err) + } + return &FileInfo{ + Id: w.Id, + MarketplaceFileType: w.MarketplaceFileType, + FileParent: fileParentPublicValue, + MimeType: w.MimeType, + DownloadLink: w.DownloadLink, + CreatedAt: w.CreatedAt, + UpdatedAt: w.UpdatedAt, + DisplayName: w.DisplayName, + Status: w.Status, + StatusMessage: w.StatusMessage, + }, nil +} + +type fileParentWire struct { + ParentId *string `json:"parent_id,omitempty"` + FileParentType FileParentType `json:"file_parent_type,omitempty"` +} + +func fileParentToWire(v *FileParent) (*fileParentWire, error) { + if v == nil { + return nil, nil + } + return &fileParentWire{ + ParentId: v.ParentId, + FileParentType: v.FileParentType, + }, nil +} + +func fileParentFromWire(w *fileParentWire) (*FileParent, error) { + if w == nil { + return nil, nil + } + return &FileParent{ + ParentId: w.ParentId, + FileParentType: w.FileParentType, + }, nil +} + +type getAllPersonalizationRequestsForConsumerResponseWire struct { + PersonalizationRequests []personalizationRequestWire `json:"personalization_requests,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func getAllPersonalizationRequestsForConsumerResponseFromWire(w *getAllPersonalizationRequestsForConsumerResponseWire) (*GetAllPersonalizationRequestsForConsumerResponse, error) { + if w == nil { + return nil, nil + } + personalizationRequestsPublicValue, err := convertSlice(w.PersonalizationRequests, personalizationRequestFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetAllPersonalizationRequestsForConsumerResponse.PersonalizationRequests", err) + } + return &GetAllPersonalizationRequestsForConsumerResponse{ + PersonalizationRequests: personalizationRequestsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type getExchangeResponseWire struct { + Exchange *exchangeWire `json:"exchange,omitempty"` +} + +func getExchangeResponseFromWire(w *getExchangeResponseWire) (*GetExchangeResponse, error) { + if w == nil { + return nil, nil + } + exchangePublicValue, err := exchangeFromWire(w.Exchange) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetExchangeResponse.Exchange", err) + } + return &GetExchangeResponse{ + Exchange: exchangePublicValue, + }, nil +} + +type getFileResponseWire struct { + FileInfo *fileInfoWire `json:"file_info,omitempty"` +} + +func getFileResponseFromWire(w *getFileResponseWire) (*GetFileResponse, error) { + if w == nil { + return nil, nil + } + fileInfoPublicValue, err := fileInfoFromWire(w.FileInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetFileResponse.FileInfo", err) + } + return &GetFileResponse{ + FileInfo: fileInfoPublicValue, + }, nil +} + +type getInstallationDetailsRequestWire struct { + ListingId *string `json:"listing_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func getInstallationDetailsRequestToWire(v *GetInstallationDetailsRequest) (*getInstallationDetailsRequestWire, error) { + if v == nil { + return nil, nil + } + return &getInstallationDetailsRequestWire{ + ListingId: v.ListingId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type getLatestVersionProviderAnalyticsDashboardResponseWire struct { + Version *int64 `json:"version,omitempty"` +} + +func getLatestVersionProviderAnalyticsDashboardResponseFromWire(w *getLatestVersionProviderAnalyticsDashboardResponseWire) (*GetLatestVersionProviderAnalyticsDashboardResponse, error) { + if w == nil { + return nil, nil + } + return &GetLatestVersionProviderAnalyticsDashboardResponse{ + Version: w.Version, + }, nil +} + +type getListingContentMetadataRequestWire struct { + ListingId *string `json:"listing_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func getListingContentMetadataRequestToWire(v *GetListingContentMetadataRequest) (*getListingContentMetadataRequestWire, error) { + if v == nil { + return nil, nil + } + return &getListingContentMetadataRequestWire{ + ListingId: v.ListingId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type getListingContentMetadataResponseWire struct { + SharedDataObjects []sharedDataObjectWire `json:"shared_data_objects,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func getListingContentMetadataResponseFromWire(w *getListingContentMetadataResponseWire) (*GetListingContentMetadataResponse, error) { + if w == nil { + return nil, nil + } + sharedDataObjectsPublicValue, err := convertSlice(w.SharedDataObjects, sharedDataObjectFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetListingContentMetadataResponse.SharedDataObjects", err) + } + return &GetListingContentMetadataResponse{ + SharedDataObjects: sharedDataObjectsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type getListingResponseWire struct { + Listing *listingWire `json:"listing,omitempty"` +} + +func getListingResponseFromWire(w *getListingResponseWire) (*GetListingResponse, error) { + if w == nil { + return nil, nil + } + listingPublicValue, err := listingFromWire(w.Listing) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetListingResponse.Listing", err) + } + return &GetListingResponse{ + Listing: listingPublicValue, + }, nil +} + +type getListingsResponseWire struct { + Listings []listingWire `json:"listings,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func getListingsResponseFromWire(w *getListingsResponseWire) (*GetListingsResponse, error) { + if w == nil { + return nil, nil + } + listingsPublicValue, err := convertSlice(w.Listings, listingFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetListingsResponse.Listings", err) + } + return &GetListingsResponse{ + Listings: listingsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type getPersonalizationRequestsForConsumerResponseWire struct { + PersonalizationRequests []personalizationRequestWire `json:"personalization_requests,omitempty"` +} + +func getPersonalizationRequestsForConsumerResponseFromWire(w *getPersonalizationRequestsForConsumerResponseWire) (*GetPersonalizationRequestsForConsumerResponse, error) { + if w == nil { + return nil, nil + } + personalizationRequestsPublicValue, err := convertSlice(w.PersonalizationRequests, personalizationRequestFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPersonalizationRequestsForConsumerResponse.PersonalizationRequests", err) + } + return &GetPersonalizationRequestsForConsumerResponse{ + PersonalizationRequests: personalizationRequestsPublicValue, + }, nil +} + +type getPersonalizationRequestsForProviderRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func getPersonalizationRequestsForProviderRequestToWire(v *GetPersonalizationRequestsForProviderRequest) (*getPersonalizationRequestsForProviderRequestWire, error) { + if v == nil { + return nil, nil + } + return &getPersonalizationRequestsForProviderRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type getPersonalizationRequestsForProviderResponseWire struct { + PersonalizationRequests []personalizationRequestWire `json:"personalization_requests,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func getPersonalizationRequestsForProviderResponseFromWire(w *getPersonalizationRequestsForProviderResponseWire) (*GetPersonalizationRequestsForProviderResponse, error) { + if w == nil { + return nil, nil + } + personalizationRequestsPublicValue, err := convertSlice(w.PersonalizationRequests, personalizationRequestFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPersonalizationRequestsForProviderResponse.PersonalizationRequests", err) + } + return &GetPersonalizationRequestsForProviderResponse{ + PersonalizationRequests: personalizationRequestsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type getProviderResponseWire struct { + Provider *providerInfoWire `json:"provider,omitempty"` +} + +func getProviderResponseFromWire(w *getProviderResponseWire) (*GetProviderResponse, error) { + if w == nil { + return nil, nil + } + providerPublicValue, err := providerInfoFromWire(w.Provider) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetProviderResponse.Provider", err) + } + return &GetProviderResponse{ + Provider: providerPublicValue, + }, nil +} + +type getPublishedListingForConsumerResponseWire struct { + Listing *listingWire `json:"listing,omitempty"` +} + +func getPublishedListingForConsumerResponseFromWire(w *getPublishedListingForConsumerResponseWire) (*GetPublishedListingForConsumerResponse, error) { + if w == nil { + return nil, nil + } + listingPublicValue, err := listingFromWire(w.Listing) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPublishedListingForConsumerResponse.Listing", err) + } + return &GetPublishedListingForConsumerResponse{ + Listing: listingPublicValue, + }, nil +} + +type getPublishedListingsForConsumerResponseWire struct { + Listings []listingWire `json:"listings,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func getPublishedListingsForConsumerResponseFromWire(w *getPublishedListingsForConsumerResponseWire) (*GetPublishedListingsForConsumerResponse, error) { + if w == nil { + return nil, nil + } + listingsPublicValue, err := convertSlice(w.Listings, listingFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPublishedListingsForConsumerResponse.Listings", err) + } + return &GetPublishedListingsForConsumerResponse{ + Listings: listingsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type getPublishedProviderForConsumerResponseWire struct { + Provider *providerInfoWire `json:"provider,omitempty"` +} + +func getPublishedProviderForConsumerResponseFromWire(w *getPublishedProviderForConsumerResponseWire) (*GetPublishedProviderForConsumerResponse, error) { + if w == nil { + return nil, nil + } + providerPublicValue, err := providerInfoFromWire(w.Provider) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPublishedProviderForConsumerResponse.Provider", err) + } + return &GetPublishedProviderForConsumerResponse{ + Provider: providerPublicValue, + }, nil +} + +type installationDetailWire struct { + Id *string `json:"id,omitempty"` + ListingId *string `json:"listing_id,omitempty"` + ShareName *string `json:"share_name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + InstalledOn *int64 `json:"installed_on,omitempty"` + Status InstallationStatus `json:"status,omitempty"` + ErrorMessage *string `json:"error_message,omitempty"` + ListingName *string `json:"listing_name,omitempty"` + RepoName *string `json:"repo_name,omitempty"` + RepoPath *string `json:"repo_path,omitempty"` + RecipientType DeltaSharingRecipientType `json:"recipient_type,omitempty"` + Tokens []tokenInfoWire `json:"tokens,omitempty"` + TokenDetail *tokenDetailWire `json:"token_detail,omitempty"` +} + +func installationDetailToWire(v *InstallationDetail) (*installationDetailWire, error) { + if v == nil { + return nil, nil + } + tokensWireValue, err := convertSlice(v.Tokens, tokenInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstallationDetail.Tokens", err) + } + tokenDetailWireValue, err := tokenDetailToWire(v.TokenDetail) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstallationDetail.TokenDetail", err) + } + return &installationDetailWire{ + Id: v.Id, + ListingId: v.ListingId, + ShareName: v.ShareName, + CatalogName: v.CatalogName, + InstalledOn: v.InstalledOn, + Status: v.Status, + ErrorMessage: v.ErrorMessage, + ListingName: v.ListingName, + RepoName: v.RepoName, + RepoPath: v.RepoPath, + RecipientType: v.RecipientType, + Tokens: tokensWireValue, + TokenDetail: tokenDetailWireValue, + }, nil +} + +func installationDetailFromWire(w *installationDetailWire) (*InstallationDetail, error) { + if w == nil { + return nil, nil + } + tokensPublicValue, err := convertSlice(w.Tokens, tokenInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstallationDetail.Tokens", err) + } + tokenDetailPublicValue, err := tokenDetailFromWire(w.TokenDetail) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InstallationDetail.TokenDetail", err) + } + return &InstallationDetail{ + Id: w.Id, + ListingId: w.ListingId, + ShareName: w.ShareName, + CatalogName: w.CatalogName, + InstalledOn: w.InstalledOn, + Status: w.Status, + ErrorMessage: w.ErrorMessage, + ListingName: w.ListingName, + RepoName: w.RepoName, + RepoPath: w.RepoPath, + RecipientType: w.RecipientType, + Tokens: tokensPublicValue, + TokenDetail: tokenDetailPublicValue, + }, nil +} + +type listAllInstallationsResponseWire struct { + Installations []installationDetailWire `json:"installations,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listAllInstallationsResponseFromWire(w *listAllInstallationsResponseWire) (*ListAllInstallationsResponse, error) { + if w == nil { + return nil, nil + } + installationsPublicValue, err := convertSlice(w.Installations, installationDetailFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAllInstallationsResponse.Installations", err) + } + return &ListAllInstallationsResponse{ + Installations: installationsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listExchangeFiltersRequestWire struct { + ExchangeId *string `json:"exchange_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listExchangeFiltersRequestToWire(v *ListExchangeFiltersRequest) (*listExchangeFiltersRequestWire, error) { + if v == nil { + return nil, nil + } + return &listExchangeFiltersRequestWire{ + ExchangeId: v.ExchangeId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listExchangeFiltersResponseWire struct { + Filters []exchangeFilterWire `json:"filters,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listExchangeFiltersResponseFromWire(w *listExchangeFiltersResponseWire) (*ListExchangeFiltersResponse, error) { + if w == nil { + return nil, nil + } + filtersPublicValue, err := convertSlice(w.Filters, exchangeFilterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListExchangeFiltersResponse.Filters", err) + } + return &ListExchangeFiltersResponse{ + Filters: filtersPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listExchangesForListingRequestWire struct { + ListingId *string `json:"listing_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listExchangesForListingRequestToWire(v *ListExchangesForListingRequest) (*listExchangesForListingRequestWire, error) { + if v == nil { + return nil, nil + } + return &listExchangesForListingRequestWire{ + ListingId: v.ListingId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listExchangesForListingResponseWire struct { + ExchangeListing []exchangeListingWire `json:"exchange_listing,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listExchangesForListingResponseFromWire(w *listExchangesForListingResponseWire) (*ListExchangesForListingResponse, error) { + if w == nil { + return nil, nil + } + exchangeListingPublicValue, err := convertSlice(w.ExchangeListing, exchangeListingFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListExchangesForListingResponse.ExchangeListing", err) + } + return &ListExchangesForListingResponse{ + ExchangeListing: exchangeListingPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listExchangesRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listExchangesRequestToWire(v *ListExchangesRequest) (*listExchangesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listExchangesRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listExchangesResponseWire struct { + Exchanges []exchangeWire `json:"exchanges,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listExchangesResponseFromWire(w *listExchangesResponseWire) (*ListExchangesResponse, error) { + if w == nil { + return nil, nil + } + exchangesPublicValue, err := convertSlice(w.Exchanges, exchangeFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListExchangesResponse.Exchanges", err) + } + return &ListExchangesResponse{ + Exchanges: exchangesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listFilesRequestWire struct { + FileParent *fileParentWire `json:"file_parent,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listFilesRequestToWire(v *ListFilesRequest) (*listFilesRequestWire, error) { + if v == nil { + return nil, nil + } + fileParentWireValue, err := fileParentToWire(v.FileParent) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListFilesRequest.FileParent", err) + } + return &listFilesRequestWire{ + FileParent: fileParentWireValue, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listFilesResponseWire struct { + FileInfos []fileInfoWire `json:"file_infos,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listFilesResponseFromWire(w *listFilesResponseWire) (*ListFilesResponse, error) { + if w == nil { + return nil, nil + } + fileInfosPublicValue, err := convertSlice(w.FileInfos, fileInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListFilesResponse.FileInfos", err) + } + return &ListFilesResponse{ + FileInfos: fileInfosPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listFulfillmentsResponseWire struct { + Fulfillments []listingFulfillmentWire `json:"fulfillments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listFulfillmentsResponseFromWire(w *listFulfillmentsResponseWire) (*ListFulfillmentsResponse, error) { + if w == nil { + return nil, nil + } + fulfillmentsPublicValue, err := convertSlice(w.Fulfillments, listingFulfillmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListFulfillmentsResponse.Fulfillments", err) + } + return &ListFulfillmentsResponse{ + Fulfillments: fulfillmentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listInstallationsRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listInstallationsRequestToWire(v *ListInstallationsRequest) (*listInstallationsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listInstallationsRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listInstallationsResponseWire struct { + Installations []installationDetailWire `json:"installations,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listInstallationsResponseFromWire(w *listInstallationsResponseWire) (*ListInstallationsResponse, error) { + if w == nil { + return nil, nil + } + installationsPublicValue, err := convertSlice(w.Installations, installationDetailFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListInstallationsResponse.Installations", err) + } + return &ListInstallationsResponse{ + Installations: installationsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listListingFulfillmentsRequestWire struct { + ListingId *string `json:"listing_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listListingFulfillmentsRequestToWire(v *ListListingFulfillmentsRequest) (*listListingFulfillmentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listListingFulfillmentsRequestWire{ + ListingId: v.ListingId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listListingsForExchangeRequestWire struct { + ExchangeId *string `json:"exchange_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listListingsForExchangeRequestToWire(v *ListListingsForExchangeRequest) (*listListingsForExchangeRequestWire, error) { + if v == nil { + return nil, nil + } + return &listListingsForExchangeRequestWire{ + ExchangeId: v.ExchangeId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listListingsForExchangeResponseWire struct { + ExchangeListings []exchangeListingWire `json:"exchange_listings,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listListingsForExchangeResponseFromWire(w *listListingsForExchangeResponseWire) (*ListListingsForExchangeResponse, error) { + if w == nil { + return nil, nil + } + exchangeListingsPublicValue, err := convertSlice(w.ExchangeListings, exchangeListingFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListListingsForExchangeResponse.ExchangeListings", err) + } + return &ListListingsForExchangeResponse{ + ExchangeListings: exchangeListingsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listListingsRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listListingsRequestToWire(v *ListListingsRequest) (*listListingsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listListingsRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listPersonalizationRequestsForConsumerRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listPersonalizationRequestsForConsumerRequestToWire(v *ListPersonalizationRequestsForConsumerRequest) (*listPersonalizationRequestsForConsumerRequestWire, error) { + if v == nil { + return nil, nil + } + return &listPersonalizationRequestsForConsumerRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listProviderAnalyticsDashboardResponseWire struct { + Id *string `json:"id,omitempty"` + Version *int64 `json:"version,omitempty"` + DashboardId *string `json:"dashboard_id,omitempty"` +} + +func listProviderAnalyticsDashboardResponseFromWire(w *listProviderAnalyticsDashboardResponseWire) (*ListProviderAnalyticsDashboardResponse, error) { + if w == nil { + return nil, nil + } + return &ListProviderAnalyticsDashboardResponse{ + Id: w.Id, + Version: w.Version, + DashboardId: w.DashboardId, + }, nil +} + +type listProvidersRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listProvidersRequestToWire(v *ListProvidersRequest) (*listProvidersRequestWire, error) { + if v == nil { + return nil, nil + } + return &listProvidersRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listProvidersResponseWire struct { + Providers []providerInfoWire `json:"providers,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listProvidersResponseFromWire(w *listProvidersResponseWire) (*ListProvidersResponse, error) { + if w == nil { + return nil, nil + } + providersPublicValue, err := convertSlice(w.Providers, providerInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListProvidersResponse.Providers", err) + } + return &ListProvidersResponse{ + Providers: providersPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listPublishedListingsForConsumerRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` + Assets []AssetType `json:"assets,omitempty"` + Categories []Category `json:"categories,omitempty"` + Tags *listingTagWire `json:"tags,omitempty"` + IsFree *bool `json:"is_free,omitempty"` + IsPrivateExchange *bool `json:"is_private_exchange,omitempty"` + IsStaffPick *bool `json:"is_staff_pick,omitempty"` + ProviderIds []string `json:"provider_ids,omitempty"` +} + +func listPublishedListingsForConsumerRequestToWire(v *ListPublishedListingsForConsumerRequest) (*listPublishedListingsForConsumerRequestWire, error) { + if v == nil { + return nil, nil + } + tagsWireValue, err := listingTagToWire(v.Tags) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPublishedListingsForConsumerRequest.Tags", err) + } + return &listPublishedListingsForConsumerRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + Assets: v.Assets, + Categories: v.Categories, + Tags: tagsWireValue, + IsFree: v.IsFree, + IsPrivateExchange: v.IsPrivateExchange, + IsStaffPick: v.IsStaffPick, + ProviderIds: v.ProviderIds, + }, nil +} + +type listPublishedProvidersForConsumerRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` + IsFeatured *bool `json:"is_featured,omitempty"` +} + +func listPublishedProvidersForConsumerRequestToWire(v *ListPublishedProvidersForConsumerRequest) (*listPublishedProvidersForConsumerRequestWire, error) { + if v == nil { + return nil, nil + } + return &listPublishedProvidersForConsumerRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + IsFeatured: v.IsFeatured, + }, nil +} + +type listPublishedProvidersForConsumerResponseWire struct { + Providers []providerInfoWire `json:"providers,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listPublishedProvidersForConsumerResponseFromWire(w *listPublishedProvidersForConsumerResponseWire) (*ListPublishedProvidersForConsumerResponse, error) { + if w == nil { + return nil, nil + } + providersPublicValue, err := convertSlice(w.Providers, providerInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPublishedProvidersForConsumerResponse.Providers", err) + } + return &ListPublishedProvidersForConsumerResponse{ + Providers: providersPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listingWire struct { + Id *string `json:"id,omitempty"` + Summary *listingSummaryWire `json:"summary,omitempty"` + Detail *listingDetailWire `json:"detail,omitempty"` +} + +func listingToWire(v *Listing) (*listingWire, error) { + if v == nil { + return nil, nil + } + summaryWireValue, err := listingSummaryToWire(v.Summary) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Listing.Summary", err) + } + detailWireValue, err := listingDetailToWire(v.Detail) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Listing.Detail", err) + } + return &listingWire{ + Id: v.Id, + Summary: summaryWireValue, + Detail: detailWireValue, + }, nil +} + +func listingFromWire(w *listingWire) (*Listing, error) { + if w == nil { + return nil, nil + } + summaryPublicValue, err := listingSummaryFromWire(w.Summary) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Listing.Summary", err) + } + detailPublicValue, err := listingDetailFromWire(w.Detail) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Listing.Detail", err) + } + return &Listing{ + Id: w.Id, + Summary: summaryPublicValue, + Detail: detailPublicValue, + }, nil +} + +type listingDetailWire struct { + Description *string `json:"description,omitempty"` + TermsOfService *string `json:"terms_of_service,omitempty"` + DocumentationLink *string `json:"documentation_link,omitempty"` + SupportLink *string `json:"support_link,omitempty"` + FileIds []string `json:"file_ids,omitempty"` + PrivacyPolicyLink *string `json:"privacy_policy_link,omitempty"` + EmbeddedNotebookFileInfos []fileInfoWire `json:"embedded_notebook_file_infos,omitempty"` + GeographicalCoverage *string `json:"geographical_coverage,omitempty"` + Cost Cost `json:"cost,omitempty"` + PricingModel *string `json:"pricing_model,omitempty"` + UpdateFrequency *dataRefreshInfoWire `json:"update_frequency,omitempty"` + CollectionGranularity *dataRefreshInfoWire `json:"collection_granularity,omitempty"` + CollectionDateStart *int64 `json:"collection_date_start,omitempty"` + CollectionDateEnd *int64 `json:"collection_date_end,omitempty"` + DataSource *string `json:"data_source,omitempty"` + Size *float64 `json:"size,omitempty"` + Assets []AssetType `json:"assets,omitempty"` + License *string `json:"license,omitempty"` + Tags []listingTagWire `json:"tags,omitempty"` +} + +func listingDetailToWire(v *ListingDetail) (*listingDetailWire, error) { + if v == nil { + return nil, nil + } + embeddedNotebookFileInfosWireValue, err := convertSlice(v.EmbeddedNotebookFileInfos, fileInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingDetail.EmbeddedNotebookFileInfos", err) + } + updateFrequencyWireValue, err := dataRefreshInfoToWire(v.UpdateFrequency) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingDetail.UpdateFrequency", err) + } + collectionGranularityWireValue, err := dataRefreshInfoToWire(v.CollectionGranularity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingDetail.CollectionGranularity", err) + } + tagsWireValue, err := convertSlice(v.Tags, listingTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingDetail.Tags", err) + } + return &listingDetailWire{ + Description: v.Description, + TermsOfService: v.TermsOfService, + DocumentationLink: v.DocumentationLink, + SupportLink: v.SupportLink, + FileIds: v.FileIds, + PrivacyPolicyLink: v.PrivacyPolicyLink, + EmbeddedNotebookFileInfos: embeddedNotebookFileInfosWireValue, + GeographicalCoverage: v.GeographicalCoverage, + Cost: v.Cost, + PricingModel: v.PricingModel, + UpdateFrequency: updateFrequencyWireValue, + CollectionGranularity: collectionGranularityWireValue, + CollectionDateStart: v.CollectionDateStart, + CollectionDateEnd: v.CollectionDateEnd, + DataSource: v.DataSource, + Size: v.Size, + Assets: v.Assets, + License: v.License, + Tags: tagsWireValue, + }, nil +} + +func listingDetailFromWire(w *listingDetailWire) (*ListingDetail, error) { + if w == nil { + return nil, nil + } + embeddedNotebookFileInfosPublicValue, err := convertSlice(w.EmbeddedNotebookFileInfos, fileInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingDetail.EmbeddedNotebookFileInfos", err) + } + updateFrequencyPublicValue, err := dataRefreshInfoFromWire(w.UpdateFrequency) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingDetail.UpdateFrequency", err) + } + collectionGranularityPublicValue, err := dataRefreshInfoFromWire(w.CollectionGranularity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingDetail.CollectionGranularity", err) + } + tagsPublicValue, err := convertSlice(w.Tags, listingTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingDetail.Tags", err) + } + return &ListingDetail{ + Description: w.Description, + TermsOfService: w.TermsOfService, + DocumentationLink: w.DocumentationLink, + SupportLink: w.SupportLink, + FileIds: w.FileIds, + PrivacyPolicyLink: w.PrivacyPolicyLink, + EmbeddedNotebookFileInfos: embeddedNotebookFileInfosPublicValue, + GeographicalCoverage: w.GeographicalCoverage, + Cost: w.Cost, + PricingModel: w.PricingModel, + UpdateFrequency: updateFrequencyPublicValue, + CollectionGranularity: collectionGranularityPublicValue, + CollectionDateStart: w.CollectionDateStart, + CollectionDateEnd: w.CollectionDateEnd, + DataSource: w.DataSource, + Size: w.Size, + Assets: w.Assets, + License: w.License, + Tags: tagsPublicValue, + }, nil +} + +type listingFulfillmentWire struct { + ListingId *string `json:"listing_id,omitempty"` + FulfillmentType FulfillmentType `json:"fulfillment_type,omitempty"` + ShareInfo *shareInfoWire `json:"share_info,omitempty"` + RepoInfo *repoInfoWire `json:"repo_info,omitempty"` + RecipientType DeltaSharingRecipientType `json:"recipient_type,omitempty"` +} + +func listingFulfillmentFromWire(w *listingFulfillmentWire) (*ListingFulfillment, error) { + if w == nil { + return nil, nil + } + shareInfoPublicValue, err := shareInfoFromWire(w.ShareInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingFulfillment.ShareInfo", err) + } + repoInfoPublicValue, err := repoInfoFromWire(w.RepoInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingFulfillment.RepoInfo", err) + } + return &ListingFulfillment{ + ListingId: w.ListingId, + FulfillmentType: w.FulfillmentType, + ShareInfo: shareInfoPublicValue, + RepoInfo: repoInfoPublicValue, + RecipientType: w.RecipientType, + }, nil +} + +type listingSettingWire struct { + Visibility Visibility `json:"visibility,omitempty"` +} + +func listingSettingToWire(v *ListingSetting) (*listingSettingWire, error) { + if v == nil { + return nil, nil + } + return &listingSettingWire{ + Visibility: v.Visibility, + }, nil +} + +func listingSettingFromWire(w *listingSettingWire) (*ListingSetting, error) { + if w == nil { + return nil, nil + } + return &ListingSetting{ + Visibility: w.Visibility, + }, nil +} + +type listingSummaryWire struct { + Name *string `json:"name,omitempty"` + Subtitle *string `json:"subtitle,omitempty"` + Status ListingStatus `json:"status,omitempty"` + Share *shareInfoWire `json:"share,omitempty"` + ProviderRegion *regionInfoWire `json:"provider_region,omitempty"` + Setting *listingSettingWire `json:"setting,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + PublishedAt *int64 `json:"published_at,omitempty"` + PublishedBy *string `json:"published_by,omitempty"` + Categories []Category `json:"categories,omitempty"` + ListingType ListingType `json:"listingType,omitempty"` + CreatedById *int64 `json:"created_by_id,omitempty"` + UpdatedById *int64 `json:"updated_by_id,omitempty"` + ProviderId *string `json:"provider_id,omitempty"` + ExchangeIds []string `json:"exchange_ids,omitempty"` + GitRepo *repoInfoWire `json:"git_repo,omitempty"` +} + +func listingSummaryToWire(v *ListingSummary) (*listingSummaryWire, error) { + if v == nil { + return nil, nil + } + shareWireValue, err := shareInfoToWire(v.Share) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingSummary.Share", err) + } + providerRegionWireValue, err := regionInfoToWire(v.ProviderRegion) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingSummary.ProviderRegion", err) + } + settingWireValue, err := listingSettingToWire(v.Setting) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingSummary.Setting", err) + } + gitRepoWireValue, err := repoInfoToWire(v.GitRepo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingSummary.GitRepo", err) + } + return &listingSummaryWire{ + Name: v.Name, + Subtitle: v.Subtitle, + Status: v.Status, + Share: shareWireValue, + ProviderRegion: providerRegionWireValue, + Setting: settingWireValue, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + PublishedAt: v.PublishedAt, + PublishedBy: v.PublishedBy, + Categories: v.Categories, + ListingType: v.ListingType, + CreatedById: v.CreatedById, + UpdatedById: v.UpdatedById, + ProviderId: v.ProviderId, + ExchangeIds: v.ExchangeIds, + GitRepo: gitRepoWireValue, + }, nil +} + +func listingSummaryFromWire(w *listingSummaryWire) (*ListingSummary, error) { + if w == nil { + return nil, nil + } + sharePublicValue, err := shareInfoFromWire(w.Share) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingSummary.Share", err) + } + providerRegionPublicValue, err := regionInfoFromWire(w.ProviderRegion) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingSummary.ProviderRegion", err) + } + settingPublicValue, err := listingSettingFromWire(w.Setting) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingSummary.Setting", err) + } + gitRepoPublicValue, err := repoInfoFromWire(w.GitRepo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListingSummary.GitRepo", err) + } + return &ListingSummary{ + Name: w.Name, + Subtitle: w.Subtitle, + Status: w.Status, + Share: sharePublicValue, + ProviderRegion: providerRegionPublicValue, + Setting: settingPublicValue, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + PublishedAt: w.PublishedAt, + PublishedBy: w.PublishedBy, + Categories: w.Categories, + ListingType: w.ListingType, + CreatedById: w.CreatedById, + UpdatedById: w.UpdatedById, + ProviderId: w.ProviderId, + ExchangeIds: w.ExchangeIds, + GitRepo: gitRepoPublicValue, + }, nil +} + +type listingTagWire struct { + TagName ListingTagType `json:"tag_name,omitempty"` + TagValues []string `json:"tag_values,omitempty"` +} + +func listingTagToWire(v *ListingTag) (*listingTagWire, error) { + if v == nil { + return nil, nil + } + return &listingTagWire{ + TagName: v.TagName, + TagValues: v.TagValues, + }, nil +} + +func listingTagFromWire(w *listingTagWire) (*ListingTag, error) { + if w == nil { + return nil, nil + } + return &ListingTag{ + TagName: w.TagName, + TagValues: w.TagValues, + }, nil +} + +type personalizationRequestWire struct { + Id *string `json:"id,omitempty"` + ConsumerRegion *regionInfoWire `json:"consumer_region,omitempty"` + ContactInfo *contactInfoWire `json:"contact_info,omitempty"` + Comment *string `json:"comment,omitempty"` + IntendedUse *string `json:"intended_use,omitempty"` + Status PersonalizationRequestStatus `json:"status,omitempty"` + StatusMessage *string `json:"status_message,omitempty"` + Share *shareInfoWire `json:"share,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + ListingId *string `json:"listing_id,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + ListingName *string `json:"listing_name,omitempty"` + IsFromLighthouse *bool `json:"is_from_lighthouse,omitempty"` + ProviderId *string `json:"provider_id,omitempty"` + RecipientType DeltaSharingRecipientType `json:"recipient_type,omitempty"` +} + +func personalizationRequestFromWire(w *personalizationRequestWire) (*PersonalizationRequest, error) { + if w == nil { + return nil, nil + } + consumerRegionPublicValue, err := regionInfoFromWire(w.ConsumerRegion) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PersonalizationRequest.ConsumerRegion", err) + } + contactInfoPublicValue, err := contactInfoFromWire(w.ContactInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PersonalizationRequest.ContactInfo", err) + } + sharePublicValue, err := shareInfoFromWire(w.Share) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PersonalizationRequest.Share", err) + } + return &PersonalizationRequest{ + Id: w.Id, + ConsumerRegion: consumerRegionPublicValue, + ContactInfo: contactInfoPublicValue, + Comment: w.Comment, + IntendedUse: w.IntendedUse, + Status: w.Status, + StatusMessage: w.StatusMessage, + Share: sharePublicValue, + CreatedAt: w.CreatedAt, + ListingId: w.ListingId, + UpdatedAt: w.UpdatedAt, + MetastoreId: w.MetastoreId, + ListingName: w.ListingName, + IsFromLighthouse: w.IsFromLighthouse, + ProviderId: w.ProviderId, + RecipientType: w.RecipientType, + }, nil +} + +type providerInfoWire struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + IconFilePath *string `json:"icon_file_path,omitempty"` + BusinessContactEmail *string `json:"business_contact_email,omitempty"` + SupportContactEmail *string `json:"support_contact_email,omitempty"` + IsFeatured *bool `json:"is_featured,omitempty"` + PublishedBy *string `json:"published_by,omitempty"` + CompanyWebsiteLink *string `json:"company_website_link,omitempty"` + IconFileId *string `json:"icon_file_id,omitempty"` + TermOfServiceLink *string `json:"term_of_service_link,omitempty"` + PrivacyPolicyLink *string `json:"privacy_policy_link,omitempty"` + DarkModeIconFileId *string `json:"dark_mode_icon_file_id,omitempty"` + DarkModeIconFilePath *string `json:"dark_mode_icon_file_path,omitempty"` +} + +func providerInfoToWire(v *ProviderInfo) (*providerInfoWire, error) { + if v == nil { + return nil, nil + } + return &providerInfoWire{ + Id: v.Id, + Name: v.Name, + Description: v.Description, + IconFilePath: v.IconFilePath, + BusinessContactEmail: v.BusinessContactEmail, + SupportContactEmail: v.SupportContactEmail, + IsFeatured: v.IsFeatured, + PublishedBy: v.PublishedBy, + CompanyWebsiteLink: v.CompanyWebsiteLink, + IconFileId: v.IconFileId, + TermOfServiceLink: v.TermOfServiceLink, + PrivacyPolicyLink: v.PrivacyPolicyLink, + DarkModeIconFileId: v.DarkModeIconFileId, + DarkModeIconFilePath: v.DarkModeIconFilePath, + }, nil +} + +func providerInfoFromWire(w *providerInfoWire) (*ProviderInfo, error) { + if w == nil { + return nil, nil + } + return &ProviderInfo{ + Id: w.Id, + Name: w.Name, + Description: w.Description, + IconFilePath: w.IconFilePath, + BusinessContactEmail: w.BusinessContactEmail, + SupportContactEmail: w.SupportContactEmail, + IsFeatured: w.IsFeatured, + PublishedBy: w.PublishedBy, + CompanyWebsiteLink: w.CompanyWebsiteLink, + IconFileId: w.IconFileId, + TermOfServiceLink: w.TermOfServiceLink, + PrivacyPolicyLink: w.PrivacyPolicyLink, + DarkModeIconFileId: w.DarkModeIconFileId, + DarkModeIconFilePath: w.DarkModeIconFilePath, + }, nil +} + +type regionInfoWire struct { + Cloud *string `json:"cloud,omitempty"` + Region *string `json:"region,omitempty"` +} + +func regionInfoToWire(v *RegionInfo) (*regionInfoWire, error) { + if v == nil { + return nil, nil + } + return ®ionInfoWire{ + Cloud: v.Cloud, + Region: v.Region, + }, nil +} + +func regionInfoFromWire(w *regionInfoWire) (*RegionInfo, error) { + if w == nil { + return nil, nil + } + return &RegionInfo{ + Cloud: w.Cloud, + Region: w.Region, + }, nil +} + +type repoInfoWire struct { + GitRepoUrl *string `json:"git_repo_url,omitempty"` +} + +func repoInfoToWire(v *RepoInfo) (*repoInfoWire, error) { + if v == nil { + return nil, nil + } + return &repoInfoWire{ + GitRepoUrl: v.GitRepoUrl, + }, nil +} + +func repoInfoFromWire(w *repoInfoWire) (*RepoInfo, error) { + if w == nil { + return nil, nil + } + return &RepoInfo{ + GitRepoUrl: w.GitRepoUrl, + }, nil +} + +type repoInstallationWire struct { + RepoName *string `json:"repo_name,omitempty"` + RepoPath *string `json:"repo_path,omitempty"` +} + +func repoInstallationToWire(v *RepoInstallation) (*repoInstallationWire, error) { + if v == nil { + return nil, nil + } + return &repoInstallationWire{ + RepoName: v.RepoName, + RepoPath: v.RepoPath, + }, nil +} + +type searchPublishedListingsForConsumerRequestWire struct { + Query *string `json:"query,omitempty"` + IsFree *bool `json:"is_free,omitempty"` + IsPrivateExchange *bool `json:"is_private_exchange,omitempty"` + ProviderIds []string `json:"provider_ids,omitempty"` + Categories []Category `json:"categories,omitempty"` + Assets []AssetType `json:"assets,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func searchPublishedListingsForConsumerRequestToWire(v *SearchPublishedListingsForConsumerRequest) (*searchPublishedListingsForConsumerRequestWire, error) { + if v == nil { + return nil, nil + } + return &searchPublishedListingsForConsumerRequestWire{ + Query: v.Query, + IsFree: v.IsFree, + IsPrivateExchange: v.IsPrivateExchange, + ProviderIds: v.ProviderIds, + Categories: v.Categories, + Assets: v.Assets, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type searchPublishedListingsForConsumerResponseWire struct { + Listings []listingWire `json:"listings,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func searchPublishedListingsForConsumerResponseFromWire(w *searchPublishedListingsForConsumerResponseWire) (*SearchPublishedListingsForConsumerResponse, error) { + if w == nil { + return nil, nil + } + listingsPublicValue, err := convertSlice(w.Listings, listingFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SearchPublishedListingsForConsumerResponse.Listings", err) + } + return &SearchPublishedListingsForConsumerResponse{ + Listings: listingsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type shareInfoWire struct { + Name *string `json:"name,omitempty"` + Type ListingShareType `json:"type,omitempty"` +} + +func shareInfoToWire(v *ShareInfo) (*shareInfoWire, error) { + if v == nil { + return nil, nil + } + return &shareInfoWire{ + Name: v.Name, + Type: v.Type, + }, nil +} + +func shareInfoFromWire(w *shareInfoWire) (*ShareInfo, error) { + if w == nil { + return nil, nil + } + return &ShareInfo{ + Name: w.Name, + Type: w.Type, + }, nil +} + +type sharedDataObjectWire struct { + Name *string `json:"name,omitempty"` + DataObjectType *string `json:"data_object_type,omitempty"` +} + +func sharedDataObjectFromWire(w *sharedDataObjectWire) (*SharedDataObject, error) { + if w == nil { + return nil, nil + } + return &SharedDataObject{ + Name: w.Name, + DataObjectType: w.DataObjectType, + }, nil +} + +type tokenDetailWire struct { + ShareCredentialsVersion *int `json:"shareCredentialsVersion,omitempty"` + BearerToken *string `json:"bearerToken,omitempty"` + Endpoint *string `json:"endpoint,omitempty"` + ExpirationTime *string `json:"expirationTime,omitempty"` +} + +func tokenDetailToWire(v *TokenDetail) (*tokenDetailWire, error) { + if v == nil { + return nil, nil + } + return &tokenDetailWire{ + ShareCredentialsVersion: v.ShareCredentialsVersion, + BearerToken: v.BearerToken, + Endpoint: v.Endpoint, + ExpirationTime: v.ExpirationTime, + }, nil +} + +func tokenDetailFromWire(w *tokenDetailWire) (*TokenDetail, error) { + if w == nil { + return nil, nil + } + return &TokenDetail{ + ShareCredentialsVersion: w.ShareCredentialsVersion, + BearerToken: w.BearerToken, + Endpoint: w.Endpoint, + ExpirationTime: w.ExpirationTime, + }, nil +} + +type tokenInfoWire struct { + Id *string `json:"id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + ActivationUrl *string `json:"activation_url,omitempty"` + ExpirationTime *int64 `json:"expiration_time,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` +} + +func tokenInfoToWire(v *TokenInfo) (*tokenInfoWire, error) { + if v == nil { + return nil, nil + } + return &tokenInfoWire{ + Id: v.Id, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + ActivationUrl: v.ActivationUrl, + ExpirationTime: v.ExpirationTime, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + }, nil +} + +func tokenInfoFromWire(w *tokenInfoWire) (*TokenInfo, error) { + if w == nil { + return nil, nil + } + return &TokenInfo{ + Id: w.Id, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + ActivationUrl: w.ActivationUrl, + ExpirationTime: w.ExpirationTime, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + }, nil +} + +type updateExchangeFilterRequestWire struct { + Id *string `json:"id,omitempty"` + Filter *exchangeFilterWire `json:"filter,omitempty"` +} + +func updateExchangeFilterRequestToWire(v *UpdateExchangeFilterRequest) (*updateExchangeFilterRequestWire, error) { + if v == nil { + return nil, nil + } + filterWireValue, err := exchangeFilterToWire(v.Filter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExchangeFilterRequest.Filter", err) + } + return &updateExchangeFilterRequestWire{ + Id: v.Id, + Filter: filterWireValue, + }, nil +} + +type updateExchangeFilterResponseWire struct { + Filter *exchangeFilterWire `json:"filter,omitempty"` +} + +func updateExchangeFilterResponseFromWire(w *updateExchangeFilterResponseWire) (*UpdateExchangeFilterResponse, error) { + if w == nil { + return nil, nil + } + filterPublicValue, err := exchangeFilterFromWire(w.Filter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExchangeFilterResponse.Filter", err) + } + return &UpdateExchangeFilterResponse{ + Filter: filterPublicValue, + }, nil +} + +type updateExchangeRequestWire struct { + Id *string `json:"id,omitempty"` + Exchange *exchangeWire `json:"exchange,omitempty"` +} + +func updateExchangeRequestToWire(v *UpdateExchangeRequest) (*updateExchangeRequestWire, error) { + if v == nil { + return nil, nil + } + exchangeWireValue, err := exchangeToWire(v.Exchange) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExchangeRequest.Exchange", err) + } + return &updateExchangeRequestWire{ + Id: v.Id, + Exchange: exchangeWireValue, + }, nil +} + +type updateExchangeResponseWire struct { + Exchange *exchangeWire `json:"exchange,omitempty"` +} + +func updateExchangeResponseFromWire(w *updateExchangeResponseWire) (*UpdateExchangeResponse, error) { + if w == nil { + return nil, nil + } + exchangePublicValue, err := exchangeFromWire(w.Exchange) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExchangeResponse.Exchange", err) + } + return &UpdateExchangeResponse{ + Exchange: exchangePublicValue, + }, nil +} + +type updateInstallationRequestWire struct { + ListingId *string `json:"listing_id,omitempty"` + InstallationId *string `json:"installation_id,omitempty"` + Installation *installationDetailWire `json:"installation,omitempty"` + RotateToken *bool `json:"rotate_token,omitempty"` +} + +func updateInstallationRequestToWire(v *UpdateInstallationRequest) (*updateInstallationRequestWire, error) { + if v == nil { + return nil, nil + } + installationWireValue, err := installationDetailToWire(v.Installation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateInstallationRequest.Installation", err) + } + return &updateInstallationRequestWire{ + ListingId: v.ListingId, + InstallationId: v.InstallationId, + Installation: installationWireValue, + RotateToken: v.RotateToken, + }, nil +} + +type updateInstallationResponseWire struct { + Installation *installationDetailWire `json:"installation,omitempty"` +} + +func updateInstallationResponseFromWire(w *updateInstallationResponseWire) (*UpdateInstallationResponse, error) { + if w == nil { + return nil, nil + } + installationPublicValue, err := installationDetailFromWire(w.Installation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateInstallationResponse.Installation", err) + } + return &UpdateInstallationResponse{ + Installation: installationPublicValue, + }, nil +} + +type updateListingRequestWire struct { + Id *string `json:"id,omitempty"` + Listing *listingWire `json:"listing,omitempty"` +} + +func updateListingRequestToWire(v *UpdateListingRequest) (*updateListingRequestWire, error) { + if v == nil { + return nil, nil + } + listingWireValue, err := listingToWire(v.Listing) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateListingRequest.Listing", err) + } + return &updateListingRequestWire{ + Id: v.Id, + Listing: listingWireValue, + }, nil +} + +type updateListingResponseWire struct { + Listing *listingWire `json:"listing,omitempty"` +} + +func updateListingResponseFromWire(w *updateListingResponseWire) (*UpdateListingResponse, error) { + if w == nil { + return nil, nil + } + listingPublicValue, err := listingFromWire(w.Listing) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateListingResponse.Listing", err) + } + return &UpdateListingResponse{ + Listing: listingPublicValue, + }, nil +} + +type updatePersonalizationRequestStatusRequestWire struct { + ListingId *string `json:"listing_id,omitempty"` + RequestId *string `json:"request_id,omitempty"` + Status PersonalizationRequestStatus `json:"status,omitempty"` + Reason *string `json:"reason,omitempty"` + Share *shareInfoWire `json:"share,omitempty"` +} + +func updatePersonalizationRequestStatusRequestToWire(v *UpdatePersonalizationRequestStatusRequest) (*updatePersonalizationRequestStatusRequestWire, error) { + if v == nil { + return nil, nil + } + shareWireValue, err := shareInfoToWire(v.Share) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdatePersonalizationRequestStatusRequest.Share", err) + } + return &updatePersonalizationRequestStatusRequestWire{ + ListingId: v.ListingId, + RequestId: v.RequestId, + Status: v.Status, + Reason: v.Reason, + Share: shareWireValue, + }, nil +} + +type updatePersonalizationRequestStatusResponseWire struct { + Request *personalizationRequestWire `json:"request,omitempty"` +} + +func updatePersonalizationRequestStatusResponseFromWire(w *updatePersonalizationRequestStatusResponseWire) (*UpdatePersonalizationRequestStatusResponse, error) { + if w == nil { + return nil, nil + } + requestPublicValue, err := personalizationRequestFromWire(w.Request) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdatePersonalizationRequestStatusResponse.Request", err) + } + return &UpdatePersonalizationRequestStatusResponse{ + Request: requestPublicValue, + }, nil +} + +type updateProviderAnalyticsDashboardRequestWire struct { + Id *string `json:"id,omitempty"` + Version *int64 `json:"version,omitempty"` +} + +func updateProviderAnalyticsDashboardRequestToWire(v *UpdateProviderAnalyticsDashboardRequest) (*updateProviderAnalyticsDashboardRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateProviderAnalyticsDashboardRequestWire{ + Id: v.Id, + Version: v.Version, + }, nil +} + +type updateProviderAnalyticsDashboardResponseWire struct { + Id *string `json:"id,omitempty"` + Version *int64 `json:"version,omitempty"` + DashboardId *string `json:"dashboard_id,omitempty"` +} + +func updateProviderAnalyticsDashboardResponseFromWire(w *updateProviderAnalyticsDashboardResponseWire) (*UpdateProviderAnalyticsDashboardResponse, error) { + if w == nil { + return nil, nil + } + return &UpdateProviderAnalyticsDashboardResponse{ + Id: w.Id, + Version: w.Version, + DashboardId: w.DashboardId, + }, nil +} + +type updateProviderRequestWire struct { + Id *string `json:"id,omitempty"` + Provider *providerInfoWire `json:"provider,omitempty"` +} + +func updateProviderRequestToWire(v *UpdateProviderRequest) (*updateProviderRequestWire, error) { + if v == nil { + return nil, nil + } + providerWireValue, err := providerInfoToWire(v.Provider) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateProviderRequest.Provider", err) + } + return &updateProviderRequestWire{ + Id: v.Id, + Provider: providerWireValue, + }, nil +} + +type updateProviderResponseWire struct { + Provider *providerInfoWire `json:"provider,omitempty"` +} + +func updateProviderResponseFromWire(w *updateProviderResponseWire) (*UpdateProviderResponse, error) { + if w == nil { + return nil, nil + } + providerPublicValue, err := providerInfoFromWire(w.Provider) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateProviderResponse.Provider", err) + } + return &UpdateProviderResponse{ + Provider: providerPublicValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/modelregistry/.package.json b/modelregistry/.package.json new file mode 100644 index 0000000..97d2951 --- /dev/null +++ b/modelregistry/.package.json @@ -0,0 +1,3 @@ +{ + "package": "modelregistry" +} diff --git a/modelregistry/CHANGELOG.md b/modelregistry/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/modelregistry/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/modelregistry/README.md b/modelregistry/README.md new file mode 100644 index 0000000..2c31f86 --- /dev/null +++ b/modelregistry/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/modelregistry + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/modelregistry@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/modelregistry/v1" + +client, err := modelregistry.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/modelregistry/go.mod b/modelregistry/go.mod new file mode 100644 index 0000000..00a624f --- /dev/null +++ b/modelregistry/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/modelregistry + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/modelregistry/internal/version.go b/modelregistry/internal/version.go new file mode 100644 index 0000000..2e3e93e --- /dev/null +++ b/modelregistry/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-modelregistry" + +const Version = "0.0.1-dev.1" diff --git a/modelregistry/v1/client.go b/modelregistry/v1/client.go new file mode 100755 index 0000000..ccf7960 --- /dev/null +++ b/modelregistry/v1/client.go @@ -0,0 +1,2361 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelregistry + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/modelregistry/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Approves a model version stage transition request. +func (c *internalClient) ApproveTransitionRequest(ctx context.Context, req *ApproveTransitionRequest, opts ...call.Option) (*ApproveTransitionResponse, error) { + wireReq, err := approveTransitionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/transition-requests/approve" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ApproveTransitionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp approveTransitionResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = approveTransitionResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Posts a comment on a model version. A comment can be submitted either by a +// user or programmatically to display relevant information about the model. For +// example, test results or deployment errors. +func (c *internalClient) CreateComment(ctx context.Context, req *CreateCommentRequest, opts ...call.Option) (*CreateCommentResponse, error) { + wireReq, err := createCommentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/comments/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateCommentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createCommentResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createCommentResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// **NOTE:** This endpoint is in Public Preview. Creates a registry webhook. +func (c *internalClient) CreateRegistryWebhook(ctx context.Context, req *CreateRegistryWebhookRequest, opts ...call.Option) (*CreateRegistryWebhookResponse, error) { + wireReq, err := createRegistryWebhookRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registry-webhooks/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateRegistryWebhookResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createRegistryWebhookResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createRegistryWebhookResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a model version stage transition request. +func (c *internalClient) CreateTransitionRequest(ctx context.Context, req *CreateTransitionRequest, opts ...call.Option) (*CreateTransitionResponse, error) { + wireReq, err := createTransitionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/transition-requests/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateTransitionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createTransitionResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createTransitionResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a comment on a model version. +func (c *internalClient) DeleteComment(ctx context.Context, req *DeleteCommentRequest, opts ...call.Option) (*DeleteCommentResponse, error) { + wireReq, err := deleteCommentRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/comments/delete" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "id", wireReq.Id); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteCommentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteCommentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// **NOTE:** This endpoint is in Public Preview. Deletes a registry webhook. +func (c *internalClient) DeleteRegistryWebhook(ctx context.Context, req *DeleteRegistryWebhookRequest, opts ...call.Option) (*DeleteRegistryWebhookResponse, error) { + wireReq, err := deleteRegistryWebhookRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registry-webhooks/delete" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "id", wireReq.Id); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteRegistryWebhookResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteRegistryWebhookResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Cancels a model version stage transition request. +func (c *internalClient) DeleteTransitionRequest(ctx context.Context, req *DeleteTransitionRequest, opts ...call.Option) (*DeleteTransitionResponse, error) { + wireReq, err := deleteTransitionRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/transition-requests/delete" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "version", wireReq.Version); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "stage", wireReq.Stage); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "creator", wireReq.Creator); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "comment", wireReq.Comment); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteTransitionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp deleteTransitionResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = deleteTransitionResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get the details of a model. This is a workspace version of the +// [MLflow endpoint] that also returns the model's workspace ID and +// the permission level of the requesting user on the model. +// +// [MLflow endpoint]: https://www.mlflow.org/docs/latest/rest-api.html#get-registeredmodel +func (c *internalClient) GetRegisteredModelDatabricks(ctx context.Context, req *GetRegisteredModelDatabricksRequest, opts ...call.Option) (*GetRegisteredModelDatabricksResponse, error) { + wireReq, err := getRegisteredModelDatabricksRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/databricks/registered-models/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetRegisteredModelDatabricksResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getRegisteredModelDatabricksResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getRegisteredModelDatabricksResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// **NOTE:** This endpoint is in Public Preview. Lists all registry webhooks. +func (c *internalClient) ListRegistryWebhooks(ctx context.Context, req *ListRegistryWebhooksRequest, opts ...call.Option) (*ListRegistryWebhooksResponse, error) { + wireReq, err := listRegistryWebhooksRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registry-webhooks/list" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "model_name", wireReq.ModelName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "events", wireReq.Events); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListRegistryWebhooksResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listRegistryWebhooksResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listRegistryWebhooksResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListRegistryWebhooksIter returns an iterator that iterates +// over the results of ListRegistryWebhooks. +// +// For example: +// +// for item, err := range c.ListRegistryWebhooksIter(ctx, &ListRegistryWebhooksRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListRegistryWebhooks call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListRegistryWebhooks directly. +func (c *internalClient) ListRegistryWebhooksIter(ctx context.Context, req *ListRegistryWebhooksRequest, opts ...call.Option) iter.Seq2[*RegistryWebhook, error] { + return func(yield func(*RegistryWebhook, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListRegistryWebhooksRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListRegistryWebhooks(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Webhooks { + if !yield(&resp.Webhooks[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Gets a list of all open stage transition requests for the model version. +func (c *internalClient) ListTransitionRequests(ctx context.Context, req *ListTransitionRequest, opts ...call.Option) (*ListTransitionResponse, error) { + wireReq, err := listTransitionRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/transition-requests/list" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "version", wireReq.Version); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListTransitionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listTransitionResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listTransitionResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Rejects a model version stage transition request. +func (c *internalClient) RejectTransitionRequest(ctx context.Context, req *RejectTransitionRequest, opts ...call.Option) (*RejectTransitionResponse, error) { + wireReq, err := rejectTransitionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/transition-requests/reject" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RejectTransitionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp rejectTransitionResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = rejectTransitionResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// **NOTE:** This endpoint is in Public Preview. Tests a registry webhook. +func (c *internalClient) TestRegistryWebhook(ctx context.Context, req *TestRegistryWebhookRequest, opts ...call.Option) (*TestRegistryWebhookResponse, error) { + wireReq, err := testRegistryWebhookRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registry-webhooks/test" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TestRegistryWebhookResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp testRegistryWebhookResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = testRegistryWebhookResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Transition a model version's stage. This is a workspace version +// of the [MLflow endpoint] that also accepts a comment associated with the +// transition to be recorded. +// +// [MLflow endpoint]: https://www.mlflow.org/docs/latest/rest-api.html#transition-modelversion-stage +func (c *internalClient) TransitionModelVersionStageDatabricks(ctx context.Context, req *TransitionModelVersionStageDatabricksRequest, opts ...call.Option) (*TransitionModelVersionStageDatabricksResponse, error) { + wireReq, err := transitionModelVersionStageDatabricksRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/databricks/model-versions/transition-stage" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TransitionModelVersionStageDatabricksResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp transitionModelVersionStageDatabricksResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = transitionModelVersionStageDatabricksResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Post an edit to a comment on a model version. +func (c *internalClient) UpdateComment(ctx context.Context, req *UpdateCommentRequest, opts ...call.Option) (*UpdateCommentResponse, error) { + wireReq, err := updateCommentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/comments/update" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateCommentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateCommentResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateCommentResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// **NOTE:** This endpoint is in Public Preview. Updates a registry webhook. +func (c *internalClient) UpdateRegistryWebhook(ctx context.Context, req *UpdateRegistryWebhookRequest, opts ...call.Option) (*UpdateRegistryWebhookResponse, error) { + wireReq, err := updateRegistryWebhookRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registry-webhooks/update" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateRegistryWebhookResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateRegistryWebhookResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateRegistryWebhookResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a model version. +func (c *internalClient) CreateModelVersion(ctx context.Context, req *CreateModelVersionRequest, opts ...call.Option) (*CreateModelVersionResponse, error) { + wireReq, err := createModelVersionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/model-versions/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateModelVersionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createModelVersionResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createModelVersionResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new registered model with the name specified in the request body. +// Throws `RESOURCE_ALREADY_EXISTS` if a registered model with the given name +// exists. +func (c *internalClient) CreateRegisteredModel(ctx context.Context, req *CreateRegisteredModelRequest, opts ...call.Option) (*CreateRegisteredModelResponse, error) { + wireReq, err := createRegisteredModelRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registered-models/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateRegisteredModelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createRegisteredModelResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createRegisteredModelResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a model version. +func (c *internalClient) DeleteModelVersion(ctx context.Context, req *DeleteModelVersionRequest, opts ...call.Option) (*DeleteModelVersionResponse, error) { + wireReq, err := deleteModelVersionRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/model-versions/delete" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "version", wireReq.Version); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteModelVersionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteModelVersionResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a model version tag. +func (c *internalClient) DeleteModelVersionTag(ctx context.Context, req *DeleteModelVersionTagRequest, opts ...call.Option) (*DeleteModelVersionTagResponse, error) { + wireReq, err := deleteModelVersionTagRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/model-versions/delete-tag" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "version", wireReq.Version); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "key", wireReq.Key); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteModelVersionTagResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteModelVersionTagResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a registered model. +func (c *internalClient) DeleteRegisteredModel(ctx context.Context, req *DeleteRegisteredModelRequest, opts ...call.Option) (*DeleteRegisteredModelResponse, error) { + wireReq, err := deleteRegisteredModelRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registered-models/delete" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteRegisteredModelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteRegisteredModelResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the tag for a registered model. +func (c *internalClient) DeleteRegisteredModelTag(ctx context.Context, req *DeleteRegisteredModelTagRequest, opts ...call.Option) (*DeleteRegisteredModelTagResponse, error) { + wireReq, err := deleteRegisteredModelTagRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registered-models/delete-tag" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "key", wireReq.Key); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteRegisteredModelTagResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteRegisteredModelTagResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a model version. +func (c *internalClient) GetModelVersion(ctx context.Context, req *GetModelVersionRequest, opts ...call.Option) (*GetModelVersionResponse, error) { + wireReq, err := getModelVersionRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/model-versions/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "version", wireReq.Version); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetModelVersionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getModelVersionResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getModelVersionResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a URI to download the model version. +func (c *internalClient) GetModelVersionDownloadUri(ctx context.Context, req *GetModelVersionDownloadUriRequest, opts ...call.Option) (*GetModelVersionDownloadUriResponse, error) { + wireReq, err := getModelVersionDownloadUriRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/model-versions/get-download-uri" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "name", wireReq.Name); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "version", wireReq.Version); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetModelVersionDownloadUriResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getModelVersionDownloadUriResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getModelVersionDownloadUriResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the latest version of a registered model. +func (c *internalClient) ListLatestVersions(ctx context.Context, req *ListLatestVersionsRequest, opts ...call.Option) (*GetLatestVersionsResponse, error) { + wireReq, err := listLatestVersionsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registered-models/get-latest-versions" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetLatestVersionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getLatestVersionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getLatestVersionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists all available registered models, up to the limit specified in +// __max_results__. +func (c *internalClient) ListRegisteredModels(ctx context.Context, req *ListRegisteredModelsRequest, opts ...call.Option) (*ListRegisteredModelsResponse, error) { + wireReq, err := listRegisteredModelsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registered-models/list" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListRegisteredModelsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listRegisteredModelsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listRegisteredModelsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListRegisteredModelsIter returns an iterator that iterates +// over the results of ListRegisteredModels. +// +// For example: +// +// for item, err := range c.ListRegisteredModelsIter(ctx, &ListRegisteredModelsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListRegisteredModels call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListRegisteredModels directly. +func (c *internalClient) ListRegisteredModelsIter(ctx context.Context, req *ListRegisteredModelsRequest, opts ...call.Option) iter.Seq2[*RegisteredModel, error] { + return func(yield func(*RegisteredModel, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListRegisteredModelsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListRegisteredModels(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.RegisteredModels { + if !yield(&resp.RegisteredModels[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Renames a registered model. +func (c *internalClient) RenameRegisteredModel(ctx context.Context, req *RenameRegisteredModelRequest, opts ...call.Option) (*RenameRegisteredModelResponse, error) { + wireReq, err := renameRegisteredModelRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registered-models/rename" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RenameRegisteredModelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp renameRegisteredModelResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = renameRegisteredModelResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Searches for specific model versions based on the supplied __filter__. +func (c *internalClient) SearchModelVersions(ctx context.Context, req *SearchModelVersionsRequest, opts ...call.Option) (*SearchModelVersionsResponse, error) { + wireReq, err := searchModelVersionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/model-versions/search" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "order_by", wireReq.OrderBy); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SearchModelVersionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp searchModelVersionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = searchModelVersionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// SearchModelVersionsIter returns an iterator that iterates +// over the results of SearchModelVersions. +// +// For example: +// +// for item, err := range c.SearchModelVersionsIter(ctx, &SearchModelVersionsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each SearchModelVersions call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// SearchModelVersions directly. +func (c *internalClient) SearchModelVersionsIter(ctx context.Context, req *SearchModelVersionsRequest, opts ...call.Option) iter.Seq2[*ModelVersion, error] { + return func(yield func(*ModelVersion, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := SearchModelVersionsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.SearchModelVersions(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ModelVersions { + if !yield(&resp.ModelVersions[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Search for registered models based on the specified __filter__. +func (c *internalClient) SearchRegisteredModels(ctx context.Context, req *SearchRegisteredModelsRequest, opts ...call.Option) (*SearchRegisteredModelsResponse, error) { + wireReq, err := searchRegisteredModelsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registered-models/search" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "order_by", wireReq.OrderBy); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SearchRegisteredModelsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp searchRegisteredModelsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = searchRegisteredModelsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// SearchRegisteredModelsIter returns an iterator that iterates +// over the results of SearchRegisteredModels. +// +// For example: +// +// for item, err := range c.SearchRegisteredModelsIter(ctx, &SearchRegisteredModelsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each SearchRegisteredModels call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// SearchRegisteredModels directly. +func (c *internalClient) SearchRegisteredModelsIter(ctx context.Context, req *SearchRegisteredModelsRequest, opts ...call.Option) iter.Seq2[*RegisteredModel, error] { + return func(yield func(*RegisteredModel, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := SearchRegisteredModelsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.SearchRegisteredModels(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.RegisteredModels { + if !yield(&resp.RegisteredModels[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Sets a model version tag. +func (c *internalClient) SetModelVersionTag(ctx context.Context, req *SetModelVersionTagRequest, opts ...call.Option) (*SetModelVersionTagResponse, error) { + wireReq, err := setModelVersionTagRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/model-versions/set-tag" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SetModelVersionTagResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &SetModelVersionTagResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Sets a tag on a registered model. +func (c *internalClient) SetRegisteredModelTag(ctx context.Context, req *SetRegisteredModelTagRequest, opts ...call.Option) (*SetRegisteredModelTagResponse, error) { + wireReq, err := setRegisteredModelTagRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registered-models/set-tag" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SetRegisteredModelTagResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &SetRegisteredModelTagResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the model version. +func (c *internalClient) UpdateModelVersion(ctx context.Context, req *UpdateModelVersionRequest, opts ...call.Option) (*UpdateModelVersionResponse, error) { + wireReq, err := updateModelVersionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/model-versions/update" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateModelVersionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateModelVersionResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateModelVersionResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a registered model. +func (c *internalClient) UpdateRegisteredModel(ctx context.Context, req *UpdateRegisteredModelRequest, opts ...call.Option) (*UpdateRegisteredModelResponse, error) { + wireReq, err := updateRegisteredModelRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/mlflow/registered-models/update" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateRegisteredModelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateRegisteredModelResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateRegisteredModelResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/modelregistry/v1/genhelper.go b/modelregistry/v1/genhelper.go new file mode 100755 index 0000000..70bfce7 --- /dev/null +++ b/modelregistry/v1/genhelper.go @@ -0,0 +1,178 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelregistry + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} diff --git a/modelregistry/v1/model.go b/modelregistry/v1/model.go new file mode 100755 index 0000000..db49f29 --- /dev/null +++ b/modelregistry/v1/model.go @@ -0,0 +1,999 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelregistry + +// An action that a user (with sufficient permissions) could take on an activity +// or comment. +// +// For activities, valid values are: * `APPROVE_TRANSITION_REQUEST`: Approve a +// transition request * `REJECT_TRANSITION_REQUEST`: Reject a transition request +// * `CANCEL_TRANSITION_REQUEST`: Cancel (delete) a transition request For +// comments, valid values are: * `EDIT_COMMENT`: Edit the comment * +// `DELETE_COMMENT`: Delete the comment +type ActivityAction string + +const ( + ActivityAction_Unspecified ActivityAction = "" + // Approve a transition request. Available to users with sufficient permissions. + ActivityAction_ApproveTransitionRequest ActivityAction = "APPROVE_TRANSITION_REQUEST" + // Reject a transition request. Available to users with sufficient permissions. + ActivityAction_RejectTransitionRequest ActivityAction = "REJECT_TRANSITION_REQUEST" + // Cancel a transition request. Available to the user who created the request. + ActivityAction_CancelTransitionRequest ActivityAction = "CANCEL_TRANSITION_REQUEST" + // Edit the comment + ActivityAction_EditComment ActivityAction = "EDIT_COMMENT" + // Delete the comment + ActivityAction_DeleteComment ActivityAction = "DELETE_COMMENT" +) + +// Type of activity. Valid values are: * `APPLIED_TRANSITION`: User applied the +// corresponding stage transition. * `REQUESTED_TRANSITION`: User requested the +// corresponding stage transition. * `CANCELLED_REQUEST`: User cancelled an +// existing transition request. * `APPROVED_REQUEST`: User approved the +// corresponding stage transition. * `REJECTED_REQUEST`: User rejected the +// coressponding stage transition. * `SYSTEM_TRANSITION`: For events performed +// as a side effect, such as archiving existing model versions in a stage. +type ActivityType string + +const ( + ActivityType_Unspecified ActivityType = "" + // Indicates that the corresponding stage transition was applied by user. + ActivityType_AppliedTransition ActivityType = "APPLIED_TRANSITION" + // Corresponding stage transition was requested by user. + ActivityType_RequestedTransition ActivityType = "REQUESTED_TRANSITION" + // User cancelled an existing request. + ActivityType_CancelledRequest ActivityType = "CANCELLED_REQUEST" + // Corresponding transition request was approved by user. + ActivityType_ApprovedRequest ActivityType = "APPROVED_REQUEST" + // Corresponding transition request was rejected by user. + ActivityType_RejectedRequest ActivityType = "REJECTED_REQUEST" + // User posted a new comment + ActivityType_NewComment ActivityType = "NEW_COMMENT" + // Corresponding transition for events such as archiving existing model versions + ActivityType_SystemTransition ActivityType = "SYSTEM_TRANSITION" +) + +// The status of the model version. Valid values are: * `PENDING_REGISTRATION`: +// Request to register a new model version is pending as server performs +// background tasks. +// +// * `FAILED_REGISTRATION`: Request to register a new model version has failed. +// +// * `READY`: Model version is ready for use. +type ModelVersionStatus string + +const ( + ModelVersionStatus_Unspecified ModelVersionStatus = "" + // Request to register a new model version is pending as server performs + // background tasks. + ModelVersionStatus_PendingRegistration ModelVersionStatus = "PENDING_REGISTRATION" + // Request to register a new model version has failed. + ModelVersionStatus_FailedRegistration ModelVersionStatus = "FAILED_REGISTRATION" + // Model version is ready for use. + ModelVersionStatus_Ready ModelVersionStatus = "READY" +) + +// Permission level of the requesting user on the object. For what is allowed at +// each level, see [MLflow Model permissions](..). +type PermissionLevel string + +const ( + PermissionLevel_Unspecified PermissionLevel = "" + // reserved 1; // IS_OWNER = 1; was DEPRECATED + PermissionLevel_CanEdit PermissionLevel = "CAN_EDIT" + PermissionLevel_CanRead PermissionLevel = "CAN_READ" + PermissionLevel_CanManageStagingVersions PermissionLevel = "CAN_MANAGE_STAGING_VERSIONS" + PermissionLevel_CanManageProductionVersions PermissionLevel = "CAN_MANAGE_PRODUCTION_VERSIONS" + // Only applicable to the root ACL path, for which it is the default value if no + // permissions are set explicitly for the user. It is the default set by the + // MLflow service and The ACL database does not understand this value. + PermissionLevel_CanCreateRegisteredModel PermissionLevel = "CAN_CREATE_REGISTERED_MODEL" +) + +// .. note:: Experimental: This entity may change or be removed in a future +// release without warning. Email subscription types for registry notifications: +// - `ALL_EVENTS`: Subscribed to all events. - `DEFAULT`: Default subscription +// type. - `SUBSCRIBED`: Subscribed to notifications. - `UNSUBSCRIBED`: Not +// subscribed to notifications. +type RegistryEmailSubscriptionType string + +const ( + RegistryEmailSubscriptionType_Unspecified RegistryEmailSubscriptionType = "" + RegistryEmailSubscriptionType_AllEvents RegistryEmailSubscriptionType = "ALL_EVENTS" + RegistryEmailSubscriptionType_Default RegistryEmailSubscriptionType = "DEFAULT" + RegistryEmailSubscriptionType_Subscribed RegistryEmailSubscriptionType = "SUBSCRIBED" + RegistryEmailSubscriptionType_Unsubscribed RegistryEmailSubscriptionType = "UNSUBSCRIBED" +) + +type RegistryWebhookEvent string + +const ( + RegistryWebhookEvent_Unspecified RegistryWebhookEvent = "" + RegistryWebhookEvent_ModelVersionCreated RegistryWebhookEvent = "MODEL_VERSION_CREATED" + RegistryWebhookEvent_ModelVersionTransitionedStage RegistryWebhookEvent = "MODEL_VERSION_TRANSITIONED_STAGE" + RegistryWebhookEvent_TransitionRequestCreated RegistryWebhookEvent = "TRANSITION_REQUEST_CREATED" + RegistryWebhookEvent_CommentCreated RegistryWebhookEvent = "COMMENT_CREATED" + RegistryWebhookEvent_RegisteredModelCreated RegistryWebhookEvent = "REGISTERED_MODEL_CREATED" + RegistryWebhookEvent_ModelVersionTagSet RegistryWebhookEvent = "MODEL_VERSION_TAG_SET" + RegistryWebhookEvent_ModelVersionTransitionedToStaging RegistryWebhookEvent = "MODEL_VERSION_TRANSITIONED_TO_STAGING" + RegistryWebhookEvent_ModelVersionTransitionedToProduction RegistryWebhookEvent = "MODEL_VERSION_TRANSITIONED_TO_PRODUCTION" + RegistryWebhookEvent_ModelVersionTransitionedToArchived RegistryWebhookEvent = "MODEL_VERSION_TRANSITIONED_TO_ARCHIVED" + RegistryWebhookEvent_TransitionRequestToStagingCreated RegistryWebhookEvent = "TRANSITION_REQUEST_TO_STAGING_CREATED" + RegistryWebhookEvent_TransitionRequestToProductionCreated RegistryWebhookEvent = "TRANSITION_REQUEST_TO_PRODUCTION_CREATED" + RegistryWebhookEvent_TransitionRequestToArchivedCreated RegistryWebhookEvent = "TRANSITION_REQUEST_TO_ARCHIVED_CREATED" +) + +// Enable or disable triggering the webhook, or put the webhook into test mode. +// The default is `ACTIVE`: * `ACTIVE`: Webhook is triggered when an associated +// event happens. * `DISABLED`: Webhook is not triggered. * `TEST_MODE`: Webhook +// can be triggered through the test endpoint, but is not triggered on a real +// event. +type RegistryWebhookStatus string + +const ( + RegistryWebhookStatus_Unspecified RegistryWebhookStatus = "" + // Event and test triggers will be sent. + RegistryWebhookStatus_Active RegistryWebhookStatus = "ACTIVE" + // No triggers will be sent. + RegistryWebhookStatus_Disabled RegistryWebhookStatus = "DISABLED" + // Test triggers will be sent, but not actual events. + RegistryWebhookStatus_TestMode RegistryWebhookStatus = "TEST_MODE" +) + +// For activities, this contains the activity recorded for the action. For +// comments, this contains the comment details. For transition requests, this +// contains the transition request details.. +type Activity struct { + // Creation time of the object, as a Unix timestamp in milliseconds. + CreationTimestamp *int64 + // The username of the user that created the object. + UserId *string + ActivityType ActivityType + // User-provided comment associated with the activity, comment, or transition + // request. + Comment *string + // Time of the object at last update, as a Unix timestamp in milliseconds. + LastUpdatedTimestamp *int64 + // Source stage of the transition (if the activity is stage transition related). + // Valid values are: * `None`: The initial stage of a model version. * + // `Staging`: Staging or pre-production stage. * `Production`: Production stage. + // * `Archived`: Archived stage. + FromStage *string + // Target stage of the transition (if the activity is stage transition related). + // Valid values are: * `None`: The initial stage of a model version. * + // `Staging`: Staging or pre-production stage. * `Production`: Production stage. + // * `Archived`: Archived stage. + ToStage *string + // Comment made by system, for example explaining an activity of type + // `SYSTEM_TRANSITION`. It usually describes a side effect, such as a version + // being archived as part of another version's stage transition, and may not be + // returned for some activity types. + SystemComment *string + // Array of actions on the activity allowed for the current viewer. + AvailableActions []ActivityAction + // Unique identifier for the object. + Id *string +} + +// Details required to identify and approve a model version stage transition +// request.. +type ApproveTransitionRequest struct { + // Name of the model. + Name *string + // Version of the model. + Version *string + // Target stage of the transition. Valid values are: * `None`: The initial stage + // of a model version. * `Staging`: Staging or pre-production stage. * + // `Production`: Production stage. * `Archived`: Archived stage. + Stage *string + // Specifies whether to archive all current model versions in the target stage. + ArchiveExistingVersions *bool + // User-provided comment on the action. + Comment *string +} + +type ApproveTransitionResponse struct { + // New activity generated as a result of this operation. + Activity *Activity +} + +// For activities, this contains the activity recorded for the action. For +// comments, this contains the comment details. For transition requests, this +// contains the transition request details.. +type CommentObject struct { + // Creation time of the object, as a Unix timestamp in milliseconds. + CreationTimestamp *int64 + // The username of the user that created the object. + UserId *string + ActivityType ActivityType + // User-provided comment associated with the activity, comment, or transition + // request. + Comment *string + // Time of the object at last update, as a Unix timestamp in milliseconds. + LastUpdatedTimestamp *int64 + // Source stage of the transition (if the activity is stage transition related). + // Valid values are: * `None`: The initial stage of a model version. * + // `Staging`: Staging or pre-production stage. * `Production`: Production stage. + // * `Archived`: Archived stage. + FromStage *string + // Target stage of the transition (if the activity is stage transition related). + // Valid values are: * `None`: The initial stage of a model version. * + // `Staging`: Staging or pre-production stage. * `Production`: Production stage. + // * `Archived`: Archived stage. + ToStage *string + // Comment made by system, for example explaining an activity of type + // `SYSTEM_TRANSITION`. It usually describes a side effect, such as a version + // being archived as part of another version's stage transition, and may not be + // returned for some activity types. + SystemComment *string + // Array of actions on the activity allowed for the current viewer. + AvailableActions []ActivityAction + // Unique identifier for the object. + Id *string +} + +// Details required to create a comment on a model version.. +type CreateCommentRequest struct { + // Name of the model. + Name *string + // Version of the model. + Version *string + // User-provided comment on the action. + Comment *string +} + +type CreateCommentResponse struct { + // New comment object + Comment *CommentObject +} + +type CreateModelVersionRequest struct { + // Register model under this name + Name *string + // URI indicating the location of the model artifacts. + Source *string + // MLflow run ID for correlation, if `source` was generated by an experiment run + // in MLflow tracking server + RunId *string + // Additional metadata for model version. + Tags []ModelVersionTag + // MLflow run link - this is the exact link of the run that generated this model + // version, potentially hosted at another instance of MLflow. + RunLink *string + // Optional description for model version. + Description *string +} + +type CreateModelVersionResponse struct { + // Return new version number generated for this model in registry. + ModelVersion *ModelVersion +} + +type CreateRegisteredModelRequest struct { + // Register models under this name + Name *string + // Additional metadata for registered model. + Tags []RegisteredModelTag + // Optional description for registered model. + Description *string +} + +type CreateRegisteredModelResponse struct { + RegisteredModel *RegisteredModel +} + +// Details required to create a registry webhook.. +type CreateRegistryWebhookRequest struct { + // If model name is not specified, a registry-wide webhook is created that + // listens for the specified events across all versions of all registered + // models. + ModelName *string + // Events that can trigger a registry webhook: * `MODEL_VERSION_CREATED`: A new + // model version was created for the associated model. * + // `MODEL_VERSION_TRANSITIONED_STAGE`: A model version’s stage was changed. * + // `TRANSITION_REQUEST_CREATED`: A user requested a model version’s stage be + // transitioned. * `COMMENT_CREATED`: A user wrote a comment on a registered + // model. * `REGISTERED_MODEL_CREATED`: A new registered model was created. This + // event type can only be specified for a registry-wide webhook, which can be + // created by not specifying a model name in the create request. * + // `MODEL_VERSION_TAG_SET`: A user set a tag on the model version. * + // `MODEL_VERSION_TRANSITIONED_TO_STAGING`: A model version was transitioned to + // staging. * `MODEL_VERSION_TRANSITIONED_TO_PRODUCTION`: A model version was + // transitioned to production. * `MODEL_VERSION_TRANSITIONED_TO_ARCHIVED`: A + // model version was archived. * `TRANSITION_REQUEST_TO_STAGING_CREATED`: A user + // requested a model version be transitioned to staging. * + // `TRANSITION_REQUEST_TO_PRODUCTION_CREATED`: A user requested a model version + // be transitioned to production. * `TRANSITION_REQUEST_TO_ARCHIVED_CREATED`: A + // user requested a model version be archived. + Events []RegistryWebhookEvent + // User-specified description for the webhook. + Description *string + // Enable or disable triggering the webhook, or put the webhook into test mode. + // The default is `ACTIVE`: * `ACTIVE`: Webhook is triggered when an associated + // event happens. * `DISABLED`: Webhook is not triggered. * `TEST_MODE`: Webhook + // can be triggered through the test endpoint, but is not triggered on a real + // event. + Status RegistryWebhookStatus + // External HTTPS URL called on event trigger (by using a POST request). + HttpUrlSpec *HttpUrlSpec + // ID of the job that the webhook runs. + JobSpec *JobSpec +} + +type CreateRegistryWebhookResponse struct { + Webhook *RegistryWebhook +} + +// Details required to create a model version stage transition request.. +type CreateTransitionRequest struct { + // Name of the model. + Name *string + // Version of the model. + Version *string + // Target stage of the transition. Valid values are: * `None`: The initial stage + // of a model version. * `Staging`: Staging or pre-production stage. * + // `Production`: Production stage. * `Archived`: Archived stage. + Stage *string + // User-provided comment on the action. + Comment *string +} + +type CreateTransitionResponse struct { + // New activity generated for stage transition request. + Request *TransitionRequest +} + +type DeleteCommentRequest struct { + // Unique identifier of an activity + Id *string +} + +type DeleteCommentResponse struct { +} + +type DeleteModelVersionRequest struct { + // Name of the registered model + Name *string + // Model version number + Version *string +} + +type DeleteModelVersionResponse struct { +} + +type DeleteModelVersionTagRequest struct { + // Name of the registered model that the tag was logged under. + Name *string + // Model version number that the tag was logged under. + Version *string + // Name of the tag. The name must be an exact match; wild-card deletion is not + // supported. Maximum size is 250 bytes. + Key *string +} + +type DeleteModelVersionTagResponse struct { +} + +type DeleteRegisteredModelRequest struct { + // Registered model unique name identifier. + Name *string +} + +type DeleteRegisteredModelResponse struct { +} + +type DeleteRegisteredModelTagRequest struct { + // Name of the registered model that the tag was logged under. + Name *string + // Name of the tag. The name must be an exact match; wild-card deletion is not + // supported. Maximum size is 250 bytes. + Key *string +} + +type DeleteRegisteredModelTagResponse struct { +} + +// .. note:: Experimental: This entity may change or be removed in a future +// release without warning.. +type DeleteRegistryWebhookRequest struct { + // Webhook ID required to delete a registry webhook. + Id *string +} + +type DeleteRegistryWebhookResponse struct { +} + +type DeleteTransitionRequest struct { + // Name of the model. + Name *string + // Version of the model. + Version *string + // Target stage of the transition request. Valid values are: * `None`: The + // initial stage of a model version. * `Staging`: Staging or pre-production + // stage. * `Production`: Production stage. * `Archived`: Archived stage. + Stage *string + // Username of the user who created this request. Of the transition requests + // matching the specified details, only the one transition created by this user + // will be deleted. + Creator *string + // User-provided comment on the action. + Comment *string +} + +type DeleteTransitionResponse struct { + // New activity generated as a result of this operation. + Activity *Activity +} + +// Feature list wrap all the features for a model version. +type FeatureList struct { + Features []LinkedFeature +} + +type GetLatestVersionsResponse struct { + // Latest version models for each requests stage. Only return models with + // current `READY` status. If no `stages` provided, returns the latest version + // for each stage, including `"None"`. + ModelVersions []ModelVersion +} + +type GetModelVersionDownloadUriRequest struct { + // Name of the registered model + Name *string + // Model version number + Version *string +} + +type GetModelVersionDownloadUriResponse struct { + // URI corresponding to where artifacts for this model version are stored. + ArtifactUri *string +} + +type GetModelVersionRequest struct { + // Name of the registered model + Name *string + // Model version number + Version *string +} + +type GetModelVersionResponse struct { + ModelVersion *ModelVersion +} + +type GetRegisteredModelDatabricksRequest struct { + // Registered model unique name identifier. + Name *string +} + +type GetRegisteredModelDatabricksResponse struct { + RegisteredModelDatabricks *RegisteredModelDatabricks +} + +type HttpUrlSpec struct { + // External HTTPS URL called on event trigger (by using a POST request). + Url *string + // Enable/disable SSL certificate validation. Default is true. For self-signed + // certificates, this field must be false AND the destination server must + // disable certificate validation as well. For security purposes, it is + // encouraged to perform secret validation with the HMAC-encoded portion of the + // payload and acknowledge the risk associated with disabling hostname + // validation whereby it becomes more likely that requests can be maliciously + // routed to an unintended host. + EnableSslVerification *bool + // Shared secret required for HMAC encoding payload. The HMAC-encoded payload + // will be sent in the header as: { "X-Databricks-Signature": $encoded_payload + // }. + Secret *string + // Value of the authorization header that should be sent in the request sent by + // the wehbook. It should be of the form `" "`. If set + // to an empty string, no authorization header will be included in the request. + Authorization *string +} + +type JobSpec struct { + // ID of the job that the webhook runs. + JobId *string + // URL of the workspace containing the job that this webhook runs. If not + // specified, the job’s workspace URL is assumed to be the same as the + // workspace where the webhook is created. + WorkspaceUrl *string + // The personal access token used to authorize webhook's job runs. + AccessToken *string +} + +// Feature for model version.. +type LinkedFeature struct { + // Feature table name + FeatureTableName *string + // Feature name + FeatureName *string + // Feature table id + FeatureTableId *string +} + +type ListLatestVersionsRequest struct { + // Registered model unique name identifier. + Name *string + // List of stages. + Stages []string +} + +type ListRegisteredModelsRequest struct { + // Maximum number of registered models desired. Max threshold is 1000. + MaxResults *int64 + // Pagination token to go to the next page based on a previous query. + PageToken *string +} + +type ListRegisteredModelsResponse struct { + RegisteredModels []RegisteredModel + // Pagination token to request next page of models for the same query. + NextPageToken *string +} + +type ListRegistryWebhooksRequest struct { + // Registered model name If not specified, all webhooks associated with the + // specified events are listed, regardless of their associated model. + ModelName *string + // Events that trigger the webhook. * `MODEL_VERSION_CREATED`: A new model + // version was created for the associated model. * + // `MODEL_VERSION_TRANSITIONED_STAGE`: A model version’s stage was changed. * + // `TRANSITION_REQUEST_CREATED`: A user requested a model version’s stage be + // transitioned. * `COMMENT_CREATED`: A user wrote a comment on a registered + // model. * `REGISTERED_MODEL_CREATED`: A new registered model was created. This + // event type can only be specified for a registry-wide webhook, which can be + // created by not specifying a model name in the create request. * + // `MODEL_VERSION_TAG_SET`: A user set a tag on the model version. * + // `MODEL_VERSION_TRANSITIONED_TO_STAGING`: A model version was transitioned to + // staging. * `MODEL_VERSION_TRANSITIONED_TO_PRODUCTION`: A model version was + // transitioned to production. * `MODEL_VERSION_TRANSITIONED_TO_ARCHIVED`: A + // model version was archived. * `TRANSITION_REQUEST_TO_STAGING_CREATED`: A user + // requested a model version be transitioned to staging. * + // `TRANSITION_REQUEST_TO_PRODUCTION_CREATED`: A user requested a model version + // be transitioned to production. * `TRANSITION_REQUEST_TO_ARCHIVED_CREATED`: A + // user requested a model version be archived. If `events` is specified, any + // webhook with one or more of the specified trigger events is included in the + // output. If `events` is not specified, webhooks of all event types are + // included in the output. + Events []RegistryWebhookEvent + // Token indicating the page of artifact results to fetch + PageToken *string + MaxResults *int64 +} + +type ListRegistryWebhooksResponse struct { + // Array of registry webhooks. + Webhooks []RegistryWebhook + // Token that can be used to retrieve the next page of artifact results + NextPageToken *string +} + +type ListTransitionRequest struct { + // Name of the registered model. + Name *string + // Version of the model. + Version *string +} + +type ListTransitionResponse struct { + // Array of open transition requests. + Requests []Activity +} + +type ModelVersion struct { + // Unique name of the model + Name *string + // Model's version number. + Version *string + // Timestamp recorded when this `model_version` was created. + CreationTimestamp *int64 + // Timestamp recorded when metadata for this `model_version` was last updated. + LastUpdatedTimestamp *int64 + // User that created this `model_version`. + UserId *string + // Current stage for this `model_version`. + CurrentStage *string + // Description of this `model_version`. + Description *string + // URI indicating the location of the source model artifacts, used when creating + // `model_version` + Source *string + // MLflow run ID used when creating `model_version`, if `source` was generated + // by an experiment run stored in MLflow tracking server. + RunId *string + // Current status of `model_version` + Status ModelVersionStatus + // Details on current `status`, if it is pending or failed. + StatusMessage *string + // Tags: Additional metadata key-value pairs for this `model_version`. + Tags []ModelVersionTag + // Run Link: Direct link to the run that generated this version + RunLink *string +} + +type ModelVersionDatabricks struct { + // Name of the model. + Name *string + // Version of the model. + Version *string + // Creation time of the object, as a Unix timestamp in milliseconds. + CreationTimestamp *int64 + // Time of the object at last update, as a Unix timestamp in milliseconds. + LastUpdatedTimestamp *int64 + // The username of the user that created the object. + UserId *string + CurrentStage *string + // User-specified description for the object. + Description *string + // URI that indicates the location of the source model artifacts. This is used + // when creating the model version. + Source *string + // Unique identifier for the MLflow tracking run associated with the source + // model artifacts. + RunId *string + Status ModelVersionStatus + // Details on the current status, for example why registration failed. + StatusMessage *string + // Open requests for this `model_versions`. Gap in sequence number is + // intentional and is done in order to match field sequence numbers of + // `ModelVersion` proto message + OpenRequests []Activity + PermissionLevel PermissionLevel + // Array of tags that are associated with the model version. + Tags []ModelVersionTag + // URL of the run associated with the model artifacts. This field is set at + // model version creation time only for model versions whose source run is from + // a tracking server that is different from the registry server. + RunLink *string + // Email Subscription Status: This is the subscription status of the user to the + // model version Users get subscribed by interacting with the model version. + EmailSubscriptionStatus RegistryEmailSubscriptionType + // Feature lineage of `model_version`. + FeatureList *FeatureList +} + +type ModelVersionTag struct { + // The tag key. + Key *string + // The tag value. + Value *string +} + +type RegisteredModel struct { + // Unique name for the model. + Name *string + // Timestamp recorded when this `registered_model` was created. + CreationTimestamp *int64 + // Timestamp recorded when metadata for this `registered_model` was last + // updated. + LastUpdatedTimestamp *int64 + // User that created this `registered_model` + UserId *string + // Description of this `registered_model`. + Description *string + // Collection of latest model versions for each stage. Only contains models with + // current `READY` status. + LatestVersions []ModelVersion + // Tags: Additional metadata key-value pairs for this `registered_model`. + Tags []RegisteredModelTag +} + +type RegisteredModelDatabricks struct { + // Name of the model. + Name *string + // Creation time of the object, as a Unix timestamp in milliseconds. + CreationTimestamp *int64 + // Last update time of the object, as a Unix timestamp in milliseconds. + LastUpdatedTimestamp *int64 + // The username of the user that created the object. + UserId *string + // User-specified description for the object. + Description *string + // Array of model versions, each the latest version for its stage. + LatestVersions []ModelVersion + // Unique identifier for the object. + Id *string + // Permission level granted for the requesting user on this registered model + PermissionLevel PermissionLevel + // Array of tags associated with the model. + Tags []RegisteredModelTag +} + +// Tag for a registered model. +type RegisteredModelTag struct { + // The tag key. + Key *string + // The tag value. + Value *string +} + +type RegistryWebhook struct { + // Webhook ID + Id *string + // Events that can trigger a registry webhook: * `MODEL_VERSION_CREATED`: A new + // model version was created for the associated model. * + // `MODEL_VERSION_TRANSITIONED_STAGE`: A model version’s stage was changed. * + // `TRANSITION_REQUEST_CREATED`: A user requested a model version’s stage be + // transitioned. * `COMMENT_CREATED`: A user wrote a comment on a registered + // model. * `REGISTERED_MODEL_CREATED`: A new registered model was created. This + // event type can only be specified for a registry-wide webhook, which can be + // created by not specifying a model name in the create request. * + // `MODEL_VERSION_TAG_SET`: A user set a tag on the model version. * + // `MODEL_VERSION_TRANSITIONED_TO_STAGING`: A model version was transitioned to + // staging. * `MODEL_VERSION_TRANSITIONED_TO_PRODUCTION`: A model version was + // transitioned to production. * `MODEL_VERSION_TRANSITIONED_TO_ARCHIVED`: A + // model version was archived. * `TRANSITION_REQUEST_TO_STAGING_CREATED`: A user + // requested a model version be transitioned to staging. * + // `TRANSITION_REQUEST_TO_PRODUCTION_CREATED`: A user requested a model version + // be transitioned to production. * `TRANSITION_REQUEST_TO_ARCHIVED_CREATED`: A + // user requested a model version be archived. + Events []RegistryWebhookEvent + // Creation time of the object, as a Unix timestamp in milliseconds. + CreationTimestamp *int64 + // Time of the object at last update, as a Unix timestamp in milliseconds. + LastUpdatedTimestamp *int64 + // User-specified description for the webhook. + Description *string + Status RegistryWebhookStatus + HttpUrlSpec *HttpUrlSpec + JobSpec *JobSpec + // Name of the model whose events would trigger this webhook. + ModelName *string +} + +// Details required to identify and reject a model version stage transition +// request.. +type RejectTransitionRequest struct { + // Name of the model. + Name *string + // Version of the model. + Version *string + // Target stage of the transition. Valid values are: * `None`: The initial stage + // of a model version. * `Staging`: Staging or pre-production stage. * + // `Production`: Production stage. * `Archived`: Archived stage. + Stage *string + // User-provided comment on the action. + Comment *string +} + +type RejectTransitionResponse struct { + // New activity generated as a result of this operation. + Activity *Activity +} + +type RenameRegisteredModelRequest struct { + // Registered model unique name identifier. + Name *string + // If provided, updates the name for this `registered_model`. + NewName *string +} + +type RenameRegisteredModelResponse struct { + RegisteredModel *RegisteredModel +} + +type SearchModelVersionsRequest struct { + // String filter condition, like "name='my-model-name'". Must be a single + // boolean condition, with string values wrapped in single quotes. + Filter *string + // Maximum number of models desired. Max threshold is 10K. + MaxResults *int64 + // List of columns to be ordered by including model name, version, stage with an + // optional "DESC" or "ASC" annotation, where "ASC" is the default. Tiebreaks + // are done by latest stage transition timestamp, followed by name ASC, followed + // by version DESC. + OrderBy []string + // Pagination token to go to next page based on previous search query. + PageToken *string +} + +type SearchModelVersionsResponse struct { + // Models that match the search criteria + ModelVersions []ModelVersion + // Pagination token to request next page of models for the same search query. + NextPageToken *string +} + +type SearchRegisteredModelsRequest struct { + // String filter condition, like "name LIKE 'my-model-name'". Interpreted in the + // backend automatically as "name LIKE '%my-model-name%'". Single boolean + // condition, with string values wrapped in single quotes. + Filter *string + // Maximum number of models desired. Default is 100. Max threshold is 1000. + MaxResults *int64 + // List of columns for ordering search results, which can include model name and + // last updated timestamp with an optional "DESC" or "ASC" annotation, where + // "ASC" is the default. Tiebreaks are done by model name ASC. + OrderBy []string + // Pagination token to go to the next page based on a previous search query. + PageToken *string +} + +type SearchRegisteredModelsResponse struct { + // Registered Models that match the search criteria. + RegisteredModels []RegisteredModel + // Pagination token to request the next page of models. + NextPageToken *string +} + +type SetModelVersionTagRequest struct { + // Unique name of the model. + Name *string + // Model version number. + Version *string + // Name of the tag. Maximum size depends on storage backend. If a tag with this + // name already exists, its preexisting value will be replaced by the specified + // `value`. All storage backends are guaranteed to support key values up to 250 + // bytes in size. + Key *string + // String value of the tag being logged. Maximum size depends on storage + // backend. All storage backends are guaranteed to support key values up to 5000 + // bytes in size. + Value *string +} + +type SetModelVersionTagResponse struct { +} + +type SetRegisteredModelTagRequest struct { + // Unique name of the model. + Name *string + // Name of the tag. Maximum size depends on storage backend. If a tag with this + // name already exists, its preexisting value will be replaced by the specified + // `value`. All storage backends are guaranteed to support key values up to 250 + // bytes in size. + Key *string + // String value of the tag being logged. Maximum size depends on storage + // backend. All storage backends are guaranteed to support key values up to 5000 + // bytes in size. + Value *string +} + +type SetRegisteredModelTagResponse struct { +} + +// Details required to test a registry webhook.. +type TestRegistryWebhookRequest struct { + // Webhook ID + Id *string + // If `event` is specified, the test trigger uses the specified event. If + // `event` is not specified, the test trigger uses a randomly chosen event + // associated with the webhook. + Event RegistryWebhookEvent +} + +type TestRegistryWebhookResponse struct { + // Status code returned by the webhook URL + StatusCode *int + // Body of the response from the webhook URL + Body *string +} + +// Details required to transition a model version's stage.. +type TransitionModelVersionStageDatabricksRequest struct { + // Name of the model. + Name *string + // Version of the model. + Version *string + // Target stage of the transition. Valid values are: * `None`: The initial stage + // of a model version. * `Staging`: Staging or pre-production stage. * + // `Production`: Production stage. * `Archived`: Archived stage. + Stage *string + // Specifies whether to archive all current model versions in the target stage. + ArchiveExistingVersions *bool + // User-provided comment on the action. + Comment *string +} + +type TransitionModelVersionStageDatabricksResponse struct { + // Updated model version + ModelVersionDatabricks *ModelVersionDatabricks +} + +// For activities, this contains the activity recorded for the action. For +// comments, this contains the comment details. For transition requests, this +// contains the transition request details.. +type TransitionRequest struct { + // Creation time of the object, as a Unix timestamp in milliseconds. + CreationTimestamp *int64 + // The username of the user that created the object. + UserId *string + ActivityType ActivityType + // User-provided comment associated with the activity, comment, or transition + // request. + Comment *string + // Time of the object at last update, as a Unix timestamp in milliseconds. + LastUpdatedTimestamp *int64 + // Source stage of the transition (if the activity is stage transition related). + // Valid values are: * `None`: The initial stage of a model version. * + // `Staging`: Staging or pre-production stage. * `Production`: Production stage. + // * `Archived`: Archived stage. + FromStage *string + // Target stage of the transition (if the activity is stage transition related). + // Valid values are: * `None`: The initial stage of a model version. * + // `Staging`: Staging or pre-production stage. * `Production`: Production stage. + // * `Archived`: Archived stage. + ToStage *string + // Comment made by system, for example explaining an activity of type + // `SYSTEM_TRANSITION`. It usually describes a side effect, such as a version + // being archived as part of another version's stage transition, and may not be + // returned for some activity types. + SystemComment *string + // Array of actions on the activity allowed for the current viewer. + AvailableActions []ActivityAction + // Unique identifier for the object. + Id *string +} + +// Details required to edit a comment on a model version.. +type UpdateCommentRequest struct { + // Unique identifier of an activity + Id *string + // User-provided comment on the action. + Comment *string +} + +type UpdateCommentResponse struct { + // Updated comment object + Comment *CommentObject +} + +type UpdateModelVersionRequest struct { + // Name of the registered model + Name *string + // Model version number + Version *string + // If provided, updates the description for this `registered_model`. + Description *string +} + +type UpdateModelVersionResponse struct { + // Return new version number generated for this model in registry. + ModelVersion *ModelVersion +} + +type UpdateRegisteredModelRequest struct { + // Registered model unique name identifier. + Name *string + // If provided, updates the description for this `registered_model`. + Description *string +} + +type UpdateRegisteredModelResponse struct { + RegisteredModel *RegisteredModel +} + +// Details required to update a registry webhook. Only the fields that need to +// be updated should be specified, and both `http_url_spec` and `job_spec` +// should not be specified in the same request.. +type UpdateRegistryWebhookRequest struct { + // Webhook ID + Id *string + // Events that can trigger a registry webhook: * `MODEL_VERSION_CREATED`: A new + // model version was created for the associated model. * + // `MODEL_VERSION_TRANSITIONED_STAGE`: A model version’s stage was changed. * + // `TRANSITION_REQUEST_CREATED`: A user requested a model version’s stage be + // transitioned. * `COMMENT_CREATED`: A user wrote a comment on a registered + // model. * `REGISTERED_MODEL_CREATED`: A new registered model was created. This + // event type can only be specified for a registry-wide webhook, which can be + // created by not specifying a model name in the create request. * + // `MODEL_VERSION_TAG_SET`: A user set a tag on the model version. * + // `MODEL_VERSION_TRANSITIONED_TO_STAGING`: A model version was transitioned to + // staging. * `MODEL_VERSION_TRANSITIONED_TO_PRODUCTION`: A model version was + // transitioned to production. * `MODEL_VERSION_TRANSITIONED_TO_ARCHIVED`: A + // model version was archived. * `TRANSITION_REQUEST_TO_STAGING_CREATED`: A user + // requested a model version be transitioned to staging. * + // `TRANSITION_REQUEST_TO_PRODUCTION_CREATED`: A user requested a model version + // be transitioned to production. * `TRANSITION_REQUEST_TO_ARCHIVED_CREATED`: A + // user requested a model version be archived. + Events []RegistryWebhookEvent + // User-specified description for the webhook. + Description *string + Status RegistryWebhookStatus + HttpUrlSpec *HttpUrlSpec + JobSpec *JobSpec +} + +type UpdateRegistryWebhookResponse struct { + Webhook *RegistryWebhook +} diff --git a/modelregistry/v1/wire.go b/modelregistry/v1/wire.go new file mode 100755 index 0000000..fb306ce --- /dev/null +++ b/modelregistry/v1/wire.go @@ -0,0 +1,1445 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelregistry + +import ( + "fmt" +) + +type activityWire struct { + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + UserId *string `json:"user_id,omitempty"` + ActivityType ActivityType `json:"activity_type,omitempty"` + Comment *string `json:"comment,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + FromStage *string `json:"from_stage,omitempty"` + ToStage *string `json:"to_stage,omitempty"` + SystemComment *string `json:"system_comment,omitempty"` + AvailableActions []ActivityAction `json:"available_actions,omitempty"` + Id *string `json:"id,omitempty"` +} + +func activityFromWire(w *activityWire) (*Activity, error) { + if w == nil { + return nil, nil + } + return &Activity{ + CreationTimestamp: w.CreationTimestamp, + UserId: w.UserId, + ActivityType: w.ActivityType, + Comment: w.Comment, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + FromStage: w.FromStage, + ToStage: w.ToStage, + SystemComment: w.SystemComment, + AvailableActions: w.AvailableActions, + Id: w.Id, + }, nil +} + +type approveTransitionRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + Stage *string `json:"stage,omitempty"` + ArchiveExistingVersions *bool `json:"archive_existing_versions,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func approveTransitionRequestToWire(v *ApproveTransitionRequest) (*approveTransitionRequestWire, error) { + if v == nil { + return nil, nil + } + return &approveTransitionRequestWire{ + Name: v.Name, + Version: v.Version, + Stage: v.Stage, + ArchiveExistingVersions: v.ArchiveExistingVersions, + Comment: v.Comment, + }, nil +} + +type approveTransitionResponseWire struct { + Activity *activityWire `json:"activity,omitempty"` +} + +func approveTransitionResponseFromWire(w *approveTransitionResponseWire) (*ApproveTransitionResponse, error) { + if w == nil { + return nil, nil + } + activityPublicValue, err := activityFromWire(w.Activity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ApproveTransitionResponse.Activity", err) + } + return &ApproveTransitionResponse{ + Activity: activityPublicValue, + }, nil +} + +type commentObjectWire struct { + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + UserId *string `json:"user_id,omitempty"` + ActivityType ActivityType `json:"activity_type,omitempty"` + Comment *string `json:"comment,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + FromStage *string `json:"from_stage,omitempty"` + ToStage *string `json:"to_stage,omitempty"` + SystemComment *string `json:"system_comment,omitempty"` + AvailableActions []ActivityAction `json:"available_actions,omitempty"` + Id *string `json:"id,omitempty"` +} + +func commentObjectFromWire(w *commentObjectWire) (*CommentObject, error) { + if w == nil { + return nil, nil + } + return &CommentObject{ + CreationTimestamp: w.CreationTimestamp, + UserId: w.UserId, + ActivityType: w.ActivityType, + Comment: w.Comment, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + FromStage: w.FromStage, + ToStage: w.ToStage, + SystemComment: w.SystemComment, + AvailableActions: w.AvailableActions, + Id: w.Id, + }, nil +} + +type createCommentRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func createCommentRequestToWire(v *CreateCommentRequest) (*createCommentRequestWire, error) { + if v == nil { + return nil, nil + } + return &createCommentRequestWire{ + Name: v.Name, + Version: v.Version, + Comment: v.Comment, + }, nil +} + +type createCommentResponseWire struct { + Comment *commentObjectWire `json:"comment,omitempty"` +} + +func createCommentResponseFromWire(w *createCommentResponseWire) (*CreateCommentResponse, error) { + if w == nil { + return nil, nil + } + commentPublicValue, err := commentObjectFromWire(w.Comment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCommentResponse.Comment", err) + } + return &CreateCommentResponse{ + Comment: commentPublicValue, + }, nil +} + +type createModelVersionRequestWire struct { + Name *string `json:"name,omitempty"` + Source *string `json:"source,omitempty"` + RunId *string `json:"run_id,omitempty"` + Tags []modelVersionTagWire `json:"tags,omitempty"` + RunLink *string `json:"run_link,omitempty"` + Description *string `json:"description,omitempty"` +} + +func createModelVersionRequestToWire(v *CreateModelVersionRequest) (*createModelVersionRequestWire, error) { + if v == nil { + return nil, nil + } + tagsWireValue, err := convertSlice(v.Tags, modelVersionTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateModelVersionRequest.Tags", err) + } + return &createModelVersionRequestWire{ + Name: v.Name, + Source: v.Source, + RunId: v.RunId, + Tags: tagsWireValue, + RunLink: v.RunLink, + Description: v.Description, + }, nil +} + +type createModelVersionResponseWire struct { + ModelVersion *modelVersionWire `json:"model_version,omitempty"` +} + +func createModelVersionResponseFromWire(w *createModelVersionResponseWire) (*CreateModelVersionResponse, error) { + if w == nil { + return nil, nil + } + modelVersionPublicValue, err := modelVersionFromWire(w.ModelVersion) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateModelVersionResponse.ModelVersion", err) + } + return &CreateModelVersionResponse{ + ModelVersion: modelVersionPublicValue, + }, nil +} + +type createRegisteredModelRequestWire struct { + Name *string `json:"name,omitempty"` + Tags []registeredModelTagWire `json:"tags,omitempty"` + Description *string `json:"description,omitempty"` +} + +func createRegisteredModelRequestToWire(v *CreateRegisteredModelRequest) (*createRegisteredModelRequestWire, error) { + if v == nil { + return nil, nil + } + tagsWireValue, err := convertSlice(v.Tags, registeredModelTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRegisteredModelRequest.Tags", err) + } + return &createRegisteredModelRequestWire{ + Name: v.Name, + Tags: tagsWireValue, + Description: v.Description, + }, nil +} + +type createRegisteredModelResponseWire struct { + RegisteredModel *registeredModelWire `json:"registered_model,omitempty"` +} + +func createRegisteredModelResponseFromWire(w *createRegisteredModelResponseWire) (*CreateRegisteredModelResponse, error) { + if w == nil { + return nil, nil + } + registeredModelPublicValue, err := registeredModelFromWire(w.RegisteredModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRegisteredModelResponse.RegisteredModel", err) + } + return &CreateRegisteredModelResponse{ + RegisteredModel: registeredModelPublicValue, + }, nil +} + +type createRegistryWebhookRequestWire struct { + ModelName *string `json:"model_name,omitempty"` + Events []RegistryWebhookEvent `json:"events,omitempty"` + Description *string `json:"description,omitempty"` + Status RegistryWebhookStatus `json:"status,omitempty"` + HttpUrlSpec *httpUrlSpecWire `json:"http_url_spec,omitempty"` + JobSpec *jobSpecWire `json:"job_spec,omitempty"` +} + +func createRegistryWebhookRequestToWire(v *CreateRegistryWebhookRequest) (*createRegistryWebhookRequestWire, error) { + if v == nil { + return nil, nil + } + httpUrlSpecWireValue, err := httpUrlSpecToWire(v.HttpUrlSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRegistryWebhookRequest.HttpUrlSpec", err) + } + jobSpecWireValue, err := jobSpecToWire(v.JobSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRegistryWebhookRequest.JobSpec", err) + } + return &createRegistryWebhookRequestWire{ + ModelName: v.ModelName, + Events: v.Events, + Description: v.Description, + Status: v.Status, + HttpUrlSpec: httpUrlSpecWireValue, + JobSpec: jobSpecWireValue, + }, nil +} + +type createRegistryWebhookResponseWire struct { + Webhook *registryWebhookWire `json:"webhook,omitempty"` +} + +func createRegistryWebhookResponseFromWire(w *createRegistryWebhookResponseWire) (*CreateRegistryWebhookResponse, error) { + if w == nil { + return nil, nil + } + webhookPublicValue, err := registryWebhookFromWire(w.Webhook) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRegistryWebhookResponse.Webhook", err) + } + return &CreateRegistryWebhookResponse{ + Webhook: webhookPublicValue, + }, nil +} + +type createTransitionRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + Stage *string `json:"stage,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func createTransitionRequestToWire(v *CreateTransitionRequest) (*createTransitionRequestWire, error) { + if v == nil { + return nil, nil + } + return &createTransitionRequestWire{ + Name: v.Name, + Version: v.Version, + Stage: v.Stage, + Comment: v.Comment, + }, nil +} + +type createTransitionResponseWire struct { + Request *transitionRequestWire `json:"request,omitempty"` +} + +func createTransitionResponseFromWire(w *createTransitionResponseWire) (*CreateTransitionResponse, error) { + if w == nil { + return nil, nil + } + requestPublicValue, err := transitionRequestFromWire(w.Request) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTransitionResponse.Request", err) + } + return &CreateTransitionResponse{ + Request: requestPublicValue, + }, nil +} + +type deleteCommentRequestWire struct { + Id *string `json:"id,omitempty"` +} + +func deleteCommentRequestToWire(v *DeleteCommentRequest) (*deleteCommentRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteCommentRequestWire{ + Id: v.Id, + }, nil +} + +type deleteModelVersionRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` +} + +func deleteModelVersionRequestToWire(v *DeleteModelVersionRequest) (*deleteModelVersionRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteModelVersionRequestWire{ + Name: v.Name, + Version: v.Version, + }, nil +} + +type deleteModelVersionTagRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + Key *string `json:"key,omitempty"` +} + +func deleteModelVersionTagRequestToWire(v *DeleteModelVersionTagRequest) (*deleteModelVersionTagRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteModelVersionTagRequestWire{ + Name: v.Name, + Version: v.Version, + Key: v.Key, + }, nil +} + +type deleteRegisteredModelRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func deleteRegisteredModelRequestToWire(v *DeleteRegisteredModelRequest) (*deleteRegisteredModelRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteRegisteredModelRequestWire{ + Name: v.Name, + }, nil +} + +type deleteRegisteredModelTagRequestWire struct { + Name *string `json:"name,omitempty"` + Key *string `json:"key,omitempty"` +} + +func deleteRegisteredModelTagRequestToWire(v *DeleteRegisteredModelTagRequest) (*deleteRegisteredModelTagRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteRegisteredModelTagRequestWire{ + Name: v.Name, + Key: v.Key, + }, nil +} + +type deleteRegistryWebhookRequestWire struct { + Id *string `json:"id,omitempty"` +} + +func deleteRegistryWebhookRequestToWire(v *DeleteRegistryWebhookRequest) (*deleteRegistryWebhookRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteRegistryWebhookRequestWire{ + Id: v.Id, + }, nil +} + +type deleteTransitionRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + Stage *string `json:"stage,omitempty"` + Creator *string `json:"creator,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func deleteTransitionRequestToWire(v *DeleteTransitionRequest) (*deleteTransitionRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteTransitionRequestWire{ + Name: v.Name, + Version: v.Version, + Stage: v.Stage, + Creator: v.Creator, + Comment: v.Comment, + }, nil +} + +type deleteTransitionResponseWire struct { + Activity *activityWire `json:"activity,omitempty"` +} + +func deleteTransitionResponseFromWire(w *deleteTransitionResponseWire) (*DeleteTransitionResponse, error) { + if w == nil { + return nil, nil + } + activityPublicValue, err := activityFromWire(w.Activity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeleteTransitionResponse.Activity", err) + } + return &DeleteTransitionResponse{ + Activity: activityPublicValue, + }, nil +} + +type featureListWire struct { + Features []linkedFeatureWire `json:"features,omitempty"` +} + +func featureListFromWire(w *featureListWire) (*FeatureList, error) { + if w == nil { + return nil, nil + } + featuresPublicValue, err := convertSlice(w.Features, linkedFeatureFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FeatureList.Features", err) + } + return &FeatureList{ + Features: featuresPublicValue, + }, nil +} + +type getLatestVersionsResponseWire struct { + ModelVersions []modelVersionWire `json:"model_versions,omitempty"` +} + +func getLatestVersionsResponseFromWire(w *getLatestVersionsResponseWire) (*GetLatestVersionsResponse, error) { + if w == nil { + return nil, nil + } + modelVersionsPublicValue, err := convertSlice(w.ModelVersions, modelVersionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetLatestVersionsResponse.ModelVersions", err) + } + return &GetLatestVersionsResponse{ + ModelVersions: modelVersionsPublicValue, + }, nil +} + +type getModelVersionDownloadUriRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` +} + +func getModelVersionDownloadUriRequestToWire(v *GetModelVersionDownloadUriRequest) (*getModelVersionDownloadUriRequestWire, error) { + if v == nil { + return nil, nil + } + return &getModelVersionDownloadUriRequestWire{ + Name: v.Name, + Version: v.Version, + }, nil +} + +type getModelVersionDownloadUriResponseWire struct { + ArtifactUri *string `json:"artifact_uri,omitempty"` +} + +func getModelVersionDownloadUriResponseFromWire(w *getModelVersionDownloadUriResponseWire) (*GetModelVersionDownloadUriResponse, error) { + if w == nil { + return nil, nil + } + return &GetModelVersionDownloadUriResponse{ + ArtifactUri: w.ArtifactUri, + }, nil +} + +type getModelVersionRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` +} + +func getModelVersionRequestToWire(v *GetModelVersionRequest) (*getModelVersionRequestWire, error) { + if v == nil { + return nil, nil + } + return &getModelVersionRequestWire{ + Name: v.Name, + Version: v.Version, + }, nil +} + +type getModelVersionResponseWire struct { + ModelVersion *modelVersionWire `json:"model_version,omitempty"` +} + +func getModelVersionResponseFromWire(w *getModelVersionResponseWire) (*GetModelVersionResponse, error) { + if w == nil { + return nil, nil + } + modelVersionPublicValue, err := modelVersionFromWire(w.ModelVersion) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetModelVersionResponse.ModelVersion", err) + } + return &GetModelVersionResponse{ + ModelVersion: modelVersionPublicValue, + }, nil +} + +type getRegisteredModelDatabricksRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func getRegisteredModelDatabricksRequestToWire(v *GetRegisteredModelDatabricksRequest) (*getRegisteredModelDatabricksRequestWire, error) { + if v == nil { + return nil, nil + } + return &getRegisteredModelDatabricksRequestWire{ + Name: v.Name, + }, nil +} + +type getRegisteredModelDatabricksResponseWire struct { + RegisteredModelDatabricks *registeredModelDatabricksWire `json:"registered_model_databricks,omitempty"` +} + +func getRegisteredModelDatabricksResponseFromWire(w *getRegisteredModelDatabricksResponseWire) (*GetRegisteredModelDatabricksResponse, error) { + if w == nil { + return nil, nil + } + registeredModelDatabricksPublicValue, err := registeredModelDatabricksFromWire(w.RegisteredModelDatabricks) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRegisteredModelDatabricksResponse.RegisteredModelDatabricks", err) + } + return &GetRegisteredModelDatabricksResponse{ + RegisteredModelDatabricks: registeredModelDatabricksPublicValue, + }, nil +} + +type httpUrlSpecWire struct { + Url *string `json:"url,omitempty"` + EnableSslVerification *bool `json:"enable_ssl_verification,omitempty"` + Secret *string `json:"secret,omitempty"` + Authorization *string `json:"authorization,omitempty"` +} + +func httpUrlSpecToWire(v *HttpUrlSpec) (*httpUrlSpecWire, error) { + if v == nil { + return nil, nil + } + return &httpUrlSpecWire{ + Url: v.Url, + EnableSslVerification: v.EnableSslVerification, + Secret: v.Secret, + Authorization: v.Authorization, + }, nil +} + +func httpUrlSpecFromWire(w *httpUrlSpecWire) (*HttpUrlSpec, error) { + if w == nil { + return nil, nil + } + return &HttpUrlSpec{ + Url: w.Url, + EnableSslVerification: w.EnableSslVerification, + Secret: w.Secret, + Authorization: w.Authorization, + }, nil +} + +type jobSpecWire struct { + JobId *string `json:"job_id,omitempty"` + WorkspaceUrl *string `json:"workspace_url,omitempty"` + AccessToken *string `json:"access_token,omitempty"` +} + +func jobSpecToWire(v *JobSpec) (*jobSpecWire, error) { + if v == nil { + return nil, nil + } + return &jobSpecWire{ + JobId: v.JobId, + WorkspaceUrl: v.WorkspaceUrl, + AccessToken: v.AccessToken, + }, nil +} + +func jobSpecFromWire(w *jobSpecWire) (*JobSpec, error) { + if w == nil { + return nil, nil + } + return &JobSpec{ + JobId: w.JobId, + WorkspaceUrl: w.WorkspaceUrl, + AccessToken: w.AccessToken, + }, nil +} + +type linkedFeatureWire struct { + FeatureTableName *string `json:"feature_table_name,omitempty"` + FeatureName *string `json:"feature_name,omitempty"` + FeatureTableId *string `json:"feature_table_id,omitempty"` +} + +func linkedFeatureFromWire(w *linkedFeatureWire) (*LinkedFeature, error) { + if w == nil { + return nil, nil + } + return &LinkedFeature{ + FeatureTableName: w.FeatureTableName, + FeatureName: w.FeatureName, + FeatureTableId: w.FeatureTableId, + }, nil +} + +type listLatestVersionsRequestWire struct { + Name *string `json:"name,omitempty"` + Stages []string `json:"stages,omitempty"` +} + +func listLatestVersionsRequestToWire(v *ListLatestVersionsRequest) (*listLatestVersionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listLatestVersionsRequestWire{ + Name: v.Name, + Stages: v.Stages, + }, nil +} + +type listRegisteredModelsRequestWire struct { + MaxResults *int64 `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listRegisteredModelsRequestToWire(v *ListRegisteredModelsRequest) (*listRegisteredModelsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listRegisteredModelsRequestWire{ + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listRegisteredModelsResponseWire struct { + RegisteredModels []registeredModelWire `json:"registered_models,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listRegisteredModelsResponseFromWire(w *listRegisteredModelsResponseWire) (*ListRegisteredModelsResponse, error) { + if w == nil { + return nil, nil + } + registeredModelsPublicValue, err := convertSlice(w.RegisteredModels, registeredModelFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListRegisteredModelsResponse.RegisteredModels", err) + } + return &ListRegisteredModelsResponse{ + RegisteredModels: registeredModelsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listRegistryWebhooksRequestWire struct { + ModelName *string `json:"model_name,omitempty"` + Events []RegistryWebhookEvent `json:"events,omitempty"` + PageToken *string `json:"page_token,omitempty"` + MaxResults *int64 `json:"max_results,omitempty"` +} + +func listRegistryWebhooksRequestToWire(v *ListRegistryWebhooksRequest) (*listRegistryWebhooksRequestWire, error) { + if v == nil { + return nil, nil + } + return &listRegistryWebhooksRequestWire{ + ModelName: v.ModelName, + Events: v.Events, + PageToken: v.PageToken, + MaxResults: v.MaxResults, + }, nil +} + +type listRegistryWebhooksResponseWire struct { + Webhooks []registryWebhookWire `json:"webhooks,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listRegistryWebhooksResponseFromWire(w *listRegistryWebhooksResponseWire) (*ListRegistryWebhooksResponse, error) { + if w == nil { + return nil, nil + } + webhooksPublicValue, err := convertSlice(w.Webhooks, registryWebhookFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListRegistryWebhooksResponse.Webhooks", err) + } + return &ListRegistryWebhooksResponse{ + Webhooks: webhooksPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listTransitionRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` +} + +func listTransitionRequestToWire(v *ListTransitionRequest) (*listTransitionRequestWire, error) { + if v == nil { + return nil, nil + } + return &listTransitionRequestWire{ + Name: v.Name, + Version: v.Version, + }, nil +} + +type listTransitionResponseWire struct { + Requests []activityWire `json:"requests,omitempty"` +} + +func listTransitionResponseFromWire(w *listTransitionResponseWire) (*ListTransitionResponse, error) { + if w == nil { + return nil, nil + } + requestsPublicValue, err := convertSlice(w.Requests, activityFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListTransitionResponse.Requests", err) + } + return &ListTransitionResponse{ + Requests: requestsPublicValue, + }, nil +} + +type modelVersionWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + UserId *string `json:"user_id,omitempty"` + CurrentStage *string `json:"current_stage,omitempty"` + Description *string `json:"description,omitempty"` + Source *string `json:"source,omitempty"` + RunId *string `json:"run_id,omitempty"` + Status ModelVersionStatus `json:"status,omitempty"` + StatusMessage *string `json:"status_message,omitempty"` + Tags []modelVersionTagWire `json:"tags,omitempty"` + RunLink *string `json:"run_link,omitempty"` +} + +func modelVersionFromWire(w *modelVersionWire) (*ModelVersion, error) { + if w == nil { + return nil, nil + } + tagsPublicValue, err := convertSlice(w.Tags, modelVersionTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelVersion.Tags", err) + } + return &ModelVersion{ + Name: w.Name, + Version: w.Version, + CreationTimestamp: w.CreationTimestamp, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + UserId: w.UserId, + CurrentStage: w.CurrentStage, + Description: w.Description, + Source: w.Source, + RunId: w.RunId, + Status: w.Status, + StatusMessage: w.StatusMessage, + Tags: tagsPublicValue, + RunLink: w.RunLink, + }, nil +} + +type modelVersionDatabricksWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + UserId *string `json:"user_id,omitempty"` + CurrentStage *string `json:"current_stage,omitempty"` + Description *string `json:"description,omitempty"` + Source *string `json:"source,omitempty"` + RunId *string `json:"run_id,omitempty"` + Status ModelVersionStatus `json:"status,omitempty"` + StatusMessage *string `json:"status_message,omitempty"` + OpenRequests []activityWire `json:"open_requests,omitempty"` + PermissionLevel PermissionLevel `json:"permission_level,omitempty"` + Tags []modelVersionTagWire `json:"tags,omitempty"` + RunLink *string `json:"run_link,omitempty"` + EmailSubscriptionStatus RegistryEmailSubscriptionType `json:"email_subscription_status,omitempty"` + FeatureList *featureListWire `json:"feature_list,omitempty"` +} + +func modelVersionDatabricksFromWire(w *modelVersionDatabricksWire) (*ModelVersionDatabricks, error) { + if w == nil { + return nil, nil + } + openRequestsPublicValue, err := convertSlice(w.OpenRequests, activityFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelVersionDatabricks.OpenRequests", err) + } + tagsPublicValue, err := convertSlice(w.Tags, modelVersionTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelVersionDatabricks.Tags", err) + } + featureListPublicValue, err := featureListFromWire(w.FeatureList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelVersionDatabricks.FeatureList", err) + } + return &ModelVersionDatabricks{ + Name: w.Name, + Version: w.Version, + CreationTimestamp: w.CreationTimestamp, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + UserId: w.UserId, + CurrentStage: w.CurrentStage, + Description: w.Description, + Source: w.Source, + RunId: w.RunId, + Status: w.Status, + StatusMessage: w.StatusMessage, + OpenRequests: openRequestsPublicValue, + PermissionLevel: w.PermissionLevel, + Tags: tagsPublicValue, + RunLink: w.RunLink, + EmailSubscriptionStatus: w.EmailSubscriptionStatus, + FeatureList: featureListPublicValue, + }, nil +} + +type modelVersionTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func modelVersionTagToWire(v *ModelVersionTag) (*modelVersionTagWire, error) { + if v == nil { + return nil, nil + } + return &modelVersionTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func modelVersionTagFromWire(w *modelVersionTagWire) (*ModelVersionTag, error) { + if w == nil { + return nil, nil + } + return &ModelVersionTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type registeredModelWire struct { + Name *string `json:"name,omitempty"` + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + UserId *string `json:"user_id,omitempty"` + Description *string `json:"description,omitempty"` + LatestVersions []modelVersionWire `json:"latest_versions,omitempty"` + Tags []registeredModelTagWire `json:"tags,omitempty"` +} + +func registeredModelFromWire(w *registeredModelWire) (*RegisteredModel, error) { + if w == nil { + return nil, nil + } + latestVersionsPublicValue, err := convertSlice(w.LatestVersions, modelVersionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RegisteredModel.LatestVersions", err) + } + tagsPublicValue, err := convertSlice(w.Tags, registeredModelTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RegisteredModel.Tags", err) + } + return &RegisteredModel{ + Name: w.Name, + CreationTimestamp: w.CreationTimestamp, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + UserId: w.UserId, + Description: w.Description, + LatestVersions: latestVersionsPublicValue, + Tags: tagsPublicValue, + }, nil +} + +type registeredModelDatabricksWire struct { + Name *string `json:"name,omitempty"` + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + UserId *string `json:"user_id,omitempty"` + Description *string `json:"description,omitempty"` + LatestVersions []modelVersionWire `json:"latest_versions,omitempty"` + Id *string `json:"id,omitempty"` + PermissionLevel PermissionLevel `json:"permission_level,omitempty"` + Tags []registeredModelTagWire `json:"tags,omitempty"` +} + +func registeredModelDatabricksFromWire(w *registeredModelDatabricksWire) (*RegisteredModelDatabricks, error) { + if w == nil { + return nil, nil + } + latestVersionsPublicValue, err := convertSlice(w.LatestVersions, modelVersionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RegisteredModelDatabricks.LatestVersions", err) + } + tagsPublicValue, err := convertSlice(w.Tags, registeredModelTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RegisteredModelDatabricks.Tags", err) + } + return &RegisteredModelDatabricks{ + Name: w.Name, + CreationTimestamp: w.CreationTimestamp, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + UserId: w.UserId, + Description: w.Description, + LatestVersions: latestVersionsPublicValue, + Id: w.Id, + PermissionLevel: w.PermissionLevel, + Tags: tagsPublicValue, + }, nil +} + +type registeredModelTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func registeredModelTagToWire(v *RegisteredModelTag) (*registeredModelTagWire, error) { + if v == nil { + return nil, nil + } + return ®isteredModelTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func registeredModelTagFromWire(w *registeredModelTagWire) (*RegisteredModelTag, error) { + if w == nil { + return nil, nil + } + return &RegisteredModelTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type registryWebhookWire struct { + Id *string `json:"id,omitempty"` + Events []RegistryWebhookEvent `json:"events,omitempty"` + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + Description *string `json:"description,omitempty"` + Status RegistryWebhookStatus `json:"status,omitempty"` + HttpUrlSpec *httpUrlSpecWire `json:"http_url_spec,omitempty"` + JobSpec *jobSpecWire `json:"job_spec,omitempty"` + ModelName *string `json:"model_name,omitempty"` +} + +func registryWebhookFromWire(w *registryWebhookWire) (*RegistryWebhook, error) { + if w == nil { + return nil, nil + } + httpUrlSpecPublicValue, err := httpUrlSpecFromWire(w.HttpUrlSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RegistryWebhook.HttpUrlSpec", err) + } + jobSpecPublicValue, err := jobSpecFromWire(w.JobSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RegistryWebhook.JobSpec", err) + } + return &RegistryWebhook{ + Id: w.Id, + Events: w.Events, + CreationTimestamp: w.CreationTimestamp, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + Description: w.Description, + Status: w.Status, + HttpUrlSpec: httpUrlSpecPublicValue, + JobSpec: jobSpecPublicValue, + ModelName: w.ModelName, + }, nil +} + +type rejectTransitionRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + Stage *string `json:"stage,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func rejectTransitionRequestToWire(v *RejectTransitionRequest) (*rejectTransitionRequestWire, error) { + if v == nil { + return nil, nil + } + return &rejectTransitionRequestWire{ + Name: v.Name, + Version: v.Version, + Stage: v.Stage, + Comment: v.Comment, + }, nil +} + +type rejectTransitionResponseWire struct { + Activity *activityWire `json:"activity,omitempty"` +} + +func rejectTransitionResponseFromWire(w *rejectTransitionResponseWire) (*RejectTransitionResponse, error) { + if w == nil { + return nil, nil + } + activityPublicValue, err := activityFromWire(w.Activity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RejectTransitionResponse.Activity", err) + } + return &RejectTransitionResponse{ + Activity: activityPublicValue, + }, nil +} + +type renameRegisteredModelRequestWire struct { + Name *string `json:"name,omitempty"` + NewName *string `json:"new_name,omitempty"` +} + +func renameRegisteredModelRequestToWire(v *RenameRegisteredModelRequest) (*renameRegisteredModelRequestWire, error) { + if v == nil { + return nil, nil + } + return &renameRegisteredModelRequestWire{ + Name: v.Name, + NewName: v.NewName, + }, nil +} + +type renameRegisteredModelResponseWire struct { + RegisteredModel *registeredModelWire `json:"registered_model,omitempty"` +} + +func renameRegisteredModelResponseFromWire(w *renameRegisteredModelResponseWire) (*RenameRegisteredModelResponse, error) { + if w == nil { + return nil, nil + } + registeredModelPublicValue, err := registeredModelFromWire(w.RegisteredModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RenameRegisteredModelResponse.RegisteredModel", err) + } + return &RenameRegisteredModelResponse{ + RegisteredModel: registeredModelPublicValue, + }, nil +} + +type searchModelVersionsRequestWire struct { + Filter *string `json:"filter,omitempty"` + MaxResults *int64 `json:"max_results,omitempty"` + OrderBy []string `json:"order_by,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func searchModelVersionsRequestToWire(v *SearchModelVersionsRequest) (*searchModelVersionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &searchModelVersionsRequestWire{ + Filter: v.Filter, + MaxResults: v.MaxResults, + OrderBy: v.OrderBy, + PageToken: v.PageToken, + }, nil +} + +type searchModelVersionsResponseWire struct { + ModelVersions []modelVersionWire `json:"model_versions,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func searchModelVersionsResponseFromWire(w *searchModelVersionsResponseWire) (*SearchModelVersionsResponse, error) { + if w == nil { + return nil, nil + } + modelVersionsPublicValue, err := convertSlice(w.ModelVersions, modelVersionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SearchModelVersionsResponse.ModelVersions", err) + } + return &SearchModelVersionsResponse{ + ModelVersions: modelVersionsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type searchRegisteredModelsRequestWire struct { + Filter *string `json:"filter,omitempty"` + MaxResults *int64 `json:"max_results,omitempty"` + OrderBy []string `json:"order_by,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func searchRegisteredModelsRequestToWire(v *SearchRegisteredModelsRequest) (*searchRegisteredModelsRequestWire, error) { + if v == nil { + return nil, nil + } + return &searchRegisteredModelsRequestWire{ + Filter: v.Filter, + MaxResults: v.MaxResults, + OrderBy: v.OrderBy, + PageToken: v.PageToken, + }, nil +} + +type searchRegisteredModelsResponseWire struct { + RegisteredModels []registeredModelWire `json:"registered_models,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func searchRegisteredModelsResponseFromWire(w *searchRegisteredModelsResponseWire) (*SearchRegisteredModelsResponse, error) { + if w == nil { + return nil, nil + } + registeredModelsPublicValue, err := convertSlice(w.RegisteredModels, registeredModelFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SearchRegisteredModelsResponse.RegisteredModels", err) + } + return &SearchRegisteredModelsResponse{ + RegisteredModels: registeredModelsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type setModelVersionTagRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func setModelVersionTagRequestToWire(v *SetModelVersionTagRequest) (*setModelVersionTagRequestWire, error) { + if v == nil { + return nil, nil + } + return &setModelVersionTagRequestWire{ + Name: v.Name, + Version: v.Version, + Key: v.Key, + Value: v.Value, + }, nil +} + +type setRegisteredModelTagRequestWire struct { + Name *string `json:"name,omitempty"` + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func setRegisteredModelTagRequestToWire(v *SetRegisteredModelTagRequest) (*setRegisteredModelTagRequestWire, error) { + if v == nil { + return nil, nil + } + return &setRegisteredModelTagRequestWire{ + Name: v.Name, + Key: v.Key, + Value: v.Value, + }, nil +} + +type testRegistryWebhookRequestWire struct { + Id *string `json:"id,omitempty"` + Event RegistryWebhookEvent `json:"event,omitempty"` +} + +func testRegistryWebhookRequestToWire(v *TestRegistryWebhookRequest) (*testRegistryWebhookRequestWire, error) { + if v == nil { + return nil, nil + } + return &testRegistryWebhookRequestWire{ + Id: v.Id, + Event: v.Event, + }, nil +} + +type testRegistryWebhookResponseWire struct { + StatusCode *int `json:"status_code,omitempty"` + Body *string `json:"body,omitempty"` +} + +func testRegistryWebhookResponseFromWire(w *testRegistryWebhookResponseWire) (*TestRegistryWebhookResponse, error) { + if w == nil { + return nil, nil + } + return &TestRegistryWebhookResponse{ + StatusCode: w.StatusCode, + Body: w.Body, + }, nil +} + +type transitionModelVersionStageDatabricksRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + Stage *string `json:"stage,omitempty"` + ArchiveExistingVersions *bool `json:"archive_existing_versions,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func transitionModelVersionStageDatabricksRequestToWire(v *TransitionModelVersionStageDatabricksRequest) (*transitionModelVersionStageDatabricksRequestWire, error) { + if v == nil { + return nil, nil + } + return &transitionModelVersionStageDatabricksRequestWire{ + Name: v.Name, + Version: v.Version, + Stage: v.Stage, + ArchiveExistingVersions: v.ArchiveExistingVersions, + Comment: v.Comment, + }, nil +} + +type transitionModelVersionStageDatabricksResponseWire struct { + ModelVersionDatabricks *modelVersionDatabricksWire `json:"model_version_databricks,omitempty"` +} + +func transitionModelVersionStageDatabricksResponseFromWire(w *transitionModelVersionStageDatabricksResponseWire) (*TransitionModelVersionStageDatabricksResponse, error) { + if w == nil { + return nil, nil + } + modelVersionDatabricksPublicValue, err := modelVersionDatabricksFromWire(w.ModelVersionDatabricks) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TransitionModelVersionStageDatabricksResponse.ModelVersionDatabricks", err) + } + return &TransitionModelVersionStageDatabricksResponse{ + ModelVersionDatabricks: modelVersionDatabricksPublicValue, + }, nil +} + +type transitionRequestWire struct { + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + UserId *string `json:"user_id,omitempty"` + ActivityType ActivityType `json:"activity_type,omitempty"` + Comment *string `json:"comment,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + FromStage *string `json:"from_stage,omitempty"` + ToStage *string `json:"to_stage,omitempty"` + SystemComment *string `json:"system_comment,omitempty"` + AvailableActions []ActivityAction `json:"available_actions,omitempty"` + Id *string `json:"id,omitempty"` +} + +func transitionRequestFromWire(w *transitionRequestWire) (*TransitionRequest, error) { + if w == nil { + return nil, nil + } + return &TransitionRequest{ + CreationTimestamp: w.CreationTimestamp, + UserId: w.UserId, + ActivityType: w.ActivityType, + Comment: w.Comment, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + FromStage: w.FromStage, + ToStage: w.ToStage, + SystemComment: w.SystemComment, + AvailableActions: w.AvailableActions, + Id: w.Id, + }, nil +} + +type updateCommentRequestWire struct { + Id *string `json:"id,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func updateCommentRequestToWire(v *UpdateCommentRequest) (*updateCommentRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateCommentRequestWire{ + Id: v.Id, + Comment: v.Comment, + }, nil +} + +type updateCommentResponseWire struct { + Comment *commentObjectWire `json:"comment,omitempty"` +} + +func updateCommentResponseFromWire(w *updateCommentResponseWire) (*UpdateCommentResponse, error) { + if w == nil { + return nil, nil + } + commentPublicValue, err := commentObjectFromWire(w.Comment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCommentResponse.Comment", err) + } + return &UpdateCommentResponse{ + Comment: commentPublicValue, + }, nil +} + +type updateModelVersionRequestWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` + Description *string `json:"description,omitempty"` +} + +func updateModelVersionRequestToWire(v *UpdateModelVersionRequest) (*updateModelVersionRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateModelVersionRequestWire{ + Name: v.Name, + Version: v.Version, + Description: v.Description, + }, nil +} + +type updateModelVersionResponseWire struct { + ModelVersion *modelVersionWire `json:"model_version,omitempty"` +} + +func updateModelVersionResponseFromWire(w *updateModelVersionResponseWire) (*UpdateModelVersionResponse, error) { + if w == nil { + return nil, nil + } + modelVersionPublicValue, err := modelVersionFromWire(w.ModelVersion) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateModelVersionResponse.ModelVersion", err) + } + return &UpdateModelVersionResponse{ + ModelVersion: modelVersionPublicValue, + }, nil +} + +type updateRegisteredModelRequestWire struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` +} + +func updateRegisteredModelRequestToWire(v *UpdateRegisteredModelRequest) (*updateRegisteredModelRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateRegisteredModelRequestWire{ + Name: v.Name, + Description: v.Description, + }, nil +} + +type updateRegisteredModelResponseWire struct { + RegisteredModel *registeredModelWire `json:"registered_model,omitempty"` +} + +func updateRegisteredModelResponseFromWire(w *updateRegisteredModelResponseWire) (*UpdateRegisteredModelResponse, error) { + if w == nil { + return nil, nil + } + registeredModelPublicValue, err := registeredModelFromWire(w.RegisteredModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRegisteredModelResponse.RegisteredModel", err) + } + return &UpdateRegisteredModelResponse{ + RegisteredModel: registeredModelPublicValue, + }, nil +} + +type updateRegistryWebhookRequestWire struct { + Id *string `json:"id,omitempty"` + Events []RegistryWebhookEvent `json:"events,omitempty"` + Description *string `json:"description,omitempty"` + Status RegistryWebhookStatus `json:"status,omitempty"` + HttpUrlSpec *httpUrlSpecWire `json:"http_url_spec,omitempty"` + JobSpec *jobSpecWire `json:"job_spec,omitempty"` +} + +func updateRegistryWebhookRequestToWire(v *UpdateRegistryWebhookRequest) (*updateRegistryWebhookRequestWire, error) { + if v == nil { + return nil, nil + } + httpUrlSpecWireValue, err := httpUrlSpecToWire(v.HttpUrlSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRegistryWebhookRequest.HttpUrlSpec", err) + } + jobSpecWireValue, err := jobSpecToWire(v.JobSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRegistryWebhookRequest.JobSpec", err) + } + return &updateRegistryWebhookRequestWire{ + Id: v.Id, + Events: v.Events, + Description: v.Description, + Status: v.Status, + HttpUrlSpec: httpUrlSpecWireValue, + JobSpec: jobSpecWireValue, + }, nil +} + +type updateRegistryWebhookResponseWire struct { + Webhook *registryWebhookWire `json:"webhook,omitempty"` +} + +func updateRegistryWebhookResponseFromWire(w *updateRegistryWebhookResponseWire) (*UpdateRegistryWebhookResponse, error) { + if w == nil { + return nil, nil + } + webhookPublicValue, err := registryWebhookFromWire(w.Webhook) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRegistryWebhookResponse.Webhook", err) + } + return &UpdateRegistryWebhookResponse{ + Webhook: webhookPublicValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/modelserving/.package.json b/modelserving/.package.json new file mode 100644 index 0000000..05864eb --- /dev/null +++ b/modelserving/.package.json @@ -0,0 +1,3 @@ +{ + "package": "modelserving" +} diff --git a/modelserving/CHANGELOG.md b/modelserving/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/modelserving/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/modelserving/README.md b/modelserving/README.md new file mode 100644 index 0000000..6ebbaf6 --- /dev/null +++ b/modelserving/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/modelserving + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/modelserving@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/modelserving/v1" + +client, err := modelserving.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/modelserving/go.mod b/modelserving/go.mod new file mode 100644 index 0000000..fc5603d --- /dev/null +++ b/modelserving/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/modelserving + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/modelserving/internal/version.go b/modelserving/internal/version.go new file mode 100644 index 0000000..f9121e0 --- /dev/null +++ b/modelserving/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-modelserving" + +const Version = "0.0.1-dev.1" diff --git a/modelserving/v1/client.go b/modelserving/v1/client.go new file mode 100755 index 0000000..7abfc43 --- /dev/null +++ b/modelserving/v1/client.go @@ -0,0 +1,1524 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelserving + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/modelserving/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a new serving endpoint. +func (c *internalClient) createInferenceEndpointBase(ctx context.Context, req *CreateInferenceEndpointRequest, opts ...call.Option) (*InferenceEndpointDetailed, error) { + wireReq, err := createInferenceEndpointRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/serving-endpoints" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *InferenceEndpointDetailed + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp inferenceEndpointDetailedWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = inferenceEndpointDetailedFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a new serving endpoint. +func (c *internalClient) CreateInferenceEndpoint(ctx context.Context, req *CreateInferenceEndpointRequest, opts ...call.Option) (*CreateInferenceEndpointWaiter, error) { + if req.Name == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "Name") + } + capturedName := *req.Name + _, err := c.createInferenceEndpointBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &CreateInferenceEndpointWaiter{ + poll: c.GetInferenceEndpoint, + name: capturedName, + }, nil +} + +// CreateInferenceEndpointWaiter tracks the state of the operation started by CreateInferenceEndpoint. +type CreateInferenceEndpointWaiter struct { + poll func(context.Context, *GetInferenceEndpointRequest, ...call.Option) (*InferenceEndpointDetailed, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateInferenceEndpointWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetInferenceEndpointRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.ConfigUpdate + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case InferenceEndpointState_ConfigUpdateState_NotUpdating, InferenceEndpointState_ConfigUpdateState_UpdateFailed, InferenceEndpointState_ConfigUpdateState_UpdateCanceled: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateInferenceEndpointWaiter) Wait(ctx context.Context, opts ...lro.Option) (*InferenceEndpointDetailed, error) { + var result *InferenceEndpointDetailed + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetInferenceEndpointRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.ConfigUpdate + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case InferenceEndpointState_ConfigUpdateState_NotUpdating: + result = pollResp + return nil + case InferenceEndpointState_ConfigUpdateState_UpdateFailed, InferenceEndpointState_ConfigUpdateState_UpdateCanceled: + message := "(no message)" + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Create a new PT serving endpoint. +func (c *internalClient) createProvisionedThroughputInferenceEndpointBase(ctx context.Context, req *CreatePtEndpointRequest, opts ...call.Option) (*InferenceEndpointDetailed, error) { + wireReq, err := createPtEndpointRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/serving-endpoints/pt" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *InferenceEndpointDetailed + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp inferenceEndpointDetailedWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = inferenceEndpointDetailedFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a new PT serving endpoint. +func (c *internalClient) CreateProvisionedThroughputInferenceEndpoint(ctx context.Context, req *CreatePtEndpointRequest, opts ...call.Option) (*CreateProvisionedThroughputInferenceEndpointWaiter, error) { + if req.Name == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "Name") + } + capturedName := *req.Name + _, err := c.createProvisionedThroughputInferenceEndpointBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &CreateProvisionedThroughputInferenceEndpointWaiter{ + poll: c.GetInferenceEndpoint, + name: capturedName, + }, nil +} + +// CreateProvisionedThroughputInferenceEndpointWaiter tracks the state of the operation started by CreateProvisionedThroughputInferenceEndpoint. +type CreateProvisionedThroughputInferenceEndpointWaiter struct { + poll func(context.Context, *GetInferenceEndpointRequest, ...call.Option) (*InferenceEndpointDetailed, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateProvisionedThroughputInferenceEndpointWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetInferenceEndpointRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.ConfigUpdate + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case InferenceEndpointState_ConfigUpdateState_NotUpdating, InferenceEndpointState_ConfigUpdateState_UpdateFailed, InferenceEndpointState_ConfigUpdateState_UpdateCanceled: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateProvisionedThroughputInferenceEndpointWaiter) Wait(ctx context.Context, opts ...lro.Option) (*InferenceEndpointDetailed, error) { + var result *InferenceEndpointDetailed + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetInferenceEndpointRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.ConfigUpdate + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case InferenceEndpointState_ConfigUpdateState_NotUpdating: + result = pollResp + return nil + case InferenceEndpointState_ConfigUpdateState_UpdateFailed, InferenceEndpointState_ConfigUpdateState_UpdateCanceled: + message := "(no message)" + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Delete a serving endpoint. +func (c *internalClient) DeleteInferenceEndpoint(ctx context.Context, req *DeleteInferenceEndpointRequest, opts ...call.Option) (*DeleteInferenceEndpointResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteInferenceEndpointResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteInferenceEndpointResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves the metrics associated with the provided serving endpoint in either +// Prometheus or OpenMetrics exposition format. +func (c *internalClient) GetExportEndpointMetrics(ctx context.Context, req *GetExportEndpointMetricsRequest, opts ...call.Option) (*ExportMetricsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + headers.Set("Accept", "application/octet-stream") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/metrics") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExportMetricsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + httpResp, err := executeStreamingHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + resp = &ExportMetricsResponse{} + resp.Contents = httpResp.Body + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves the details for a single serving endpoint. +func (c *internalClient) GetInferenceEndpoint(ctx context.Context, req *GetInferenceEndpointRequest, opts ...call.Option) (*InferenceEndpointDetailed, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *InferenceEndpointDetailed + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp inferenceEndpointDetailedWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = inferenceEndpointDetailedFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get the query schema of the serving endpoint in OpenAPI format. The schema +// contains information for the supported paths, input and output format and +// datatypes. +func (c *internalClient) GetInferenceEndpointSchema(ctx context.Context, req *GetInferenceEndpointSchemaRequest, opts ...call.Option) (*GetOpenApiResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + headers.Set("Accept", "application/octet-stream") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/openapi") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetOpenApiResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + httpResp, err := executeStreamingHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + resp = &GetOpenApiResponse{} + resp.Contents = httpResp.Body + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves the build logs associated with the provided served model. +func (c *internalClient) GetServedModelBuildLogs(ctx context.Context, req *GetServedModelBuildLogsRequest, opts ...call.Option) (*GetServedModelBuildLogsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/served-models/") + pb.singleSegment(*req.ServedModelName) + pb.literal("/build-logs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetServedModelBuildLogsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getServedModelBuildLogsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getServedModelBuildLogsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves the service logs associated with the provided served model. +func (c *internalClient) GetServedModelLogs(ctx context.Context, req *GetServedModelLogsRequest, opts ...call.Option) (*GetServedModelLogsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/served-models/") + pb.singleSegment(*req.ServedModelName) + pb.literal("/logs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetServedModelLogsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getServedModelLogsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getServedModelLogsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get all serving endpoints. +func (c *internalClient) ListInferenceEndpoints(ctx context.Context, req *ListInferenceEndpointsRequest, opts ...call.Option) (*ListInferenceEndpointsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/serving-endpoints" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListInferenceEndpointsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listInferenceEndpointsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listInferenceEndpointsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Used to batch add and delete tags from a serving endpoint with a single API +// call. +func (c *internalClient) PatchInferenceEndpointTags(ctx context.Context, req *PatchInferenceEndpointTagsRequest, opts ...call.Option) (*PatchInferenceEndpointTagsResponse, error) { + wireReq, err := patchInferenceEndpointTagsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/tags") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PatchInferenceEndpointTagsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp patchInferenceEndpointTagsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = patchInferenceEndpointTagsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the telemetry configuration of a serving endpoint. +func (c *internalClient) PatchInferenceEndpointTelemetryConfig(ctx context.Context, req *PatchInferenceEndpointTelemetryConfigRequest, opts ...call.Option) (*InferenceEndpointDetailed, error) { + wireReq, err := patchInferenceEndpointTelemetryConfigRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/telemetry-config") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *InferenceEndpointDetailed + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp inferenceEndpointDetailedWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = inferenceEndpointDetailedFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Used to update the AI Gateway of a serving endpoint. NOTE: External model, +// provisioned throughput, and pay-per-token endpoints are fully supported; +// agent endpoints currently only support inference tables. +func (c *internalClient) PutInferenceEndpointAiGateway(ctx context.Context, req *PutInferenceEndpointAiGatewayRequest, opts ...call.Option) (*PutInferenceEndpointAiGatewayResponse, error) { + wireReq, err := putInferenceEndpointAiGatewayRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/ai-gateway") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PutInferenceEndpointAiGatewayResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp putInferenceEndpointAiGatewayResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = putInferenceEndpointAiGatewayResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates any combination of the serving endpoint's served entities, the +// compute configuration of those served entities, and the endpoint's traffic +// config. An endpoint that already has an update in progress can not be updated +// until the current update completes or fails. +func (c *internalClient) putInferenceEndpointConfigBase(ctx context.Context, req *PutInferenceEndpointConfigRequest, opts ...call.Option) (*InferenceEndpointDetailed, error) { + wireReq, err := putInferenceEndpointConfigRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/config") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *InferenceEndpointDetailed + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp inferenceEndpointDetailedWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = inferenceEndpointDetailedFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates any combination of the serving endpoint's served entities, the +// compute configuration of those served entities, and the endpoint's traffic +// config. An endpoint that already has an update in progress can not be updated +// until the current update completes or fails. +func (c *internalClient) PutInferenceEndpointConfig(ctx context.Context, req *PutInferenceEndpointConfigRequest, opts ...call.Option) (*PutInferenceEndpointConfigWaiter, error) { + if req.Name == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "Name") + } + capturedName := *req.Name + _, err := c.putInferenceEndpointConfigBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &PutInferenceEndpointConfigWaiter{ + poll: c.GetInferenceEndpoint, + name: capturedName, + }, nil +} + +// PutInferenceEndpointConfigWaiter tracks the state of the operation started by PutInferenceEndpointConfig. +type PutInferenceEndpointConfigWaiter struct { + poll func(context.Context, *GetInferenceEndpointRequest, ...call.Option) (*InferenceEndpointDetailed, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *PutInferenceEndpointConfigWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetInferenceEndpointRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.ConfigUpdate + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case InferenceEndpointState_ConfigUpdateState_NotUpdating, InferenceEndpointState_ConfigUpdateState_UpdateFailed, InferenceEndpointState_ConfigUpdateState_UpdateCanceled: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *PutInferenceEndpointConfigWaiter) Wait(ctx context.Context, opts ...lro.Option) (*InferenceEndpointDetailed, error) { + var result *InferenceEndpointDetailed + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetInferenceEndpointRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.ConfigUpdate + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case InferenceEndpointState_ConfigUpdateState_NotUpdating: + result = pollResp + return nil + case InferenceEndpointState_ConfigUpdateState_UpdateFailed, InferenceEndpointState_ConfigUpdateState_UpdateCanceled: + message := "(no message)" + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Deprecated: Please use AI Gateway to manage rate limits instead. +func (c *internalClient) PutInferenceEndpointRateLimits(ctx context.Context, req *PutInferenceEndpointRateLimitsRequest, opts ...call.Option) (*PutInferenceEndpointRateLimitsResponse, error) { + wireReq, err := putInferenceEndpointRateLimitsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/rate-limits") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PutInferenceEndpointRateLimitsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp putInferenceEndpointRateLimitsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = putInferenceEndpointRateLimitsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates any combination of the pt endpoint's served entities, the compute +// configuration of those served entities, and the endpoint's traffic config. +// Updates are instantaneous and endpoint should be updated instantly +func (c *internalClient) putProvisionedThroughputInferenceEndpointConfigBase(ctx context.Context, req *PutPtEndpointConfigRequest, opts ...call.Option) (*InferenceEndpointDetailed, error) { + wireReq, err := putPtEndpointConfigRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/pt/") + pb.singleSegment(*req.Name) + pb.literal("/config") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *InferenceEndpointDetailed + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp inferenceEndpointDetailedWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = inferenceEndpointDetailedFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates any combination of the pt endpoint's served entities, the compute +// configuration of those served entities, and the endpoint's traffic config. +// Updates are instantaneous and endpoint should be updated instantly +func (c *internalClient) PutProvisionedThroughputInferenceEndpointConfig(ctx context.Context, req *PutPtEndpointConfigRequest, opts ...call.Option) (*PutProvisionedThroughputInferenceEndpointConfigWaiter, error) { + if req.Name == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "Name") + } + capturedName := *req.Name + _, err := c.putProvisionedThroughputInferenceEndpointConfigBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &PutProvisionedThroughputInferenceEndpointConfigWaiter{ + poll: c.GetInferenceEndpoint, + name: capturedName, + }, nil +} + +// PutProvisionedThroughputInferenceEndpointConfigWaiter tracks the state of the operation started by PutProvisionedThroughputInferenceEndpointConfig. +type PutProvisionedThroughputInferenceEndpointConfigWaiter struct { + poll func(context.Context, *GetInferenceEndpointRequest, ...call.Option) (*InferenceEndpointDetailed, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *PutProvisionedThroughputInferenceEndpointConfigWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetInferenceEndpointRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.ConfigUpdate + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case InferenceEndpointState_ConfigUpdateState_NotUpdating, InferenceEndpointState_ConfigUpdateState_UpdateFailed, InferenceEndpointState_ConfigUpdateState_UpdateCanceled: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *PutProvisionedThroughputInferenceEndpointConfigWaiter) Wait(ctx context.Context, opts ...lro.Option) (*InferenceEndpointDetailed, error) { + var result *InferenceEndpointDetailed + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetInferenceEndpointRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.State == nil { + return fmt.Errorf("response field %q required for polling is missing", "State") + } + status := pollResp.State.ConfigUpdate + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case InferenceEndpointState_ConfigUpdateState_NotUpdating: + result = pollResp + return nil + case InferenceEndpointState_ConfigUpdateState_UpdateFailed, InferenceEndpointState_ConfigUpdateState_UpdateCanceled: + message := "(no message)" + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Updates the email and webhook notification settings for an endpoint. +func (c *internalClient) UpdateInferenceEndpointNotifications(ctx context.Context, req *UpdateInferenceEndpointNotificationsRequest, opts ...call.Option) (*UpdateInferenceEndpointNotificationsResponse, error) { + wireReq, err := updateInferenceEndpointNotificationsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/notifications") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateInferenceEndpointNotificationsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateInferenceEndpointNotificationsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateInferenceEndpointNotificationsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Make external services call using the credentials stored in UC Connection. +func (c *internalClient) HttpRequest(ctx context.Context, req *ExternalFunctionRequest, opts ...call.Option) (*ExternalFunctionResponse, error) { + wireReq, err := externalFunctionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + headers.Set("Accept", "application/octet-stream") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/external-function" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExternalFunctionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + httpResp, err := executeStreamingHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + resp = &ExternalFunctionResponse{} + resp.Contents = httpResp.Body + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/modelserving/v1/genhelper.go b/modelserving/v1/genhelper.go new file mode 100755 index 0000000..dc0d510 --- /dev/null +++ b/modelserving/v1/genhelper.go @@ -0,0 +1,235 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelserving + +import ( + "context" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} + +// executeStreamingHTTPCall executes an HTTP call whose response body is a raw +// byte stream. On success it returns the response with its body still open, so +// the caller can stream and close it. On a non-2xx status it reads and closes +// the body to build the API error; the returned response is nil in that case. +func executeStreamingHTTPCall(opts httpCallOptions) (*http.Response, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, err + } + if resp.StatusCode >= 400 { + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if apiErr := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); apiErr != nil { + return nil, apiErr + } + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, []byte("")}) + return resp, nil +} diff --git a/modelserving/v1/model.go b/modelserving/v1/model.go new file mode 100755 index 0000000..cd261fd --- /dev/null +++ b/modelserving/v1/model.go @@ -0,0 +1,1192 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelserving + +import ( + "io" +) + +type Behavior string + +const ( + Behavior_Unspecified Behavior = "" + Behavior_None Behavior = "NONE" + Behavior_Block Behavior = "BLOCK" + Behavior_Mask Behavior = "MASK" +) + +type ServedModelDeploymentState string + +const ( + ServedModelDeploymentState_Unspecified ServedModelDeploymentState = "" + ServedModelDeploymentState_DeploymentCreating ServedModelDeploymentState = "DEPLOYMENT_CREATING" + ServedModelDeploymentState_DeploymentRecovering ServedModelDeploymentState = "DEPLOYMENT_RECOVERING" + ServedModelDeploymentState_DeploymentReady ServedModelDeploymentState = "DEPLOYMENT_READY" + ServedModelDeploymentState_DeploymentFailed ServedModelDeploymentState = "DEPLOYMENT_FAILED" + ServedModelDeploymentState_DeploymentAborted ServedModelDeploymentState = "DEPLOYMENT_ABORTED" + ServedModelDeploymentState_DeploymentStopped ServedModelDeploymentState = "DEPLOYMENT_STOPPED" +) + +type ServingEndpointDetailedPermissionLevel string + +const ( + ServingEndpointDetailedPermissionLevel_Unspecified ServingEndpointDetailedPermissionLevel = "" + ServingEndpointDetailedPermissionLevel_CanManage ServingEndpointDetailedPermissionLevel = "CAN_MANAGE" + ServingEndpointDetailedPermissionLevel_CanQuery ServingEndpointDetailedPermissionLevel = "CAN_QUERY" + ServingEndpointDetailedPermissionLevel_CanView ServingEndpointDetailedPermissionLevel = "CAN_VIEW" +) + +// A telemetry signal that a serving endpoint can export to Unity Catalog. Use +// these values to select which signals the endpoint exports. +type TelemetryFeature string + +const ( + TelemetryFeature_Unspecified TelemetryFeature = "" + // Application logs emitted by the served model, exported to the logs table. + TelemetryFeature_TelemetryFeatureLogs TelemetryFeature = "TELEMETRY_FEATURE_LOGS" + // Request traces (spans), exported to the traces table. + TelemetryFeature_TelemetryFeatureTraces TelemetryFeature = "TELEMETRY_FEATURE_TRACES" + // Endpoint metrics, exported to the metrics table. + TelemetryFeature_TelemetryFeatureMetrics TelemetryFeature = "TELEMETRY_FEATURE_METRICS" + // Request and response payloads, logged to the endpoint's inference table. + TelemetryFeature_TelemetryFeatureInferenceTable TelemetryFeature = "TELEMETRY_FEATURE_INFERENCE_TABLE" +) + +type ExternalFunctionRequest_HttpMethod string + +const ( + ExternalFunctionRequest_HttpMethod_Unspecified ExternalFunctionRequest_HttpMethod = "" + ExternalFunctionRequest_HttpMethod_Get ExternalFunctionRequest_HttpMethod = "GET" + ExternalFunctionRequest_HttpMethod_Post ExternalFunctionRequest_HttpMethod = "POST" + ExternalFunctionRequest_HttpMethod_Put ExternalFunctionRequest_HttpMethod = "PUT" + ExternalFunctionRequest_HttpMethod_Delete ExternalFunctionRequest_HttpMethod = "DELETE" + ExternalFunctionRequest_HttpMethod_Patch ExternalFunctionRequest_HttpMethod = "PATCH" +) + +type InferenceEndpointState_ConfigUpdateState string + +const ( + InferenceEndpointState_ConfigUpdateState_Unspecified InferenceEndpointState_ConfigUpdateState = "" + InferenceEndpointState_ConfigUpdateState_NotUpdating InferenceEndpointState_ConfigUpdateState = "NOT_UPDATING" + InferenceEndpointState_ConfigUpdateState_InProgress InferenceEndpointState_ConfigUpdateState = "IN_PROGRESS" + InferenceEndpointState_ConfigUpdateState_UpdateFailed InferenceEndpointState_ConfigUpdateState = "UPDATE_FAILED" + InferenceEndpointState_ConfigUpdateState_UpdateCanceled InferenceEndpointState_ConfigUpdateState = "UPDATE_CANCELED" +) + +type InferenceEndpointState_ReadyState string + +const ( + InferenceEndpointState_ReadyState_Unspecified InferenceEndpointState_ReadyState = "" + InferenceEndpointState_ReadyState_Ready InferenceEndpointState_ReadyState = "READY" + InferenceEndpointState_ReadyState_NotReady InferenceEndpointState_ReadyState = "NOT_READY" +) + +type Ai21LabsConfig struct { + // The secret key reference for an AI21 Labs API key. If you prefer + // to paste your API key directly, see `ai21labs_api_key_plaintext`. You must + // provide an API key using one of the following fields: `ai21labs_api_key` or + // `ai21labs_api_key_plaintext`. + Ai21labsApiKey *string + // An AI21 Labs API key provided as a plaintext string. If you prefer to + // reference your key using Databricks Secrets, see `ai21labs_api_key`. You must + // provide an API key using one of the following fields: `ai21labs_api_key` or + // `ai21labs_api_key_plaintext`. + Ai21labsApiKeyPlaintext *string +} + +type AiGatewayConfig struct { + // Configuration to enable usage tracking using system tables. These tables + // allow you to monitor operational usage on endpoints and their associated + // costs. + UsageTrackingConfig *UsageTrackingConfig + // Configuration for payload logging using inference tables. Use these tables to + // monitor and audit data being sent to and received from model APIs and to + // improve model quality. + InferenceTableConfig *InferenceTableConfig + // Configuration for rate limits which can be set to limit endpoint traffic. + RateLimits []AiGatewayRateLimit + // Configuration for AI Guardrails to prevent unwanted data and unsafe data in + // requests and responses. + Guardrails *AiGuardrails + // Configuration for traffic fallback which auto fallbacks to other served + // entities if the request to a served entity fails with certain error codes, to + // increase availability. + FallbackConfig *FallbackConfig +} + +type AiGatewayRateLimit struct { + // Used to specify how many calls are allowed for a key within the + // renewal_period. + Calls *int64 + // Key field for a rate limit. Currently, 'user', 'user_group, + // 'service_principal', and 'endpoint' are supported, with 'endpoint' being the + // default if not specified. + Key *string + // Renewal period field for a rate limit. Currently, only 'minute' is supported. + RenewalPeriod *string + // Principal field for a user, user group, or service principal to apply rate + // limiting to. Accepts a user email, group name, or service principal + // application ID. + Principal *string + // Used to specify how many tokens are allowed for a key within the + // renewal_period. + Tokens *int64 +} + +type AiGuardrailParameters struct { + // Indicates whether the safety filter is enabled. + Safety *bool + // Configuration for guardrail PII filter. + Pii *PiiSettings + // The list of allowed topics. Given a chat request, this guardrail flags the + // request if its topic is not in the allowed topics. + ValidTopics []string + // List of invalid keywords. AI guardrail uses keyword or string matching to + // decide if the keyword exists in the request or response content. + InvalidKeywords []string +} + +type AiGuardrails struct { + // Configuration for input guardrail filters. + Input *AiGuardrailParameters + // Configuration for output guardrail filters. + Output *AiGuardrailParameters +} + +type AmazonBedrockConfig struct { + // The AWS region to use. Bedrock has to be enabled there. + AwsRegion *string + // The secret key reference for an AWS access key ID with + // permissions to interact with Bedrock services. If you prefer to paste your + // API key directly, see `aws_access_key_id_plaintext`. You must provide an API + // key using one of the following fields: `aws_access_key_id` or + // `aws_access_key_id_plaintext`. + AwsAccessKeyId *string + // The secret key reference for an AWS secret access key paired + // with the access key ID, with permissions to interact with Bedrock services. + // If you prefer to paste your API key directly, see + // `aws_secret_access_key_plaintext`. You must provide an API key using one of + // the following fields: `aws_secret_access_key` or + // `aws_secret_access_key_plaintext`. + AwsSecretAccessKey *string + // The underlying provider in Amazon Bedrock. Supported values (case + // insensitive) include: Anthropic, Cohere, AI21Labs, Amazon. + BedrockProvider *string + // An AWS access key ID with permissions to interact with Bedrock services + // provided as a plaintext string. If you prefer to reference your key using + // Databricks Secrets, see `aws_access_key_id`. You must provide an API key + // using one of the following fields: `aws_access_key_id` or + // `aws_access_key_id_plaintext`. + AwsAccessKeyIdPlaintext *string + // An AWS secret access key paired with the access key ID, with permissions to + // interact with Bedrock services provided as a plaintext string. If you prefer + // to reference your key using Databricks Secrets, see `aws_secret_access_key`. + // You must provide an API key using one of the following fields: + // `aws_secret_access_key` or `aws_secret_access_key_plaintext`. + AwsSecretAccessKeyPlaintext *string + // ARN of the instance profile that the external model will use to access AWS + // resources. You must authenticate using an instance profile or access keys. If + // you prefer to authenticate using access keys, see `aws_access_key_id`, + // `aws_access_key_id_plaintext`, `aws_secret_access_key` and + // `aws_secret_access_key_plaintext`. + InstanceProfileArn *string +} + +type AnthropicConfig struct { + // The secret key reference for an Anthropic API key. If you prefer + // to paste your API key directly, see `anthropic_api_key_plaintext`. You must + // provide an API key using one of the following fields: `anthropic_api_key` or + // `anthropic_api_key_plaintext`. + AnthropicApiKey *string + // The Anthropic API key provided as a plaintext string. If you prefer to + // reference your key using Databricks Secrets, see `anthropic_api_key`. You + // must provide an API key using one of the following fields: + // `anthropic_api_key` or `anthropic_api_key_plaintext`. + AnthropicApiKeyPlaintext *string +} + +type ApiKeyAuth struct { + // The name of the API key parameter used for authentication. + Key *string + // The secret key reference for an API Key. If you prefer to paste + // your token directly, see `value_plaintext`. + Value *string + // The API Key provided as a plaintext string. If you prefer to reference your + // token using Databricks Secrets, see `value`. + ValuePlaintext *string +} + +// Deprecated: legacy inference table configuration. Please use AI Gateway +// inference tables instead. See +// https://docs.databricks.com/aws/en/ai-gateway/inference-tables.. +type AutoCaptureConfig struct { + // The name of the catalog in Unity Catalog. NOTE: On update, you cannot change + // the catalog name if the inference table is already enabled. + CatalogName *string + // The name of the schema in Unity Catalog. NOTE: On update, you cannot change + // the schema name if the inference table is already enabled. + SchemaName *string + // The prefix of the table in Unity Catalog. NOTE: On update, you cannot change + // the prefix name if the inference table is already enabled. + TableNamePrefix *string + State *AutoCaptureState + // Indicates whether the inference table is enabled. + Enabled *bool +} + +type AutoCaptureState struct { + PayloadTable *PayloadTable +} + +type BearerTokenAuth struct { + // The secret key reference for a token. If you prefer to paste + // your token directly, see `token_plaintext`. + Token *string + // The token provided as a plaintext string. If you prefer to reference your + // token using Databricks Secrets, see `token`. + TokenPlaintext *string +} + +type CohereConfig struct { + // The secret key reference for a Cohere API key. If you prefer to + // paste your API key directly, see `cohere_api_key_plaintext`. You must provide + // an API key using one of the following fields: `cohere_api_key` or + // `cohere_api_key_plaintext`. + CohereApiKey *string + // The Cohere API key provided as a plaintext string. If you prefer to reference + // your key using Databricks Secrets, see `cohere_api_key`. You must provide an + // API key using one of the following fields: `cohere_api_key` or + // `cohere_api_key_plaintext`. + CohereApiKeyPlaintext *string + // This is an optional field to provide a customized base URL for the Cohere + // API. If left unspecified, the standard Cohere base URL is used. + CohereApiBase *string +} + +type CreateInferenceEndpointRequest struct { + // The name of the serving endpoint. This field is required and must be unique + // across a . An endpoint name can consist of alphanumeric + // characters, dashes, and underscores. + Name *string + // The core config of the serving endpoint. + Config *EndpointCoreConfig + // Tags to be attached to the serving endpoint and automatically propagated to + // billing logs. + Tags []EndpointTag + // Enable route optimization for the serving endpoint. + RouteOptimized *bool + // Rate limits to be applied to the serving endpoint. NOTE: this field is + // deprecated, please use AI Gateway to manage rate limits. + RateLimits []RateLimit + // The AI Gateway configuration for the serving endpoint. NOTE: External model, + // provisioned throughput, and pay-per-token endpoints are fully supported; + // agent endpoints currently only support inference tables. + AiGateway *AiGatewayConfig + // The budget policy to be applied to the serving endpoint. + BudgetPolicyId *string + // Email notification settings. + EmailNotifications *EmailNotifications + Description *string + // Configuration for persisting endpoint telemetry (logs, traces, and metrics) + // to Unity Catalog tables. + TelemetryConfig *TelemetryConfig +} + +type CreatePtEndpointRequest struct { + // The name of the serving endpoint. This field is required and must be unique + // across a . An endpoint name can consist of alphanumeric + // characters, dashes, and underscores. + Name *string + // The core config of the serving endpoint. + Config *PtEndpointCoreConfig + // Tags to be attached to the serving endpoint and automatically propagated to + // billing logs. + Tags []EndpointTag + // The AI Gateway configuration for the serving endpoint. + AiGateway *AiGatewayConfig + // The budget policy associated with the endpoint. + BudgetPolicyId *string + // Email notification settings. + EmailNotifications *EmailNotifications +} + +// Configs needed to create a custom provider model route.. +type CustomProviderConfig struct { + // This is a field to provide the URL of the custom provider API. + CustomProviderUrl *string + // This is a field to provide bearer token authentication for the custom + // provider API. You can only specify one authentication method. + BearerTokenAuth *BearerTokenAuth + // This is a field to provide API key authentication for the custom provider + // API. You can only specify one authentication method. + ApiKeyAuth *ApiKeyAuth +} + +// Details necessary to query this object's API through the DataPlane APIs.. +type DataPlaneInfo struct { + // The URL of the endpoint for this operation in the dataplane. + EndpointUrl *string + // Authorization details as a string. + AuthorizationDetails *string +} + +type DatabricksModelServingConfig struct { + // The secret key reference for a Databricks API token that + // corresponds to a user or service principal with Can Query access to the model + // serving endpoint pointed to by this external model. If you prefer to paste + // your API key directly, see `databricks_api_token_plaintext`. You must provide + // an API key using one of the following fields: `databricks_api_token` or + // `databricks_api_token_plaintext`. + DatabricksApiToken *string + // The URL of the workspace containing the model serving endpoint + // pointed to by this external model. + DatabricksWorkspaceUrl *string + // The Databricks API token that corresponds to a user or service principal with + // Can Query access to the model serving endpoint pointed to by this external + // model provided as a plaintext string. If you prefer to reference your key + // using Databricks Secrets, see `databricks_api_token`. You must provide an API + // key using one of the following fields: `databricks_api_token` or + // `databricks_api_token_plaintext`. + DatabricksApiTokenPlaintext *string +} + +type DeleteInferenceEndpointRequest struct { + Name *string +} + +type DeleteInferenceEndpointResponse struct { +} + +type EmailNotifications struct { + // A list of email addresses to be notified when an endpoint successfully + // updates its configuration or state. + OnUpdateSuccess []string + // A list of email addresses to be notified when an endpoint fails to update its + // configuration or state. + OnUpdateFailure []string +} + +type EndpointCoreConfig struct { + // The list of served entities under the serving endpoint config. + ServedEntities []ServedModel + // (Deprecated, use served_entities instead) The list of served models under the + // serving endpoint config. + ServedModels []ServedModel + // The traffic configuration associated with the serving endpoint config. + TrafficConfig *TrafficConfig + // Configuration for legacy Inference Tables which automatically log requests + // and responses to Unity Catalog. Deprecated: please use AI Gateway inference + // tables instead. See + // https://docs.databricks.com/aws/en/ai-gateway/inference-tables. + AutoCaptureConfig *AutoCaptureConfig +} + +type EndpointCoreConfigOutput struct { + // The config version that the serving endpoint is currently serving. + ConfigVersion *int64 + // The list of served entities under the serving endpoint config. + ServedEntities []ServedModel + // (Deprecated, use served_entities instead) The list of served models under the + // serving endpoint config. + ServedModels []ServedModel + // The traffic configuration associated with the serving endpoint config. + TrafficConfig *TrafficConfig + // Configuration for legacy Inference Tables which automatically log requests + // and responses to Unity Catalog. Deprecated: please use AI Gateway inference + // tables instead. See + // https://docs.databricks.com/aws/en/ai-gateway/inference-tables. + AutoCaptureConfig *AutoCaptureConfig +} + +type EndpointCoreConfigSummary struct { + // The list of served entities under the serving endpoint config. + ServedEntities []ServedModelLite + // (Deprecated, use served_entities instead) The list of served models under the + // serving endpoint config. + ServedModels []ServedModelLite +} + +type EndpointTag struct { + // Key field for a serving endpoint tag. + Key *string + // Optional value field for a serving endpoint tag. + Value *string +} + +// * Proto version of com.databricks.rpc.HttpOverRpcResponse. +// +// This message can be specially handled in UnaryRpcService with JettyRPC when +// the advanced feature CustomHandlingForHttpOverRpcProtoResponse is enabled - +// bypass the RPC serializer and populate HTTP status, response headers and +// response body from the proto message directly. +// +// Don't add/modify the fields before being aware of the implications.. +type ExportMetricsResponse struct { + Contents io.ReadCloser +} + +// Simple Proto message for testing. +type ExternalFunctionRequest struct { + // The connection name to use. This is required to identify the external + // connection. + ConnectionName *string + // The HTTP method to use (e.g., 'GET', 'POST'). + Method ExternalFunctionRequest_HttpMethod + // The relative path for the API endpoint. This is required. + Path *string + // The JSON payload to send in the request body. + Json *string + // Additional headers for the request. If not provided, only auth headers from + // connections would be passed. + Headers *string + // Query parameters for the request. + Params *string + // Optional subdomain to prepend to the connection URL's host. If provided, this + // will be added as a prefix to the connection URL's host. For example, if the + // connection URL is `https://api.example.com/v1` and `sub_domain` is + // `"custom"`, the resulting URL will be `https://custom.api.example.com/v1`. + SubDomain *string +} + +type ExternalFunctionResponse struct { + Contents io.ReadCloser +} + +type ExternalModel struct { + // The name of the provider for the external model. Currently, the supported + // providers are 'ai21labs', 'anthropic', 'amazon-bedrock', 'cohere', + // 'databricks-model-serving', 'google-cloud-vertex-ai', 'openai', 'palm', and + // 'custom'. + Provider *string + // The name of the external model. + Name *string + // The task type of the external model. + Task *string + // external model config. The config corresponding to the provider will be used. + Config isExternalModel_Config +} + +type isExternalModel_Config interface { + isExternalModel_Config() +} + +// ExternalModel_Config_Ai21labsConfig selects Ai21labsConfig for ExternalModel.Config. +// AI21Labs Config. Only required if the provider is 'ai21labs'. +type ExternalModel_Config_Ai21labsConfig struct { + Ai21labsConfig Ai21LabsConfig +} + +func (*ExternalModel_Config_Ai21labsConfig) isExternalModel_Config() {} + +// ExternalModel_Config_AnthropicConfig selects AnthropicConfig for ExternalModel.Config. +// Anthropic Config. Only required if the provider is 'anthropic'. +type ExternalModel_Config_AnthropicConfig struct { + AnthropicConfig AnthropicConfig +} + +func (*ExternalModel_Config_AnthropicConfig) isExternalModel_Config() {} + +// ExternalModel_Config_AmazonBedrockConfig selects AmazonBedrockConfig for ExternalModel.Config. +// Amazon Bedrock Config. Only required if the provider is 'amazon-bedrock'. +type ExternalModel_Config_AmazonBedrockConfig struct { + AmazonBedrockConfig AmazonBedrockConfig +} + +func (*ExternalModel_Config_AmazonBedrockConfig) isExternalModel_Config() {} + +// ExternalModel_Config_CohereConfig selects CohereConfig for ExternalModel.Config. +// Cohere Config. Only required if the provider is 'cohere'. +type ExternalModel_Config_CohereConfig struct { + CohereConfig CohereConfig +} + +func (*ExternalModel_Config_CohereConfig) isExternalModel_Config() {} + +// ExternalModel_Config_GoogleCloudVertexAiConfig selects GoogleCloudVertexAiConfig for ExternalModel.Config. +// Google Cloud Vertex AI Config. Only required if the provider is +// 'google-cloud-vertex-ai'. +type ExternalModel_Config_GoogleCloudVertexAiConfig struct { + GoogleCloudVertexAiConfig GoogleCloudVertexAiConfig +} + +func (*ExternalModel_Config_GoogleCloudVertexAiConfig) isExternalModel_Config() {} + +// ExternalModel_Config_DatabricksModelServingConfig selects DatabricksModelServingConfig for ExternalModel.Config. +// Databricks Model Serving Config. Only required if the provider is +// 'databricks-model-serving'. +type ExternalModel_Config_DatabricksModelServingConfig struct { + DatabricksModelServingConfig DatabricksModelServingConfig +} + +func (*ExternalModel_Config_DatabricksModelServingConfig) isExternalModel_Config() {} + +// ExternalModel_Config_OpenaiConfig selects OpenaiConfig for ExternalModel.Config. +// OpenAI Config. Only required if the provider is 'openai'. +type ExternalModel_Config_OpenaiConfig struct { + OpenaiConfig OpenAiConfig +} + +func (*ExternalModel_Config_OpenaiConfig) isExternalModel_Config() {} + +// ExternalModel_Config_PalmConfig selects PalmConfig for ExternalModel.Config. +// PaLM Config. Only required if the provider is 'palm'. +type ExternalModel_Config_PalmConfig struct { + PalmConfig PaLmConfig +} + +func (*ExternalModel_Config_PalmConfig) isExternalModel_Config() {} + +// ExternalModel_Config_CustomProviderConfig selects CustomProviderConfig for ExternalModel.Config. +// Custom Provider Config. Only required if the provider is 'custom'. +type ExternalModel_Config_CustomProviderConfig struct { + CustomProviderConfig CustomProviderConfig +} + +func (*ExternalModel_Config_CustomProviderConfig) isExternalModel_Config() {} + +type FallbackConfig struct { + // Whether to enable traffic fallback. When a served entity in the serving + // endpoint returns specific error codes (e.g. 500), the request will + // automatically be round-robin attempted with other served entities in the same + // endpoint, following the order of served entity list, until a successful + // response is returned. If all attempts fail, return the last response with the + // error code. + Enabled *bool +} + +// All fields are not sensitive as they are hard-coded in the system and made +// available to customers.. +type FoundationModel struct { + Name *string + DisplayName *string + Docs *string + Description *string +} + +type GetExportEndpointMetricsRequest struct { + // The name of the serving endpoint to retrieve metrics for. This field is + // required. + Name *string +} + +type GetInferenceEndpointRequest struct { + // The name of the serving endpoint. This field is required. + Name *string +} + +type GetInferenceEndpointSchemaRequest struct { + // The name of the serving endpoint that the served model belongs to. This field + // is required. + Name *string +} + +// The top level proto message that represents an OpenAPI 3.0 document.. +type GetOpenApiResponse struct { + Contents io.ReadCloser +} + +type GetServedModelBuildLogsRequest struct { + // The name of the serving endpoint that the served model belongs to. This field + // is required. + Name *string + // The name of the served model that build logs will be retrieved for. This + // field is required. + ServedModelName *string +} + +type GetServedModelBuildLogsResponse struct { + // The logs associated with building the served entity's environment. + Logs *string +} + +type GetServedModelLogsRequest struct { + // The name of the serving endpoint that the served model belongs to. This field + // is required. + Name *string + // The name of the served model that logs will be retrieved for. This field is + // required. + ServedModelName *string +} + +type GetServedModelLogsResponse struct { + // The most recent log lines of the model server processing invocation requests. + Logs *string +} + +type GoogleCloudVertexAiConfig struct { + // The secret key reference for a private key for the service + // account which has access to the Google Cloud Vertex AI Service. See [Best + // practices for managing service account keys]. If you prefer to paste your API + // key directly, see `private_key_plaintext`. You must provide an API key using + // one of the following fields: `private_key` or `private_key_plaintext` + // + // [Best practices for managing service account keys]: + // https://cloud.google.com/iam/docs/best-practices-for-managing-service-account-keys + PrivateKey *string + // This is the Google Cloud project id that the service account is associated + // with. + ProjectId *string + // This is the region for the Google Cloud Vertex AI Service. See [supported + // regions] for more details. Some models are only available in specific + // regions. + // + // [supported regions]: + // https://cloud.google.com/vertex-ai/docs/general/locations + Region *string + // The private key for the service account which has access to the Google Cloud + // Vertex AI Service provided as a plaintext secret. See [Best practices for + // managing service account keys]. If you prefer to reference your key using + // Databricks Secrets, see `private_key`. You must provide an API key using one + // of the following fields: `private_key` or `private_key_plaintext`. + // + // [Best practices for managing service account keys]: + // https://cloud.google.com/iam/docs/best-practices-for-managing-service-account-keys + PrivateKeyPlaintext *string +} + +type InferenceEndpoint struct { + // The name of the serving endpoint. + Name *string + // The email of the user who created the serving endpoint. + Creator *string + // The timestamp when the endpoint was created in Unix time. + CreationTimestamp *int64 + // The timestamp when the endpoint was last updated by a user in Unix time. + LastUpdatedTimestamp *int64 + // Information corresponding to the state of the serving endpoint. + State *InferenceEndpointState + // The config that is currently being served by the endpoint. + Config *EndpointCoreConfigSummary + // Tags attached to the serving endpoint. + Tags []EndpointTag + // System-generated ID of the endpoint, included to be used by the Permissions + // API. + Id *string + // The task type of the serving endpoint. + Task *string + // The AI Gateway configuration for the serving endpoint. NOTE: External model, + // provisioned throughput, and pay-per-token endpoints are fully supported; + // agent endpoints currently only support inference tables. + AiGateway *AiGatewayConfig + // The budget policy associated with the endpoint. + BudgetPolicyId *string + // Description of the endpoint + Description *string + // The usage policy associated with serving endpoint. + UsagePolicyId *string + // Telemetry configuration for the endpoint, including inference-table payload + // logging. + TelemetryConfig *TelemetryConfig +} + +type InferenceEndpointDetailed struct { + // The name of the serving endpoint. + Name *string + // The email of the user who created the serving endpoint. + Creator *string + // The timestamp when the endpoint was created in Unix time. + CreationTimestamp *int64 + // The timestamp when the endpoint was last updated by a user in Unix time. + LastUpdatedTimestamp *int64 + // Information corresponding to the state of the serving endpoint. + State *InferenceEndpointState + // The config that is currently being served by the endpoint. + Config *EndpointCoreConfigOutput + // The config that the endpoint is attempting to update to. + PendingConfig *PendingConfig + // System-generated ID of the endpoint. This is used to refer to the endpoint in + // the Permissions API + Id *string + // The permission level of the principal making the request. + PermissionLevel ServingEndpointDetailedPermissionLevel + // Tags attached to the serving endpoint. + Tags []EndpointTag + // The task type of the serving endpoint. + Task *string + // Boolean representing if route optimization has been enabled for the endpoint + RouteOptimized *bool + // Endpoint invocation url if route optimization is enabled for endpoint + EndpointUrl *string + // Information required to query DataPlane APIs. + DataPlaneInfo *ModelDataPlaneInfo + // The AI Gateway configuration for the serving endpoint. NOTE: External model, + // provisioned throughput, and pay-per-token endpoints are fully supported; + // agent endpoints currently only support inference tables. + AiGateway *AiGatewayConfig + // The budget policy associated with the endpoint. + BudgetPolicyId *string + // Email notification settings. + EmailNotifications *EmailNotifications + // Description of the serving model + Description *string + // Telemetry configuration for the endpoint, including inference-table payload + // logging. + TelemetryConfig *TelemetryConfig +} + +type InferenceEndpointState struct { + // The state of an endpoint, indicating whether or not the endpoint is + // queryable. An endpoint is READY if all of the served entities in its active + // configuration are ready. If any of the actively served entities are in a + // non-ready state, the endpoint state will be NOT_READY. + Ready InferenceEndpointState_ReadyState + // The state of an endpoint's config update. This informs the user if the + // pending_config is in progress, if the update failed, or if there is no update + // in progress. Note that if the endpoint's config_update state value is + // IN_PROGRESS, another update can not be made until the update completes or + // fails. + ConfigUpdate InferenceEndpointState_ConfigUpdateState +} + +type InferenceTableConfig struct { + // The name of the catalog in Unity Catalog. Required when enabling inference + // tables. NOTE: On update, you have to disable inference table first in order + // to change the catalog name. + CatalogName *string + // The name of the schema in Unity Catalog. Required when enabling inference + // tables. NOTE: On update, you have to disable inference table first in order + // to change the schema name. + SchemaName *string + // The prefix of the table in Unity Catalog. NOTE: On update, you have to + // disable inference table first in order to change the prefix name. + TableNamePrefix *string + // Indicates whether the inference table is enabled. + Enabled *bool +} + +type ListInferenceEndpointsRequest struct { +} + +type ListInferenceEndpointsResponse struct { + // The list of endpoints. + Endpoints []InferenceEndpoint +} + +// A representation of all DataPlaneInfo for operations that can be done on a +// model through Data Plane APIs.. +type ModelDataPlaneInfo struct { + // Information required to query DataPlane API 'query' endpoint. + QueryInfo *DataPlaneInfo +} + +// Configs needed to create an OpenAI model route.. +type OpenAiConfig struct { + // The secret key reference for an OpenAI API key using the OpenAI + // or Azure service. If you prefer to paste your API key directly, see + // `openai_api_key_plaintext`. You must provide an API key using one of the + // following fields: `openai_api_key` or `openai_api_key_plaintext`. + OpenaiApiKey *string + // This is an optional field to specify the type of OpenAI API to use. For Azure + // OpenAI, this field is required, and adjust this parameter to represent the + // preferred security access validation protocol. For access token validation, + // use azure. For authentication using Azure Active Directory (Azure AD) use, + // azuread. + OpenaiApiType *string + // This is a field to provide a customized base URl for the OpenAI API. For + // Azure OpenAI, this field is required, and is the base URL for the Azure + // OpenAI API service provided by Azure. For other OpenAI API types, this field + // is optional, and if left unspecified, the standard OpenAI base URL is used. + OpenaiApiBase *string + // This is an optional field to specify the OpenAI API version. For Azure + // OpenAI, this field is required, and is the version of the Azure OpenAI + // service to utilize, specified by a date. + OpenaiApiVersion *string + // This field is only required for Azure OpenAI and is the name of the + // deployment resource for the Azure OpenAI service. + OpenaiDeploymentName *string + // This is an optional field to specify the organization in OpenAI or Azure + // OpenAI. + OpenaiOrganization *string + // This field is only required for Azure AD OpenAI and is the Microsoft Entra + // Tenant ID. + MicrosoftEntraTenantId *string + // This field is only required for Azure AD OpenAI and is the Microsoft Entra + // Client ID. + MicrosoftEntraClientId *string + // The secret key reference for a client secret used for Microsoft + // Entra ID authentication. If you prefer to paste your client secret directly, + // see `microsoft_entra_client_secret_plaintext`. You must provide an API key + // using one of the following fields: `microsoft_entra_client_secret` or + // `microsoft_entra_client_secret_plaintext`. + MicrosoftEntraClientSecret *string + // The OpenAI API key using the OpenAI or Azure service provided as a plaintext + // string. If you prefer to reference your key using Databricks Secrets, see + // `openai_api_key`. You must provide an API key using one of the following + // fields: `openai_api_key` or `openai_api_key_plaintext`. + OpenaiApiKeyPlaintext *string + // The client secret used for Microsoft Entra ID authentication provided as a + // plaintext string. If you prefer to reference your key using Databricks + // Secrets, see `microsoft_entra_client_secret`. You must provide an API key + // using one of the following fields: `microsoft_entra_client_secret` or + // `microsoft_entra_client_secret_plaintext`. + MicrosoftEntraClientSecretPlaintext *string +} + +type PaLmConfig struct { + // The secret key reference for a PaLM API key. If you prefer to + // paste your API key directly, see `palm_api_key_plaintext`. You must provide + // an API key using one of the following fields: `palm_api_key` or + // `palm_api_key_plaintext`. + PalmApiKey *string + // The PaLM API key provided as a plaintext string. If you prefer to reference + // your key using Databricks Secrets, see `palm_api_key`. You must provide an + // API key using one of the following fields: `palm_api_key` or + // `palm_api_key_plaintext`. + PalmApiKeyPlaintext *string +} + +type PatchInferenceEndpointTagsRequest struct { + // The name of the serving endpoint who's tags to patch. This field is required. + Name *string + // List of endpoint tags to add + AddTags []EndpointTag + // List of tag keys to delete + DeleteTags []string +} + +type PatchInferenceEndpointTagsResponse struct { + Tags []EndpointTag +} + +// Updates the telemetry configuration of a serving endpoint.. +type PatchInferenceEndpointTelemetryConfigRequest struct { + // The name of the serving endpoint whose telemetry configuration is being + // updated. This field is required. + Name *string + // The telemetry configuration to be applied to the serving endpoint. Can + // specify either a telemetry_profile_id to use an existing profile, or + // table_names to create a new profile with the specified Unity Catalog tables. + // If not provided, the telemetry configuration will be removed from the + // endpoint. + TelemetryConfig *TelemetryConfig +} + +type PayloadTable struct { + Name *string + Status *string + StatusMessage *string +} + +type PendingConfig struct { + // The list of served entities belonging to the last issued update to the + // serving endpoint. + ServedEntities []ServedModel + // (Deprecated, use served_entities instead) The list of served models belonging + // to the last issued update to the serving endpoint. + ServedModels []ServedModel + // The traffic config defining how invocations to the serving endpoint should be + // routed. + TrafficConfig *TrafficConfig + // The config version that the serving endpoint is currently serving. + ConfigVersion *int + // The timestamp when the update to the pending config started. + StartTime *int64 + // Configuration for legacy Inference Tables which automatically log requests + // and responses to Unity Catalog. Deprecated: please use AI Gateway inference + // tables instead. See + // https://docs.databricks.com/aws/en/ai-gateway/inference-tables. + AutoCaptureConfig *AutoCaptureConfig +} + +type PiiSettings struct { + // Configuration for input guardrail filters. + Behavior Behavior +} + +type PtEndpointCoreConfig struct { + // The list of served entities under the serving endpoint config. + ServedEntities []PtServedModel + TrafficConfig *TrafficConfig +} + +type PtServedModel struct { + // The name of a served entity. It must be unique across an endpoint. A served + // entity name can consist of alphanumeric characters, dashes, and underscores. + // If not specified for an external model, this field defaults to + // external_model.name, with '.' and ':' replaced with '-', and if not specified + // for other entities, it defaults to entity_name-entity_version. + Name *string + // The name of the entity to be served. The entity may be a model in the + // Databricks Model Registry, a model in the Unity Catalog (UC), or a function + // of type FEATURE_SPEC in the UC. If it is a UC object, the full name of the + // object should be given in the form of + // **catalog_name.schema_name.model_name**. + EntityName *string + EntityVersion *string + // The number of model units to be provisioned. + ProvisionedModelUnits *int64 + // Whether burst scaling is enabled. When enabled (default), the endpoint can + // automatically scale up beyond provisioned capacity to handle traffic spikes. + // When disabled, the endpoint maintains fixed capacity at + // provisioned_model_units. + BurstScalingEnabled *bool +} + +type PutInferenceEndpointAiGatewayRequest struct { + // The name of the serving endpoint whose AI Gateway is being updated. This + // field is required. + Name *string + // Configuration to enable usage tracking using system tables. These tables + // allow you to monitor operational usage on endpoints and their associated + // costs. + UsageTrackingConfig *UsageTrackingConfig + // Configuration for payload logging using inference tables. Use these tables to + // monitor and audit data being sent to and received from model APIs and to + // improve model quality. + InferenceTableConfig *InferenceTableConfig + // Configuration for rate limits which can be set to limit endpoint traffic. + RateLimits []AiGatewayRateLimit + // Configuration for AI Guardrails to prevent unwanted data and unsafe data in + // requests and responses. + Guardrails *AiGuardrails + // Configuration for traffic fallback which auto fallbacks to other served + // entities if the request to a served entity fails with certain error codes, to + // increase availability. + FallbackConfig *FallbackConfig +} + +type PutInferenceEndpointAiGatewayResponse struct { + // Configuration to enable usage tracking using system tables. These tables + // allow you to monitor operational usage on endpoints and their associated + // costs. + UsageTrackingConfig *UsageTrackingConfig + // Configuration for payload logging using inference tables. Use these tables to + // monitor and audit data being sent to and received from model APIs and to + // improve model quality. + InferenceTableConfig *InferenceTableConfig + // Configuration for rate limits which can be set to limit endpoint traffic. + RateLimits []AiGatewayRateLimit + // Configuration for AI Guardrails to prevent unwanted data and unsafe data in + // requests and responses. + Guardrails *AiGuardrails + // Configuration for traffic fallback which auto fallbacks to other served + // entities if the request to a served entity fails with certain error codes, to + // increase availability. + FallbackConfig *FallbackConfig +} + +type PutInferenceEndpointConfigRequest struct { + // The name of the serving endpoint to update. This field is required. + Name *string + // The list of served entities under the serving endpoint config. + ServedEntities []ServedModel + // (Deprecated, use served_entities instead) The list of served models under the + // serving endpoint config. + ServedModels []ServedModel + // The traffic configuration associated with the serving endpoint config. + TrafficConfig *TrafficConfig + // Configuration for legacy Inference Tables which automatically log requests + // and responses to Unity Catalog. Deprecated: please use AI Gateway inference + // tables instead. See + // https://docs.databricks.com/aws/en/ai-gateway/inference-tables. + AutoCaptureConfig *AutoCaptureConfig +} + +type PutInferenceEndpointRateLimitsRequest struct { + // The name of the serving endpoint whose rate limits are being updated. This + // field is required. + Name *string + // The list of endpoint rate limits. + RateLimits []RateLimit +} + +type PutInferenceEndpointRateLimitsResponse struct { + // The list of endpoint rate limits. + RateLimits []RateLimit +} + +type PutPtEndpointConfigRequest struct { + // The name of the pt endpoint to update. This field is required. + Name *string + Config *PtEndpointCoreConfig +} + +type RateLimit struct { + // Used to specify how many calls are allowed for a key within the + // renewal_period. + Calls *int64 + // Key field for a serving endpoint rate limit. Currently, only 'user' and + // 'endpoint' are supported, with 'endpoint' being the default if not specified. + Key *string + // Renewal period field for a serving endpoint rate limit. Currently, only + // 'minute' is supported. + RenewalPeriod *string +} + +type Route struct { + // The name of the served model this route configures traffic for. + ServedModelName *string + // The percentage of endpoint traffic to send to this route. It must be an + // integer between 0 and 100 inclusive. + TrafficPercentage *int + ServedEntityName *string +} + +type ServedModel struct { + // The name of a served entity. It must be unique across an endpoint. A served + // entity name can consist of alphanumeric characters, dashes, and underscores. + // If not specified for an external model, this field defaults to + // external_model.name, with '.' and ':' replaced with '-', and if not specified + // for other entities, it defaults to entity_name-entity_version. + Name *string + // The external model to be served. NOTE: Only one of external_model and + // (entity_name, entity_version, workload_size, workload_type, and + // scale_to_zero_enabled) can be specified with the latter set being used for + // custom model serving for a registered model. For an existing + // endpoint with external_model, it cannot be updated to an endpoint without + // external_model. If the endpoint is created without external_model, users + // cannot update it to add external_model later. The task type of all external + // models within an endpoint must be the same. + ExternalModel *ExternalModel + // The name of the entity to be served. The entity may be a model in the + // Databricks Model Registry, a model in the Unity Catalog (UC), or a function + // of type FEATURE_SPEC in the UC. If it is a UC object, the full name of the + // object should be given in the form of + // **catalog_name.schema_name.model_name**. + EntityName *string + EntityVersion *string + // The minimum tokens per second that the endpoint can scale down to. + MinProvisionedThroughput *int + // The maximum tokens per second that the endpoint can scale up to. + MaxProvisionedThroughput *int + // The minimum provisioned concurrency that the endpoint can scale down to. Do + // not use if workload_size is specified. + MinProvisionedConcurrency *int + // The maximum provisioned concurrency that the endpoint can scale up to. Do not + // use if workload_size is specified. + MaxProvisionedConcurrency *int + // The workload size of the served entity. The workload size corresponds to a + // range of provisioned concurrency that the compute autoscales between. A + // single unit of provisioned concurrency can process one request at a time. + // Valid workload sizes are "Small" (4 - 4 provisioned concurrency), "Medium" (8 + // - 16 provisioned concurrency), and "Large" (16 - 64 provisioned concurrency). + // Additional custom workload sizes can also be used when available in the + // workspace. If scale-to-zero is enabled, the lower bound of the provisioned + // concurrency for each workload size is 0. Do not use if + // min_provisioned_concurrency and max_provisioned_concurrency are specified. + WorkloadSize *string + // The number of model units provisioned. + ProvisionedModelUnits *int64 + // Whether burst scaling is enabled. When enabled (default), the endpoint can + // automatically scale up beyond provisioned capacity to handle traffic spikes. + // When disabled, the endpoint maintains fixed capacity at + // provisioned_model_units. + BurstScalingEnabled *bool + // Whether the compute resources for the served entity should scale down to + // zero. + ScaleToZeroEnabled *bool + ModelName *string + ModelVersion *string + // An object containing a set of optional, user-specified environment variable + // key-value pairs used for serving this entity. Note: this is an experimental + // feature and subject to change. Example entity environment variables that + // refer to secrets: `{"OPENAI_API_KEY": + // "{{secrets/my_scope/my_key}}", "DATABRICKS_TOKEN": + // "{{secrets/my_scope2/my_key2}}"}` + EnvironmentVars map[string]string + // ARN of the instance profile that the served entity uses to access AWS + // resources. + InstanceProfileArn *string + FoundationModel *FoundationModel + State *ServedModelState + Creator *string + CreationTimestamp *int64 +} + +type ServedModelLite struct { + Name *string + // Only one of model_name and entity_name should be populated + ModelName *string + EntityName *string + // Only one of model_version and entity_version should be populated + ModelVersion *string + EntityVersion *string + ExternalModel *ExternalModel + FoundationModel *FoundationModel +} + +type ServedModelState struct { + Deployment ServedModelDeploymentState + DeploymentStateMessage *string +} + +type TelemetryConfig struct { + TelemetryProfile isTelemetryConfig_TelemetryProfile + // Configuration for inference table payload logging, including sampling. + InferenceTableConfig *TelemetryInferenceTableConfig + // The telemetry signals to enable for this endpoint. If empty or omitted, all + // signals are enabled; otherwise only the listed signals are enabled. + EnabledTelemetryFeatures []TelemetryFeature +} + +type isTelemetryConfig_TelemetryProfile interface { + isTelemetryConfig_TelemetryProfile() +} + +// TelemetryConfig_TelemetryProfile_TelemetryProfileId selects TelemetryProfileId for TelemetryConfig.TelemetryProfile. +// The ID of an existing telemetry profile to apply to this endpoint. Provide +// this to reuse a telemetry profile that has already been created, instead of +// specifying table_names. +type TelemetryConfig_TelemetryProfile_TelemetryProfileId struct { + TelemetryProfileId string +} + +func (*TelemetryConfig_TelemetryProfile_TelemetryProfileId) isTelemetryConfig_TelemetryProfile() {} + +// TelemetryConfig_TelemetryProfile_TableNames selects TableNames for TelemetryConfig.TelemetryProfile. +// The Unity Catalog tables to which endpoint telemetry (logs, traces, and +// metrics) is exported. Provide this to create a new telemetry profile for the +// endpoint from the given tables. +type TelemetryConfig_TelemetryProfile_TableNames struct { + TableNames UnityCatalogTableNames +} + +func (*TelemetryConfig_TelemetryProfile_TableNames) isTelemetryConfig_TelemetryProfile() {} + +// Inference table payload logging configuration. +type TelemetryInferenceTableConfig struct { + // Fraction of requests sampled for payload logging, in the range [0.0, 1.0], + // where 1.0 logs all requests. + SamplingFraction *float64 + // The full name of the inference table created for this endpoint. + Name *string +} + +type TrafficConfig struct { + // The list of routes that define traffic to each served entity. + Routes []Route +} + +type UnityCatalogTableNames struct { + // The full three-level Unity Catalog name (catalog.schema.table) of the table + // that receives exported logs. + LogsTable *string + // The full three-level Unity Catalog name (catalog.schema.table) of the table + // that receives exported metrics. + MetricsTable *string + // The full three-level Unity Catalog name (catalog.schema.table) of the table + // that receives exported traces (spans). + TracesTable *string + // The full three-level Unity Catalog name (catalog.schema.table) of the table + // that receives exported annotations. + AnnotationsTable *string +} + +type UpdateInferenceEndpointNotificationsRequest struct { + // The name of the serving endpoint whose notifications are being updated. This + // field is required. + Name *string + // The email notification settings to update. Specify email addresses to notify + // when endpoint state changes occur. + EmailNotifications *EmailNotifications +} + +type UpdateInferenceEndpointNotificationsResponse struct { + Name *string + EmailNotifications *EmailNotifications +} + +type UsageTrackingConfig struct { + // Whether to enable usage tracking. + Enabled *bool +} diff --git a/modelserving/v1/wire.go b/modelserving/v1/wire.go new file mode 100755 index 0000000..ea791b1 --- /dev/null +++ b/modelserving/v1/wire.go @@ -0,0 +1,2239 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelserving + +import ( + "fmt" +) + +type ai21LabsConfigWire struct { + Ai21labsApiKey *string `json:"ai21labs_api_key,omitempty"` + Ai21labsApiKeyPlaintext *string `json:"ai21labs_api_key_plaintext,omitempty"` +} + +func ai21LabsConfigToWire(v *Ai21LabsConfig) (*ai21LabsConfigWire, error) { + if v == nil { + return nil, nil + } + return &ai21LabsConfigWire{ + Ai21labsApiKey: v.Ai21labsApiKey, + Ai21labsApiKeyPlaintext: v.Ai21labsApiKeyPlaintext, + }, nil +} + +func ai21LabsConfigFromWire(w *ai21LabsConfigWire) (*Ai21LabsConfig, error) { + if w == nil { + return nil, nil + } + return &Ai21LabsConfig{ + Ai21labsApiKey: w.Ai21labsApiKey, + Ai21labsApiKeyPlaintext: w.Ai21labsApiKeyPlaintext, + }, nil +} + +type aiGatewayConfigWire struct { + UsageTrackingConfig *usageTrackingConfigWire `json:"usage_tracking_config,omitempty"` + InferenceTableConfig *inferenceTableConfigWire `json:"inference_table_config,omitempty"` + RateLimits []aiGatewayRateLimitWire `json:"rate_limits,omitempty"` + Guardrails *aiGuardrailsWire `json:"guardrails,omitempty"` + FallbackConfig *fallbackConfigWire `json:"fallback_config,omitempty"` +} + +func aiGatewayConfigToWire(v *AiGatewayConfig) (*aiGatewayConfigWire, error) { + if v == nil { + return nil, nil + } + usageTrackingConfigWireValue, err := usageTrackingConfigToWire(v.UsageTrackingConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGatewayConfig.UsageTrackingConfig", err) + } + inferenceTableConfigWireValue, err := inferenceTableConfigToWire(v.InferenceTableConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGatewayConfig.InferenceTableConfig", err) + } + rateLimitsWireValue, err := convertSlice(v.RateLimits, aiGatewayRateLimitToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGatewayConfig.RateLimits", err) + } + guardrailsWireValue, err := aiGuardrailsToWire(v.Guardrails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGatewayConfig.Guardrails", err) + } + fallbackConfigWireValue, err := fallbackConfigToWire(v.FallbackConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGatewayConfig.FallbackConfig", err) + } + return &aiGatewayConfigWire{ + UsageTrackingConfig: usageTrackingConfigWireValue, + InferenceTableConfig: inferenceTableConfigWireValue, + RateLimits: rateLimitsWireValue, + Guardrails: guardrailsWireValue, + FallbackConfig: fallbackConfigWireValue, + }, nil +} + +func aiGatewayConfigFromWire(w *aiGatewayConfigWire) (*AiGatewayConfig, error) { + if w == nil { + return nil, nil + } + usageTrackingConfigPublicValue, err := usageTrackingConfigFromWire(w.UsageTrackingConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGatewayConfig.UsageTrackingConfig", err) + } + inferenceTableConfigPublicValue, err := inferenceTableConfigFromWire(w.InferenceTableConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGatewayConfig.InferenceTableConfig", err) + } + rateLimitsPublicValue, err := convertSlice(w.RateLimits, aiGatewayRateLimitFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGatewayConfig.RateLimits", err) + } + guardrailsPublicValue, err := aiGuardrailsFromWire(w.Guardrails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGatewayConfig.Guardrails", err) + } + fallbackConfigPublicValue, err := fallbackConfigFromWire(w.FallbackConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGatewayConfig.FallbackConfig", err) + } + return &AiGatewayConfig{ + UsageTrackingConfig: usageTrackingConfigPublicValue, + InferenceTableConfig: inferenceTableConfigPublicValue, + RateLimits: rateLimitsPublicValue, + Guardrails: guardrailsPublicValue, + FallbackConfig: fallbackConfigPublicValue, + }, nil +} + +type aiGatewayRateLimitWire struct { + Calls *int64 `json:"calls,omitempty"` + Key *string `json:"key,omitempty"` + RenewalPeriod *string `json:"renewal_period,omitempty"` + Principal *string `json:"principal,omitempty"` + Tokens *int64 `json:"tokens,omitempty"` +} + +func aiGatewayRateLimitToWire(v *AiGatewayRateLimit) (*aiGatewayRateLimitWire, error) { + if v == nil { + return nil, nil + } + return &aiGatewayRateLimitWire{ + Calls: v.Calls, + Key: v.Key, + RenewalPeriod: v.RenewalPeriod, + Principal: v.Principal, + Tokens: v.Tokens, + }, nil +} + +func aiGatewayRateLimitFromWire(w *aiGatewayRateLimitWire) (*AiGatewayRateLimit, error) { + if w == nil { + return nil, nil + } + return &AiGatewayRateLimit{ + Calls: w.Calls, + Key: w.Key, + RenewalPeriod: w.RenewalPeriod, + Principal: w.Principal, + Tokens: w.Tokens, + }, nil +} + +type aiGuardrailParametersWire struct { + Safety *bool `json:"safety,omitempty"` + Pii *piiSettingsWire `json:"pii,omitempty"` + ValidTopics []string `json:"valid_topics,omitempty"` + InvalidKeywords []string `json:"invalid_keywords,omitempty"` +} + +func aiGuardrailParametersToWire(v *AiGuardrailParameters) (*aiGuardrailParametersWire, error) { + if v == nil { + return nil, nil + } + piiWireValue, err := piiSettingsToWire(v.Pii) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGuardrailParameters.Pii", err) + } + return &aiGuardrailParametersWire{ + Safety: v.Safety, + Pii: piiWireValue, + ValidTopics: v.ValidTopics, + InvalidKeywords: v.InvalidKeywords, + }, nil +} + +func aiGuardrailParametersFromWire(w *aiGuardrailParametersWire) (*AiGuardrailParameters, error) { + if w == nil { + return nil, nil + } + piiPublicValue, err := piiSettingsFromWire(w.Pii) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGuardrailParameters.Pii", err) + } + return &AiGuardrailParameters{ + Safety: w.Safety, + Pii: piiPublicValue, + ValidTopics: w.ValidTopics, + InvalidKeywords: w.InvalidKeywords, + }, nil +} + +type aiGuardrailsWire struct { + Input *aiGuardrailParametersWire `json:"input,omitempty"` + Output *aiGuardrailParametersWire `json:"output,omitempty"` +} + +func aiGuardrailsToWire(v *AiGuardrails) (*aiGuardrailsWire, error) { + if v == nil { + return nil, nil + } + inputWireValue, err := aiGuardrailParametersToWire(v.Input) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGuardrails.Input", err) + } + outputWireValue, err := aiGuardrailParametersToWire(v.Output) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGuardrails.Output", err) + } + return &aiGuardrailsWire{ + Input: inputWireValue, + Output: outputWireValue, + }, nil +} + +func aiGuardrailsFromWire(w *aiGuardrailsWire) (*AiGuardrails, error) { + if w == nil { + return nil, nil + } + inputPublicValue, err := aiGuardrailParametersFromWire(w.Input) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGuardrails.Input", err) + } + outputPublicValue, err := aiGuardrailParametersFromWire(w.Output) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AiGuardrails.Output", err) + } + return &AiGuardrails{ + Input: inputPublicValue, + Output: outputPublicValue, + }, nil +} + +type amazonBedrockConfigWire struct { + AwsRegion *string `json:"aws_region,omitempty"` + AwsAccessKeyId *string `json:"aws_access_key_id,omitempty"` + AwsSecretAccessKey *string `json:"aws_secret_access_key,omitempty"` + BedrockProvider *string `json:"bedrock_provider,omitempty"` + AwsAccessKeyIdPlaintext *string `json:"aws_access_key_id_plaintext,omitempty"` + AwsSecretAccessKeyPlaintext *string `json:"aws_secret_access_key_plaintext,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` +} + +func amazonBedrockConfigToWire(v *AmazonBedrockConfig) (*amazonBedrockConfigWire, error) { + if v == nil { + return nil, nil + } + return &amazonBedrockConfigWire{ + AwsRegion: v.AwsRegion, + AwsAccessKeyId: v.AwsAccessKeyId, + AwsSecretAccessKey: v.AwsSecretAccessKey, + BedrockProvider: v.BedrockProvider, + AwsAccessKeyIdPlaintext: v.AwsAccessKeyIdPlaintext, + AwsSecretAccessKeyPlaintext: v.AwsSecretAccessKeyPlaintext, + InstanceProfileArn: v.InstanceProfileArn, + }, nil +} + +func amazonBedrockConfigFromWire(w *amazonBedrockConfigWire) (*AmazonBedrockConfig, error) { + if w == nil { + return nil, nil + } + return &AmazonBedrockConfig{ + AwsRegion: w.AwsRegion, + AwsAccessKeyId: w.AwsAccessKeyId, + AwsSecretAccessKey: w.AwsSecretAccessKey, + BedrockProvider: w.BedrockProvider, + AwsAccessKeyIdPlaintext: w.AwsAccessKeyIdPlaintext, + AwsSecretAccessKeyPlaintext: w.AwsSecretAccessKeyPlaintext, + InstanceProfileArn: w.InstanceProfileArn, + }, nil +} + +type anthropicConfigWire struct { + AnthropicApiKey *string `json:"anthropic_api_key,omitempty"` + AnthropicApiKeyPlaintext *string `json:"anthropic_api_key_plaintext,omitempty"` +} + +func anthropicConfigToWire(v *AnthropicConfig) (*anthropicConfigWire, error) { + if v == nil { + return nil, nil + } + return &anthropicConfigWire{ + AnthropicApiKey: v.AnthropicApiKey, + AnthropicApiKeyPlaintext: v.AnthropicApiKeyPlaintext, + }, nil +} + +func anthropicConfigFromWire(w *anthropicConfigWire) (*AnthropicConfig, error) { + if w == nil { + return nil, nil + } + return &AnthropicConfig{ + AnthropicApiKey: w.AnthropicApiKey, + AnthropicApiKeyPlaintext: w.AnthropicApiKeyPlaintext, + }, nil +} + +type apiKeyAuthWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` + ValuePlaintext *string `json:"value_plaintext,omitempty"` +} + +func apiKeyAuthToWire(v *ApiKeyAuth) (*apiKeyAuthWire, error) { + if v == nil { + return nil, nil + } + return &apiKeyAuthWire{ + Key: v.Key, + Value: v.Value, + ValuePlaintext: v.ValuePlaintext, + }, nil +} + +func apiKeyAuthFromWire(w *apiKeyAuthWire) (*ApiKeyAuth, error) { + if w == nil { + return nil, nil + } + return &ApiKeyAuth{ + Key: w.Key, + Value: w.Value, + ValuePlaintext: w.ValuePlaintext, + }, nil +} + +type autoCaptureConfigWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + TableNamePrefix *string `json:"table_name_prefix,omitempty"` + State *autoCaptureStateWire `json:"state,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func autoCaptureConfigToWire(v *AutoCaptureConfig) (*autoCaptureConfigWire, error) { + if v == nil { + return nil, nil + } + stateWireValue, err := autoCaptureStateToWire(v.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AutoCaptureConfig.State", err) + } + return &autoCaptureConfigWire{ + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + TableNamePrefix: v.TableNamePrefix, + State: stateWireValue, + Enabled: v.Enabled, + }, nil +} + +func autoCaptureConfigFromWire(w *autoCaptureConfigWire) (*AutoCaptureConfig, error) { + if w == nil { + return nil, nil + } + statePublicValue, err := autoCaptureStateFromWire(w.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AutoCaptureConfig.State", err) + } + return &AutoCaptureConfig{ + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + TableNamePrefix: w.TableNamePrefix, + State: statePublicValue, + Enabled: w.Enabled, + }, nil +} + +type autoCaptureStateWire struct { + PayloadTable *payloadTableWire `json:"payload_table,omitempty"` +} + +func autoCaptureStateToWire(v *AutoCaptureState) (*autoCaptureStateWire, error) { + if v == nil { + return nil, nil + } + payloadTableWireValue, err := payloadTableToWire(v.PayloadTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AutoCaptureState.PayloadTable", err) + } + return &autoCaptureStateWire{ + PayloadTable: payloadTableWireValue, + }, nil +} + +func autoCaptureStateFromWire(w *autoCaptureStateWire) (*AutoCaptureState, error) { + if w == nil { + return nil, nil + } + payloadTablePublicValue, err := payloadTableFromWire(w.PayloadTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AutoCaptureState.PayloadTable", err) + } + return &AutoCaptureState{ + PayloadTable: payloadTablePublicValue, + }, nil +} + +type bearerTokenAuthWire struct { + Token *string `json:"token,omitempty"` + TokenPlaintext *string `json:"token_plaintext,omitempty"` +} + +func bearerTokenAuthToWire(v *BearerTokenAuth) (*bearerTokenAuthWire, error) { + if v == nil { + return nil, nil + } + return &bearerTokenAuthWire{ + Token: v.Token, + TokenPlaintext: v.TokenPlaintext, + }, nil +} + +func bearerTokenAuthFromWire(w *bearerTokenAuthWire) (*BearerTokenAuth, error) { + if w == nil { + return nil, nil + } + return &BearerTokenAuth{ + Token: w.Token, + TokenPlaintext: w.TokenPlaintext, + }, nil +} + +type cohereConfigWire struct { + CohereApiKey *string `json:"cohere_api_key,omitempty"` + CohereApiKeyPlaintext *string `json:"cohere_api_key_plaintext,omitempty"` + CohereApiBase *string `json:"cohere_api_base,omitempty"` +} + +func cohereConfigToWire(v *CohereConfig) (*cohereConfigWire, error) { + if v == nil { + return nil, nil + } + return &cohereConfigWire{ + CohereApiKey: v.CohereApiKey, + CohereApiKeyPlaintext: v.CohereApiKeyPlaintext, + CohereApiBase: v.CohereApiBase, + }, nil +} + +func cohereConfigFromWire(w *cohereConfigWire) (*CohereConfig, error) { + if w == nil { + return nil, nil + } + return &CohereConfig{ + CohereApiKey: w.CohereApiKey, + CohereApiKeyPlaintext: w.CohereApiKeyPlaintext, + CohereApiBase: w.CohereApiBase, + }, nil +} + +type createInferenceEndpointRequestWire struct { + Name *string `json:"name,omitempty"` + Config *endpointCoreConfigWire `json:"config,omitempty"` + Tags []endpointTagWire `json:"tags,omitempty"` + RouteOptimized *bool `json:"route_optimized,omitempty"` + RateLimits []rateLimitWire `json:"rate_limits,omitempty"` + AiGateway *aiGatewayConfigWire `json:"ai_gateway,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + EmailNotifications *emailNotificationsWire `json:"email_notifications,omitempty"` + Description *string `json:"description,omitempty"` + TelemetryConfig *telemetryConfigWire `json:"telemetry_config,omitempty"` +} + +func createInferenceEndpointRequestToWire(v *CreateInferenceEndpointRequest) (*createInferenceEndpointRequestWire, error) { + if v == nil { + return nil, nil + } + configWireValue, err := endpointCoreConfigToWire(v.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInferenceEndpointRequest.Config", err) + } + tagsWireValue, err := convertSlice(v.Tags, endpointTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInferenceEndpointRequest.Tags", err) + } + rateLimitsWireValue, err := convertSlice(v.RateLimits, rateLimitToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInferenceEndpointRequest.RateLimits", err) + } + aiGatewayWireValue, err := aiGatewayConfigToWire(v.AiGateway) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInferenceEndpointRequest.AiGateway", err) + } + emailNotificationsWireValue, err := emailNotificationsToWire(v.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInferenceEndpointRequest.EmailNotifications", err) + } + telemetryConfigWireValue, err := telemetryConfigToWire(v.TelemetryConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateInferenceEndpointRequest.TelemetryConfig", err) + } + return &createInferenceEndpointRequestWire{ + Name: v.Name, + Config: configWireValue, + Tags: tagsWireValue, + RouteOptimized: v.RouteOptimized, + RateLimits: rateLimitsWireValue, + AiGateway: aiGatewayWireValue, + BudgetPolicyId: v.BudgetPolicyId, + EmailNotifications: emailNotificationsWireValue, + Description: v.Description, + TelemetryConfig: telemetryConfigWireValue, + }, nil +} + +type createPtEndpointRequestWire struct { + Name *string `json:"name,omitempty"` + Config *ptEndpointCoreConfigWire `json:"config,omitempty"` + Tags []endpointTagWire `json:"tags,omitempty"` + AiGateway *aiGatewayConfigWire `json:"ai_gateway,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + EmailNotifications *emailNotificationsWire `json:"email_notifications,omitempty"` +} + +func createPtEndpointRequestToWire(v *CreatePtEndpointRequest) (*createPtEndpointRequestWire, error) { + if v == nil { + return nil, nil + } + configWireValue, err := ptEndpointCoreConfigToWire(v.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePtEndpointRequest.Config", err) + } + tagsWireValue, err := convertSlice(v.Tags, endpointTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePtEndpointRequest.Tags", err) + } + aiGatewayWireValue, err := aiGatewayConfigToWire(v.AiGateway) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePtEndpointRequest.AiGateway", err) + } + emailNotificationsWireValue, err := emailNotificationsToWire(v.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePtEndpointRequest.EmailNotifications", err) + } + return &createPtEndpointRequestWire{ + Name: v.Name, + Config: configWireValue, + Tags: tagsWireValue, + AiGateway: aiGatewayWireValue, + BudgetPolicyId: v.BudgetPolicyId, + EmailNotifications: emailNotificationsWireValue, + }, nil +} + +type customProviderConfigWire struct { + CustomProviderUrl *string `json:"custom_provider_url,omitempty"` + BearerTokenAuth *bearerTokenAuthWire `json:"bearer_token_auth,omitempty"` + ApiKeyAuth *apiKeyAuthWire `json:"api_key_auth,omitempty"` +} + +func customProviderConfigToWire(v *CustomProviderConfig) (*customProviderConfigWire, error) { + if v == nil { + return nil, nil + } + bearerTokenAuthWireValue, err := bearerTokenAuthToWire(v.BearerTokenAuth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomProviderConfig.BearerTokenAuth", err) + } + apiKeyAuthWireValue, err := apiKeyAuthToWire(v.ApiKeyAuth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomProviderConfig.ApiKeyAuth", err) + } + return &customProviderConfigWire{ + CustomProviderUrl: v.CustomProviderUrl, + BearerTokenAuth: bearerTokenAuthWireValue, + ApiKeyAuth: apiKeyAuthWireValue, + }, nil +} + +func customProviderConfigFromWire(w *customProviderConfigWire) (*CustomProviderConfig, error) { + if w == nil { + return nil, nil + } + bearerTokenAuthPublicValue, err := bearerTokenAuthFromWire(w.BearerTokenAuth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomProviderConfig.BearerTokenAuth", err) + } + apiKeyAuthPublicValue, err := apiKeyAuthFromWire(w.ApiKeyAuth) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomProviderConfig.ApiKeyAuth", err) + } + return &CustomProviderConfig{ + CustomProviderUrl: w.CustomProviderUrl, + BearerTokenAuth: bearerTokenAuthPublicValue, + ApiKeyAuth: apiKeyAuthPublicValue, + }, nil +} + +type dataPlaneInfoWire struct { + EndpointUrl *string `json:"endpoint_url,omitempty"` + AuthorizationDetails *string `json:"authorization_details,omitempty"` +} + +func dataPlaneInfoFromWire(w *dataPlaneInfoWire) (*DataPlaneInfo, error) { + if w == nil { + return nil, nil + } + return &DataPlaneInfo{ + EndpointUrl: w.EndpointUrl, + AuthorizationDetails: w.AuthorizationDetails, + }, nil +} + +type databricksModelServingConfigWire struct { + DatabricksApiToken *string `json:"databricks_api_token,omitempty"` + DatabricksWorkspaceUrl *string `json:"databricks_workspace_url,omitempty"` + DatabricksApiTokenPlaintext *string `json:"databricks_api_token_plaintext,omitempty"` +} + +func databricksModelServingConfigToWire(v *DatabricksModelServingConfig) (*databricksModelServingConfigWire, error) { + if v == nil { + return nil, nil + } + return &databricksModelServingConfigWire{ + DatabricksApiToken: v.DatabricksApiToken, + DatabricksWorkspaceUrl: v.DatabricksWorkspaceUrl, + DatabricksApiTokenPlaintext: v.DatabricksApiTokenPlaintext, + }, nil +} + +func databricksModelServingConfigFromWire(w *databricksModelServingConfigWire) (*DatabricksModelServingConfig, error) { + if w == nil { + return nil, nil + } + return &DatabricksModelServingConfig{ + DatabricksApiToken: w.DatabricksApiToken, + DatabricksWorkspaceUrl: w.DatabricksWorkspaceUrl, + DatabricksApiTokenPlaintext: w.DatabricksApiTokenPlaintext, + }, nil +} + +type emailNotificationsWire struct { + OnUpdateSuccess []string `json:"on_update_success,omitempty"` + OnUpdateFailure []string `json:"on_update_failure,omitempty"` +} + +func emailNotificationsToWire(v *EmailNotifications) (*emailNotificationsWire, error) { + if v == nil { + return nil, nil + } + return &emailNotificationsWire{ + OnUpdateSuccess: v.OnUpdateSuccess, + OnUpdateFailure: v.OnUpdateFailure, + }, nil +} + +func emailNotificationsFromWire(w *emailNotificationsWire) (*EmailNotifications, error) { + if w == nil { + return nil, nil + } + return &EmailNotifications{ + OnUpdateSuccess: w.OnUpdateSuccess, + OnUpdateFailure: w.OnUpdateFailure, + }, nil +} + +type endpointCoreConfigWire struct { + ServedEntities []servedModelWire `json:"served_entities,omitempty"` + ServedModels []servedModelWire `json:"served_models,omitempty"` + TrafficConfig *trafficConfigWire `json:"traffic_config,omitempty"` + AutoCaptureConfig *autoCaptureConfigWire `json:"auto_capture_config,omitempty"` +} + +func endpointCoreConfigToWire(v *EndpointCoreConfig) (*endpointCoreConfigWire, error) { + if v == nil { + return nil, nil + } + servedEntitiesWireValue, err := convertSlice(v.ServedEntities, servedModelToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointCoreConfig.ServedEntities", err) + } + servedModelsWireValue, err := convertSlice(v.ServedModels, servedModelToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointCoreConfig.ServedModels", err) + } + trafficConfigWireValue, err := trafficConfigToWire(v.TrafficConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointCoreConfig.TrafficConfig", err) + } + autoCaptureConfigWireValue, err := autoCaptureConfigToWire(v.AutoCaptureConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointCoreConfig.AutoCaptureConfig", err) + } + return &endpointCoreConfigWire{ + ServedEntities: servedEntitiesWireValue, + ServedModels: servedModelsWireValue, + TrafficConfig: trafficConfigWireValue, + AutoCaptureConfig: autoCaptureConfigWireValue, + }, nil +} + +type endpointCoreConfigOutputWire struct { + ConfigVersion *int64 `json:"config_version,omitempty"` + ServedEntities []servedModelWire `json:"served_entities,omitempty"` + ServedModels []servedModelWire `json:"served_models,omitempty"` + TrafficConfig *trafficConfigWire `json:"traffic_config,omitempty"` + AutoCaptureConfig *autoCaptureConfigWire `json:"auto_capture_config,omitempty"` +} + +func endpointCoreConfigOutputFromWire(w *endpointCoreConfigOutputWire) (*EndpointCoreConfigOutput, error) { + if w == nil { + return nil, nil + } + servedEntitiesPublicValue, err := convertSlice(w.ServedEntities, servedModelFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointCoreConfigOutput.ServedEntities", err) + } + servedModelsPublicValue, err := convertSlice(w.ServedModels, servedModelFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointCoreConfigOutput.ServedModels", err) + } + trafficConfigPublicValue, err := trafficConfigFromWire(w.TrafficConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointCoreConfigOutput.TrafficConfig", err) + } + autoCaptureConfigPublicValue, err := autoCaptureConfigFromWire(w.AutoCaptureConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointCoreConfigOutput.AutoCaptureConfig", err) + } + return &EndpointCoreConfigOutput{ + ConfigVersion: w.ConfigVersion, + ServedEntities: servedEntitiesPublicValue, + ServedModels: servedModelsPublicValue, + TrafficConfig: trafficConfigPublicValue, + AutoCaptureConfig: autoCaptureConfigPublicValue, + }, nil +} + +type endpointCoreConfigSummaryWire struct { + ServedEntities []servedModelLiteWire `json:"served_entities,omitempty"` + ServedModels []servedModelLiteWire `json:"served_models,omitempty"` +} + +func endpointCoreConfigSummaryFromWire(w *endpointCoreConfigSummaryWire) (*EndpointCoreConfigSummary, error) { + if w == nil { + return nil, nil + } + servedEntitiesPublicValue, err := convertSlice(w.ServedEntities, servedModelLiteFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointCoreConfigSummary.ServedEntities", err) + } + servedModelsPublicValue, err := convertSlice(w.ServedModels, servedModelLiteFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointCoreConfigSummary.ServedModels", err) + } + return &EndpointCoreConfigSummary{ + ServedEntities: servedEntitiesPublicValue, + ServedModels: servedModelsPublicValue, + }, nil +} + +type endpointTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func endpointTagToWire(v *EndpointTag) (*endpointTagWire, error) { + if v == nil { + return nil, nil + } + return &endpointTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func endpointTagFromWire(w *endpointTagWire) (*EndpointTag, error) { + if w == nil { + return nil, nil + } + return &EndpointTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type externalFunctionRequestWire struct { + ConnectionName *string `json:"connection_name,omitempty"` + Method ExternalFunctionRequest_HttpMethod `json:"method,omitempty"` + Path *string `json:"path,omitempty"` + Json *string `json:"json,omitempty"` + Headers *string `json:"headers,omitempty"` + Params *string `json:"params,omitempty"` + SubDomain *string `json:"sub_domain,omitempty"` +} + +func externalFunctionRequestToWire(v *ExternalFunctionRequest) (*externalFunctionRequestWire, error) { + if v == nil { + return nil, nil + } + return &externalFunctionRequestWire{ + ConnectionName: v.ConnectionName, + Method: v.Method, + Path: v.Path, + Json: v.Json, + Headers: v.Headers, + Params: v.Params, + SubDomain: v.SubDomain, + }, nil +} + +type externalModelWire struct { + Provider *string `json:"provider,omitempty"` + Name *string `json:"name,omitempty"` + Task *string `json:"task,omitempty"` + Ai21labsConfig *ai21LabsConfigWire `json:"ai21labs_config,omitempty"` + AnthropicConfig *anthropicConfigWire `json:"anthropic_config,omitempty"` + AmazonBedrockConfig *amazonBedrockConfigWire `json:"amazon_bedrock_config,omitempty"` + CohereConfig *cohereConfigWire `json:"cohere_config,omitempty"` + GoogleCloudVertexAiConfig *googleCloudVertexAiConfigWire `json:"google_cloud_vertex_ai_config,omitempty"` + DatabricksModelServingConfig *databricksModelServingConfigWire `json:"databricks_model_serving_config,omitempty"` + OpenaiConfig *openAiConfigWire `json:"openai_config,omitempty"` + PalmConfig *paLmConfigWire `json:"palm_config,omitempty"` + CustomProviderConfig *customProviderConfigWire `json:"custom_provider_config,omitempty"` +} + +func externalModelToWire(v *ExternalModel) (*externalModelWire, error) { + if v == nil { + return nil, nil + } + var configAi21labsConfigWire *ai21LabsConfigWire + var configAnthropicConfigWire *anthropicConfigWire + var configAmazonBedrockConfigWire *amazonBedrockConfigWire + var configCohereConfigWire *cohereConfigWire + var configGoogleCloudVertexAiConfigWire *googleCloudVertexAiConfigWire + var configDatabricksModelServingConfigWire *databricksModelServingConfigWire + var configOpenaiConfigWire *openAiConfigWire + var configPalmConfigWire *paLmConfigWire + var configCustomProviderConfigWire *customProviderConfigWire + switch value := v.Config.(type) { + case nil: + case *ExternalModel_Config_Ai21labsConfig: + if value != nil { + configAi21labsConfigConverted, err := ai21LabsConfigToWire(&value.Ai21labsConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.Ai21labsConfig", err) + } + configAi21labsConfigWire = configAi21labsConfigConverted + } + case *ExternalModel_Config_AnthropicConfig: + if value != nil { + configAnthropicConfigConverted, err := anthropicConfigToWire(&value.AnthropicConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.AnthropicConfig", err) + } + configAnthropicConfigWire = configAnthropicConfigConverted + } + case *ExternalModel_Config_AmazonBedrockConfig: + if value != nil { + configAmazonBedrockConfigConverted, err := amazonBedrockConfigToWire(&value.AmazonBedrockConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.AmazonBedrockConfig", err) + } + configAmazonBedrockConfigWire = configAmazonBedrockConfigConverted + } + case *ExternalModel_Config_CohereConfig: + if value != nil { + configCohereConfigConverted, err := cohereConfigToWire(&value.CohereConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.CohereConfig", err) + } + configCohereConfigWire = configCohereConfigConverted + } + case *ExternalModel_Config_GoogleCloudVertexAiConfig: + if value != nil { + configGoogleCloudVertexAiConfigConverted, err := googleCloudVertexAiConfigToWire(&value.GoogleCloudVertexAiConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.GoogleCloudVertexAiConfig", err) + } + configGoogleCloudVertexAiConfigWire = configGoogleCloudVertexAiConfigConverted + } + case *ExternalModel_Config_DatabricksModelServingConfig: + if value != nil { + configDatabricksModelServingConfigConverted, err := databricksModelServingConfigToWire(&value.DatabricksModelServingConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.DatabricksModelServingConfig", err) + } + configDatabricksModelServingConfigWire = configDatabricksModelServingConfigConverted + } + case *ExternalModel_Config_OpenaiConfig: + if value != nil { + configOpenaiConfigConverted, err := openAiConfigToWire(&value.OpenaiConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.OpenaiConfig", err) + } + configOpenaiConfigWire = configOpenaiConfigConverted + } + case *ExternalModel_Config_PalmConfig: + if value != nil { + configPalmConfigConverted, err := paLmConfigToWire(&value.PalmConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.PalmConfig", err) + } + configPalmConfigWire = configPalmConfigConverted + } + case *ExternalModel_Config_CustomProviderConfig: + if value != nil { + configCustomProviderConfigConverted, err := customProviderConfigToWire(&value.CustomProviderConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.CustomProviderConfig", err) + } + configCustomProviderConfigWire = configCustomProviderConfigConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ExternalModel.Config", value) + } + return &externalModelWire{ + Provider: v.Provider, + Name: v.Name, + Task: v.Task, + Ai21labsConfig: configAi21labsConfigWire, + AnthropicConfig: configAnthropicConfigWire, + AmazonBedrockConfig: configAmazonBedrockConfigWire, + CohereConfig: configCohereConfigWire, + GoogleCloudVertexAiConfig: configGoogleCloudVertexAiConfigWire, + DatabricksModelServingConfig: configDatabricksModelServingConfigWire, + OpenaiConfig: configOpenaiConfigWire, + PalmConfig: configPalmConfigWire, + CustomProviderConfig: configCustomProviderConfigWire, + }, nil +} + +func externalModelFromWire(w *externalModelWire) (*ExternalModel, error) { + if w == nil { + return nil, nil + } + configMembers := 0 + if w.Ai21labsConfig != nil { + configMembers++ + } + if w.AnthropicConfig != nil { + configMembers++ + } + if w.AmazonBedrockConfig != nil { + configMembers++ + } + if w.CohereConfig != nil { + configMembers++ + } + if w.GoogleCloudVertexAiConfig != nil { + configMembers++ + } + if w.DatabricksModelServingConfig != nil { + configMembers++ + } + if w.OpenaiConfig != nil { + configMembers++ + } + if w.PalmConfig != nil { + configMembers++ + } + if w.CustomProviderConfig != nil { + configMembers++ + } + if configMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ExternalModel.Config") + } + var configSelection isExternalModel_Config + switch { + case w.Ai21labsConfig != nil: + configAi21labsConfigConverted, err := ai21LabsConfigFromWire(w.Ai21labsConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.Ai21labsConfig", err) + } + configSelection = &ExternalModel_Config_Ai21labsConfig{Ai21labsConfig: *configAi21labsConfigConverted} + case w.AnthropicConfig != nil: + configAnthropicConfigConverted, err := anthropicConfigFromWire(w.AnthropicConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.AnthropicConfig", err) + } + configSelection = &ExternalModel_Config_AnthropicConfig{AnthropicConfig: *configAnthropicConfigConverted} + case w.AmazonBedrockConfig != nil: + configAmazonBedrockConfigConverted, err := amazonBedrockConfigFromWire(w.AmazonBedrockConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.AmazonBedrockConfig", err) + } + configSelection = &ExternalModel_Config_AmazonBedrockConfig{AmazonBedrockConfig: *configAmazonBedrockConfigConverted} + case w.CohereConfig != nil: + configCohereConfigConverted, err := cohereConfigFromWire(w.CohereConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.CohereConfig", err) + } + configSelection = &ExternalModel_Config_CohereConfig{CohereConfig: *configCohereConfigConverted} + case w.GoogleCloudVertexAiConfig != nil: + configGoogleCloudVertexAiConfigConverted, err := googleCloudVertexAiConfigFromWire(w.GoogleCloudVertexAiConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.GoogleCloudVertexAiConfig", err) + } + configSelection = &ExternalModel_Config_GoogleCloudVertexAiConfig{GoogleCloudVertexAiConfig: *configGoogleCloudVertexAiConfigConverted} + case w.DatabricksModelServingConfig != nil: + configDatabricksModelServingConfigConverted, err := databricksModelServingConfigFromWire(w.DatabricksModelServingConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.DatabricksModelServingConfig", err) + } + configSelection = &ExternalModel_Config_DatabricksModelServingConfig{DatabricksModelServingConfig: *configDatabricksModelServingConfigConverted} + case w.OpenaiConfig != nil: + configOpenaiConfigConverted, err := openAiConfigFromWire(w.OpenaiConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.OpenaiConfig", err) + } + configSelection = &ExternalModel_Config_OpenaiConfig{OpenaiConfig: *configOpenaiConfigConverted} + case w.PalmConfig != nil: + configPalmConfigConverted, err := paLmConfigFromWire(w.PalmConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.PalmConfig", err) + } + configSelection = &ExternalModel_Config_PalmConfig{PalmConfig: *configPalmConfigConverted} + case w.CustomProviderConfig != nil: + configCustomProviderConfigConverted, err := customProviderConfigFromWire(w.CustomProviderConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalModel.Config.CustomProviderConfig", err) + } + configSelection = &ExternalModel_Config_CustomProviderConfig{CustomProviderConfig: *configCustomProviderConfigConverted} + } + return &ExternalModel{ + Provider: w.Provider, + Name: w.Name, + Task: w.Task, + Config: configSelection, + }, nil +} + +type fallbackConfigWire struct { + Enabled *bool `json:"enabled,omitempty"` +} + +func fallbackConfigToWire(v *FallbackConfig) (*fallbackConfigWire, error) { + if v == nil { + return nil, nil + } + return &fallbackConfigWire{ + Enabled: v.Enabled, + }, nil +} + +func fallbackConfigFromWire(w *fallbackConfigWire) (*FallbackConfig, error) { + if w == nil { + return nil, nil + } + return &FallbackConfig{ + Enabled: w.Enabled, + }, nil +} + +type foundationModelWire struct { + Name *string `json:"name,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Docs *string `json:"docs,omitempty"` + Description *string `json:"description,omitempty"` +} + +func foundationModelToWire(v *FoundationModel) (*foundationModelWire, error) { + if v == nil { + return nil, nil + } + return &foundationModelWire{ + Name: v.Name, + DisplayName: v.DisplayName, + Docs: v.Docs, + Description: v.Description, + }, nil +} + +func foundationModelFromWire(w *foundationModelWire) (*FoundationModel, error) { + if w == nil { + return nil, nil + } + return &FoundationModel{ + Name: w.Name, + DisplayName: w.DisplayName, + Docs: w.Docs, + Description: w.Description, + }, nil +} + +type getServedModelBuildLogsResponseWire struct { + Logs *string `json:"logs,omitempty"` +} + +func getServedModelBuildLogsResponseFromWire(w *getServedModelBuildLogsResponseWire) (*GetServedModelBuildLogsResponse, error) { + if w == nil { + return nil, nil + } + return &GetServedModelBuildLogsResponse{ + Logs: w.Logs, + }, nil +} + +type getServedModelLogsResponseWire struct { + Logs *string `json:"logs,omitempty"` +} + +func getServedModelLogsResponseFromWire(w *getServedModelLogsResponseWire) (*GetServedModelLogsResponse, error) { + if w == nil { + return nil, nil + } + return &GetServedModelLogsResponse{ + Logs: w.Logs, + }, nil +} + +type googleCloudVertexAiConfigWire struct { + PrivateKey *string `json:"private_key,omitempty"` + ProjectId *string `json:"project_id,omitempty"` + Region *string `json:"region,omitempty"` + PrivateKeyPlaintext *string `json:"private_key_plaintext,omitempty"` +} + +func googleCloudVertexAiConfigToWire(v *GoogleCloudVertexAiConfig) (*googleCloudVertexAiConfigWire, error) { + if v == nil { + return nil, nil + } + return &googleCloudVertexAiConfigWire{ + PrivateKey: v.PrivateKey, + ProjectId: v.ProjectId, + Region: v.Region, + PrivateKeyPlaintext: v.PrivateKeyPlaintext, + }, nil +} + +func googleCloudVertexAiConfigFromWire(w *googleCloudVertexAiConfigWire) (*GoogleCloudVertexAiConfig, error) { + if w == nil { + return nil, nil + } + return &GoogleCloudVertexAiConfig{ + PrivateKey: w.PrivateKey, + ProjectId: w.ProjectId, + Region: w.Region, + PrivateKeyPlaintext: w.PrivateKeyPlaintext, + }, nil +} + +type inferenceEndpointWire struct { + Name *string `json:"name,omitempty"` + Creator *string `json:"creator,omitempty"` + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + State *inferenceEndpointStateWire `json:"state,omitempty"` + Config *endpointCoreConfigSummaryWire `json:"config,omitempty"` + Tags []endpointTagWire `json:"tags,omitempty"` + Id *string `json:"id,omitempty"` + Task *string `json:"task,omitempty"` + AiGateway *aiGatewayConfigWire `json:"ai_gateway,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + Description *string `json:"description,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + TelemetryConfig *telemetryConfigWire `json:"telemetry_config,omitempty"` +} + +func inferenceEndpointFromWire(w *inferenceEndpointWire) (*InferenceEndpoint, error) { + if w == nil { + return nil, nil + } + statePublicValue, err := inferenceEndpointStateFromWire(w.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpoint.State", err) + } + configPublicValue, err := endpointCoreConfigSummaryFromWire(w.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpoint.Config", err) + } + tagsPublicValue, err := convertSlice(w.Tags, endpointTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpoint.Tags", err) + } + aiGatewayPublicValue, err := aiGatewayConfigFromWire(w.AiGateway) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpoint.AiGateway", err) + } + telemetryConfigPublicValue, err := telemetryConfigFromWire(w.TelemetryConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpoint.TelemetryConfig", err) + } + return &InferenceEndpoint{ + Name: w.Name, + Creator: w.Creator, + CreationTimestamp: w.CreationTimestamp, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + State: statePublicValue, + Config: configPublicValue, + Tags: tagsPublicValue, + Id: w.Id, + Task: w.Task, + AiGateway: aiGatewayPublicValue, + BudgetPolicyId: w.BudgetPolicyId, + Description: w.Description, + UsagePolicyId: w.UsagePolicyId, + TelemetryConfig: telemetryConfigPublicValue, + }, nil +} + +type inferenceEndpointDetailedWire struct { + Name *string `json:"name,omitempty"` + Creator *string `json:"creator,omitempty"` + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + State *inferenceEndpointStateWire `json:"state,omitempty"` + Config *endpointCoreConfigOutputWire `json:"config,omitempty"` + PendingConfig *pendingConfigWire `json:"pending_config,omitempty"` + Id *string `json:"id,omitempty"` + PermissionLevel ServingEndpointDetailedPermissionLevel `json:"permission_level,omitempty"` + Tags []endpointTagWire `json:"tags,omitempty"` + Task *string `json:"task,omitempty"` + RouteOptimized *bool `json:"route_optimized,omitempty"` + EndpointUrl *string `json:"endpoint_url,omitempty"` + DataPlaneInfo *modelDataPlaneInfoWire `json:"data_plane_info,omitempty"` + AiGateway *aiGatewayConfigWire `json:"ai_gateway,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + EmailNotifications *emailNotificationsWire `json:"email_notifications,omitempty"` + Description *string `json:"description,omitempty"` + TelemetryConfig *telemetryConfigWire `json:"telemetry_config,omitempty"` +} + +func inferenceEndpointDetailedFromWire(w *inferenceEndpointDetailedWire) (*InferenceEndpointDetailed, error) { + if w == nil { + return nil, nil + } + statePublicValue, err := inferenceEndpointStateFromWire(w.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpointDetailed.State", err) + } + configPublicValue, err := endpointCoreConfigOutputFromWire(w.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpointDetailed.Config", err) + } + pendingConfigPublicValue, err := pendingConfigFromWire(w.PendingConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpointDetailed.PendingConfig", err) + } + tagsPublicValue, err := convertSlice(w.Tags, endpointTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpointDetailed.Tags", err) + } + dataPlaneInfoPublicValue, err := modelDataPlaneInfoFromWire(w.DataPlaneInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpointDetailed.DataPlaneInfo", err) + } + aiGatewayPublicValue, err := aiGatewayConfigFromWire(w.AiGateway) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpointDetailed.AiGateway", err) + } + emailNotificationsPublicValue, err := emailNotificationsFromWire(w.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpointDetailed.EmailNotifications", err) + } + telemetryConfigPublicValue, err := telemetryConfigFromWire(w.TelemetryConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InferenceEndpointDetailed.TelemetryConfig", err) + } + return &InferenceEndpointDetailed{ + Name: w.Name, + Creator: w.Creator, + CreationTimestamp: w.CreationTimestamp, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + State: statePublicValue, + Config: configPublicValue, + PendingConfig: pendingConfigPublicValue, + Id: w.Id, + PermissionLevel: w.PermissionLevel, + Tags: tagsPublicValue, + Task: w.Task, + RouteOptimized: w.RouteOptimized, + EndpointUrl: w.EndpointUrl, + DataPlaneInfo: dataPlaneInfoPublicValue, + AiGateway: aiGatewayPublicValue, + BudgetPolicyId: w.BudgetPolicyId, + EmailNotifications: emailNotificationsPublicValue, + Description: w.Description, + TelemetryConfig: telemetryConfigPublicValue, + }, nil +} + +type inferenceEndpointStateWire struct { + Ready InferenceEndpointState_ReadyState `json:"ready,omitempty"` + ConfigUpdate InferenceEndpointState_ConfigUpdateState `json:"config_update,omitempty"` +} + +func inferenceEndpointStateFromWire(w *inferenceEndpointStateWire) (*InferenceEndpointState, error) { + if w == nil { + return nil, nil + } + return &InferenceEndpointState{ + Ready: w.Ready, + ConfigUpdate: w.ConfigUpdate, + }, nil +} + +type inferenceTableConfigWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + TableNamePrefix *string `json:"table_name_prefix,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func inferenceTableConfigToWire(v *InferenceTableConfig) (*inferenceTableConfigWire, error) { + if v == nil { + return nil, nil + } + return &inferenceTableConfigWire{ + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + TableNamePrefix: v.TableNamePrefix, + Enabled: v.Enabled, + }, nil +} + +func inferenceTableConfigFromWire(w *inferenceTableConfigWire) (*InferenceTableConfig, error) { + if w == nil { + return nil, nil + } + return &InferenceTableConfig{ + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + TableNamePrefix: w.TableNamePrefix, + Enabled: w.Enabled, + }, nil +} + +type listInferenceEndpointsResponseWire struct { + Endpoints []inferenceEndpointWire `json:"endpoints,omitempty"` +} + +func listInferenceEndpointsResponseFromWire(w *listInferenceEndpointsResponseWire) (*ListInferenceEndpointsResponse, error) { + if w == nil { + return nil, nil + } + endpointsPublicValue, err := convertSlice(w.Endpoints, inferenceEndpointFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListInferenceEndpointsResponse.Endpoints", err) + } + return &ListInferenceEndpointsResponse{ + Endpoints: endpointsPublicValue, + }, nil +} + +type modelDataPlaneInfoWire struct { + QueryInfo *dataPlaneInfoWire `json:"query_info,omitempty"` +} + +func modelDataPlaneInfoFromWire(w *modelDataPlaneInfoWire) (*ModelDataPlaneInfo, error) { + if w == nil { + return nil, nil + } + queryInfoPublicValue, err := dataPlaneInfoFromWire(w.QueryInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelDataPlaneInfo.QueryInfo", err) + } + return &ModelDataPlaneInfo{ + QueryInfo: queryInfoPublicValue, + }, nil +} + +type openAiConfigWire struct { + OpenaiApiKey *string `json:"openai_api_key,omitempty"` + OpenaiApiType *string `json:"openai_api_type,omitempty"` + OpenaiApiBase *string `json:"openai_api_base,omitempty"` + OpenaiApiVersion *string `json:"openai_api_version,omitempty"` + OpenaiDeploymentName *string `json:"openai_deployment_name,omitempty"` + OpenaiOrganization *string `json:"openai_organization,omitempty"` + MicrosoftEntraTenantId *string `json:"microsoft_entra_tenant_id,omitempty"` + MicrosoftEntraClientId *string `json:"microsoft_entra_client_id,omitempty"` + MicrosoftEntraClientSecret *string `json:"microsoft_entra_client_secret,omitempty"` + OpenaiApiKeyPlaintext *string `json:"openai_api_key_plaintext,omitempty"` + MicrosoftEntraClientSecretPlaintext *string `json:"microsoft_entra_client_secret_plaintext,omitempty"` +} + +func openAiConfigToWire(v *OpenAiConfig) (*openAiConfigWire, error) { + if v == nil { + return nil, nil + } + return &openAiConfigWire{ + OpenaiApiKey: v.OpenaiApiKey, + OpenaiApiType: v.OpenaiApiType, + OpenaiApiBase: v.OpenaiApiBase, + OpenaiApiVersion: v.OpenaiApiVersion, + OpenaiDeploymentName: v.OpenaiDeploymentName, + OpenaiOrganization: v.OpenaiOrganization, + MicrosoftEntraTenantId: v.MicrosoftEntraTenantId, + MicrosoftEntraClientId: v.MicrosoftEntraClientId, + MicrosoftEntraClientSecret: v.MicrosoftEntraClientSecret, + OpenaiApiKeyPlaintext: v.OpenaiApiKeyPlaintext, + MicrosoftEntraClientSecretPlaintext: v.MicrosoftEntraClientSecretPlaintext, + }, nil +} + +func openAiConfigFromWire(w *openAiConfigWire) (*OpenAiConfig, error) { + if w == nil { + return nil, nil + } + return &OpenAiConfig{ + OpenaiApiKey: w.OpenaiApiKey, + OpenaiApiType: w.OpenaiApiType, + OpenaiApiBase: w.OpenaiApiBase, + OpenaiApiVersion: w.OpenaiApiVersion, + OpenaiDeploymentName: w.OpenaiDeploymentName, + OpenaiOrganization: w.OpenaiOrganization, + MicrosoftEntraTenantId: w.MicrosoftEntraTenantId, + MicrosoftEntraClientId: w.MicrosoftEntraClientId, + MicrosoftEntraClientSecret: w.MicrosoftEntraClientSecret, + OpenaiApiKeyPlaintext: w.OpenaiApiKeyPlaintext, + MicrosoftEntraClientSecretPlaintext: w.MicrosoftEntraClientSecretPlaintext, + }, nil +} + +type paLmConfigWire struct { + PalmApiKey *string `json:"palm_api_key,omitempty"` + PalmApiKeyPlaintext *string `json:"palm_api_key_plaintext,omitempty"` +} + +func paLmConfigToWire(v *PaLmConfig) (*paLmConfigWire, error) { + if v == nil { + return nil, nil + } + return &paLmConfigWire{ + PalmApiKey: v.PalmApiKey, + PalmApiKeyPlaintext: v.PalmApiKeyPlaintext, + }, nil +} + +func paLmConfigFromWire(w *paLmConfigWire) (*PaLmConfig, error) { + if w == nil { + return nil, nil + } + return &PaLmConfig{ + PalmApiKey: w.PalmApiKey, + PalmApiKeyPlaintext: w.PalmApiKeyPlaintext, + }, nil +} + +type patchInferenceEndpointTagsRequestWire struct { + Name *string `json:"name,omitempty"` + AddTags []endpointTagWire `json:"add_tags,omitempty"` + DeleteTags []string `json:"delete_tags,omitempty"` +} + +func patchInferenceEndpointTagsRequestToWire(v *PatchInferenceEndpointTagsRequest) (*patchInferenceEndpointTagsRequestWire, error) { + if v == nil { + return nil, nil + } + addTagsWireValue, err := convertSlice(v.AddTags, endpointTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchInferenceEndpointTagsRequest.AddTags", err) + } + return &patchInferenceEndpointTagsRequestWire{ + Name: v.Name, + AddTags: addTagsWireValue, + DeleteTags: v.DeleteTags, + }, nil +} + +type patchInferenceEndpointTagsResponseWire struct { + Tags []endpointTagWire `json:"tags,omitempty"` +} + +func patchInferenceEndpointTagsResponseFromWire(w *patchInferenceEndpointTagsResponseWire) (*PatchInferenceEndpointTagsResponse, error) { + if w == nil { + return nil, nil + } + tagsPublicValue, err := convertSlice(w.Tags, endpointTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchInferenceEndpointTagsResponse.Tags", err) + } + return &PatchInferenceEndpointTagsResponse{ + Tags: tagsPublicValue, + }, nil +} + +type patchInferenceEndpointTelemetryConfigRequestWire struct { + Name *string `json:"name,omitempty"` + TelemetryConfig *telemetryConfigWire `json:"telemetry_config,omitempty"` +} + +func patchInferenceEndpointTelemetryConfigRequestToWire(v *PatchInferenceEndpointTelemetryConfigRequest) (*patchInferenceEndpointTelemetryConfigRequestWire, error) { + if v == nil { + return nil, nil + } + telemetryConfigWireValue, err := telemetryConfigToWire(v.TelemetryConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchInferenceEndpointTelemetryConfigRequest.TelemetryConfig", err) + } + return &patchInferenceEndpointTelemetryConfigRequestWire{ + Name: v.Name, + TelemetryConfig: telemetryConfigWireValue, + }, nil +} + +type payloadTableWire struct { + Name *string `json:"name,omitempty"` + Status *string `json:"status,omitempty"` + StatusMessage *string `json:"status_message,omitempty"` +} + +func payloadTableToWire(v *PayloadTable) (*payloadTableWire, error) { + if v == nil { + return nil, nil + } + return &payloadTableWire{ + Name: v.Name, + Status: v.Status, + StatusMessage: v.StatusMessage, + }, nil +} + +func payloadTableFromWire(w *payloadTableWire) (*PayloadTable, error) { + if w == nil { + return nil, nil + } + return &PayloadTable{ + Name: w.Name, + Status: w.Status, + StatusMessage: w.StatusMessage, + }, nil +} + +type pendingConfigWire struct { + ServedEntities []servedModelWire `json:"served_entities,omitempty"` + ServedModels []servedModelWire `json:"served_models,omitempty"` + TrafficConfig *trafficConfigWire `json:"traffic_config,omitempty"` + ConfigVersion *int `json:"config_version,omitempty"` + StartTime *int64 `json:"start_time,omitempty"` + AutoCaptureConfig *autoCaptureConfigWire `json:"auto_capture_config,omitempty"` +} + +func pendingConfigFromWire(w *pendingConfigWire) (*PendingConfig, error) { + if w == nil { + return nil, nil + } + servedEntitiesPublicValue, err := convertSlice(w.ServedEntities, servedModelFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PendingConfig.ServedEntities", err) + } + servedModelsPublicValue, err := convertSlice(w.ServedModels, servedModelFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PendingConfig.ServedModels", err) + } + trafficConfigPublicValue, err := trafficConfigFromWire(w.TrafficConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PendingConfig.TrafficConfig", err) + } + autoCaptureConfigPublicValue, err := autoCaptureConfigFromWire(w.AutoCaptureConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PendingConfig.AutoCaptureConfig", err) + } + return &PendingConfig{ + ServedEntities: servedEntitiesPublicValue, + ServedModels: servedModelsPublicValue, + TrafficConfig: trafficConfigPublicValue, + ConfigVersion: w.ConfigVersion, + StartTime: w.StartTime, + AutoCaptureConfig: autoCaptureConfigPublicValue, + }, nil +} + +type piiSettingsWire struct { + Behavior Behavior `json:"behavior,omitempty"` +} + +func piiSettingsToWire(v *PiiSettings) (*piiSettingsWire, error) { + if v == nil { + return nil, nil + } + return &piiSettingsWire{ + Behavior: v.Behavior, + }, nil +} + +func piiSettingsFromWire(w *piiSettingsWire) (*PiiSettings, error) { + if w == nil { + return nil, nil + } + return &PiiSettings{ + Behavior: w.Behavior, + }, nil +} + +type ptEndpointCoreConfigWire struct { + ServedEntities []ptServedModelWire `json:"served_entities,omitempty"` + TrafficConfig *trafficConfigWire `json:"traffic_config,omitempty"` +} + +func ptEndpointCoreConfigToWire(v *PtEndpointCoreConfig) (*ptEndpointCoreConfigWire, error) { + if v == nil { + return nil, nil + } + servedEntitiesWireValue, err := convertSlice(v.ServedEntities, ptServedModelToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PtEndpointCoreConfig.ServedEntities", err) + } + trafficConfigWireValue, err := trafficConfigToWire(v.TrafficConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PtEndpointCoreConfig.TrafficConfig", err) + } + return &ptEndpointCoreConfigWire{ + ServedEntities: servedEntitiesWireValue, + TrafficConfig: trafficConfigWireValue, + }, nil +} + +type ptServedModelWire struct { + Name *string `json:"name,omitempty"` + EntityName *string `json:"entity_name,omitempty"` + EntityVersion *string `json:"entity_version,omitempty"` + ProvisionedModelUnits *int64 `json:"provisioned_model_units,omitempty"` + BurstScalingEnabled *bool `json:"burst_scaling_enabled,omitempty"` +} + +func ptServedModelToWire(v *PtServedModel) (*ptServedModelWire, error) { + if v == nil { + return nil, nil + } + return &ptServedModelWire{ + Name: v.Name, + EntityName: v.EntityName, + EntityVersion: v.EntityVersion, + ProvisionedModelUnits: v.ProvisionedModelUnits, + BurstScalingEnabled: v.BurstScalingEnabled, + }, nil +} + +type putInferenceEndpointAiGatewayRequestWire struct { + Name *string `json:"name,omitempty"` + UsageTrackingConfig *usageTrackingConfigWire `json:"usage_tracking_config,omitempty"` + InferenceTableConfig *inferenceTableConfigWire `json:"inference_table_config,omitempty"` + RateLimits []aiGatewayRateLimitWire `json:"rate_limits,omitempty"` + Guardrails *aiGuardrailsWire `json:"guardrails,omitempty"` + FallbackConfig *fallbackConfigWire `json:"fallback_config,omitempty"` +} + +func putInferenceEndpointAiGatewayRequestToWire(v *PutInferenceEndpointAiGatewayRequest) (*putInferenceEndpointAiGatewayRequestWire, error) { + if v == nil { + return nil, nil + } + usageTrackingConfigWireValue, err := usageTrackingConfigToWire(v.UsageTrackingConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointAiGatewayRequest.UsageTrackingConfig", err) + } + inferenceTableConfigWireValue, err := inferenceTableConfigToWire(v.InferenceTableConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointAiGatewayRequest.InferenceTableConfig", err) + } + rateLimitsWireValue, err := convertSlice(v.RateLimits, aiGatewayRateLimitToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointAiGatewayRequest.RateLimits", err) + } + guardrailsWireValue, err := aiGuardrailsToWire(v.Guardrails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointAiGatewayRequest.Guardrails", err) + } + fallbackConfigWireValue, err := fallbackConfigToWire(v.FallbackConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointAiGatewayRequest.FallbackConfig", err) + } + return &putInferenceEndpointAiGatewayRequestWire{ + Name: v.Name, + UsageTrackingConfig: usageTrackingConfigWireValue, + InferenceTableConfig: inferenceTableConfigWireValue, + RateLimits: rateLimitsWireValue, + Guardrails: guardrailsWireValue, + FallbackConfig: fallbackConfigWireValue, + }, nil +} + +type putInferenceEndpointAiGatewayResponseWire struct { + UsageTrackingConfig *usageTrackingConfigWire `json:"usage_tracking_config,omitempty"` + InferenceTableConfig *inferenceTableConfigWire `json:"inference_table_config,omitempty"` + RateLimits []aiGatewayRateLimitWire `json:"rate_limits,omitempty"` + Guardrails *aiGuardrailsWire `json:"guardrails,omitempty"` + FallbackConfig *fallbackConfigWire `json:"fallback_config,omitempty"` +} + +func putInferenceEndpointAiGatewayResponseFromWire(w *putInferenceEndpointAiGatewayResponseWire) (*PutInferenceEndpointAiGatewayResponse, error) { + if w == nil { + return nil, nil + } + usageTrackingConfigPublicValue, err := usageTrackingConfigFromWire(w.UsageTrackingConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointAiGatewayResponse.UsageTrackingConfig", err) + } + inferenceTableConfigPublicValue, err := inferenceTableConfigFromWire(w.InferenceTableConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointAiGatewayResponse.InferenceTableConfig", err) + } + rateLimitsPublicValue, err := convertSlice(w.RateLimits, aiGatewayRateLimitFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointAiGatewayResponse.RateLimits", err) + } + guardrailsPublicValue, err := aiGuardrailsFromWire(w.Guardrails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointAiGatewayResponse.Guardrails", err) + } + fallbackConfigPublicValue, err := fallbackConfigFromWire(w.FallbackConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointAiGatewayResponse.FallbackConfig", err) + } + return &PutInferenceEndpointAiGatewayResponse{ + UsageTrackingConfig: usageTrackingConfigPublicValue, + InferenceTableConfig: inferenceTableConfigPublicValue, + RateLimits: rateLimitsPublicValue, + Guardrails: guardrailsPublicValue, + FallbackConfig: fallbackConfigPublicValue, + }, nil +} + +type putInferenceEndpointConfigRequestWire struct { + Name *string `json:"name,omitempty"` + ServedEntities []servedModelWire `json:"served_entities,omitempty"` + ServedModels []servedModelWire `json:"served_models,omitempty"` + TrafficConfig *trafficConfigWire `json:"traffic_config,omitempty"` + AutoCaptureConfig *autoCaptureConfigWire `json:"auto_capture_config,omitempty"` +} + +func putInferenceEndpointConfigRequestToWire(v *PutInferenceEndpointConfigRequest) (*putInferenceEndpointConfigRequestWire, error) { + if v == nil { + return nil, nil + } + servedEntitiesWireValue, err := convertSlice(v.ServedEntities, servedModelToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointConfigRequest.ServedEntities", err) + } + servedModelsWireValue, err := convertSlice(v.ServedModels, servedModelToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointConfigRequest.ServedModels", err) + } + trafficConfigWireValue, err := trafficConfigToWire(v.TrafficConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointConfigRequest.TrafficConfig", err) + } + autoCaptureConfigWireValue, err := autoCaptureConfigToWire(v.AutoCaptureConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointConfigRequest.AutoCaptureConfig", err) + } + return &putInferenceEndpointConfigRequestWire{ + Name: v.Name, + ServedEntities: servedEntitiesWireValue, + ServedModels: servedModelsWireValue, + TrafficConfig: trafficConfigWireValue, + AutoCaptureConfig: autoCaptureConfigWireValue, + }, nil +} + +type putInferenceEndpointRateLimitsRequestWire struct { + Name *string `json:"name,omitempty"` + RateLimits []rateLimitWire `json:"rate_limits,omitempty"` +} + +func putInferenceEndpointRateLimitsRequestToWire(v *PutInferenceEndpointRateLimitsRequest) (*putInferenceEndpointRateLimitsRequestWire, error) { + if v == nil { + return nil, nil + } + rateLimitsWireValue, err := convertSlice(v.RateLimits, rateLimitToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointRateLimitsRequest.RateLimits", err) + } + return &putInferenceEndpointRateLimitsRequestWire{ + Name: v.Name, + RateLimits: rateLimitsWireValue, + }, nil +} + +type putInferenceEndpointRateLimitsResponseWire struct { + RateLimits []rateLimitWire `json:"rate_limits,omitempty"` +} + +func putInferenceEndpointRateLimitsResponseFromWire(w *putInferenceEndpointRateLimitsResponseWire) (*PutInferenceEndpointRateLimitsResponse, error) { + if w == nil { + return nil, nil + } + rateLimitsPublicValue, err := convertSlice(w.RateLimits, rateLimitFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutInferenceEndpointRateLimitsResponse.RateLimits", err) + } + return &PutInferenceEndpointRateLimitsResponse{ + RateLimits: rateLimitsPublicValue, + }, nil +} + +type putPtEndpointConfigRequestWire struct { + Name *string `json:"name,omitempty"` + Config *ptEndpointCoreConfigWire `json:"config,omitempty"` +} + +func putPtEndpointConfigRequestToWire(v *PutPtEndpointConfigRequest) (*putPtEndpointConfigRequestWire, error) { + if v == nil { + return nil, nil + } + configWireValue, err := ptEndpointCoreConfigToWire(v.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PutPtEndpointConfigRequest.Config", err) + } + return &putPtEndpointConfigRequestWire{ + Name: v.Name, + Config: configWireValue, + }, nil +} + +type rateLimitWire struct { + Calls *int64 `json:"calls,omitempty"` + Key *string `json:"key,omitempty"` + RenewalPeriod *string `json:"renewal_period,omitempty"` +} + +func rateLimitToWire(v *RateLimit) (*rateLimitWire, error) { + if v == nil { + return nil, nil + } + return &rateLimitWire{ + Calls: v.Calls, + Key: v.Key, + RenewalPeriod: v.RenewalPeriod, + }, nil +} + +func rateLimitFromWire(w *rateLimitWire) (*RateLimit, error) { + if w == nil { + return nil, nil + } + return &RateLimit{ + Calls: w.Calls, + Key: w.Key, + RenewalPeriod: w.RenewalPeriod, + }, nil +} + +type routeWire struct { + ServedModelName *string `json:"served_model_name,omitempty"` + TrafficPercentage *int `json:"traffic_percentage,omitempty"` + ServedEntityName *string `json:"served_entity_name,omitempty"` +} + +func routeToWire(v *Route) (*routeWire, error) { + if v == nil { + return nil, nil + } + return &routeWire{ + ServedModelName: v.ServedModelName, + TrafficPercentage: v.TrafficPercentage, + ServedEntityName: v.ServedEntityName, + }, nil +} + +func routeFromWire(w *routeWire) (*Route, error) { + if w == nil { + return nil, nil + } + return &Route{ + ServedModelName: w.ServedModelName, + TrafficPercentage: w.TrafficPercentage, + ServedEntityName: w.ServedEntityName, + }, nil +} + +type servedModelWire struct { + Name *string `json:"name,omitempty"` + ExternalModel *externalModelWire `json:"external_model,omitempty"` + EntityName *string `json:"entity_name,omitempty"` + EntityVersion *string `json:"entity_version,omitempty"` + MinProvisionedThroughput *int `json:"min_provisioned_throughput,omitempty"` + MaxProvisionedThroughput *int `json:"max_provisioned_throughput,omitempty"` + MinProvisionedConcurrency *int `json:"min_provisioned_concurrency,omitempty"` + MaxProvisionedConcurrency *int `json:"max_provisioned_concurrency,omitempty"` + WorkloadSize *string `json:"workload_size,omitempty"` + ProvisionedModelUnits *int64 `json:"provisioned_model_units,omitempty"` + BurstScalingEnabled *bool `json:"burst_scaling_enabled,omitempty"` + ScaleToZeroEnabled *bool `json:"scale_to_zero_enabled,omitempty"` + ModelName *string `json:"model_name,omitempty"` + ModelVersion *string `json:"model_version,omitempty"` + EnvironmentVars map[string]string `json:"environment_vars,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + FoundationModel *foundationModelWire `json:"foundation_model,omitempty"` + State *servedModelStateWire `json:"state,omitempty"` + Creator *string `json:"creator,omitempty"` + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` +} + +func servedModelToWire(v *ServedModel) (*servedModelWire, error) { + if v == nil { + return nil, nil + } + externalModelWireValue, err := externalModelToWire(v.ExternalModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServedModel.ExternalModel", err) + } + foundationModelWireValue, err := foundationModelToWire(v.FoundationModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServedModel.FoundationModel", err) + } + stateWireValue, err := servedModelStateToWire(v.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServedModel.State", err) + } + return &servedModelWire{ + Name: v.Name, + ExternalModel: externalModelWireValue, + EntityName: v.EntityName, + EntityVersion: v.EntityVersion, + MinProvisionedThroughput: v.MinProvisionedThroughput, + MaxProvisionedThroughput: v.MaxProvisionedThroughput, + MinProvisionedConcurrency: v.MinProvisionedConcurrency, + MaxProvisionedConcurrency: v.MaxProvisionedConcurrency, + WorkloadSize: v.WorkloadSize, + ProvisionedModelUnits: v.ProvisionedModelUnits, + BurstScalingEnabled: v.BurstScalingEnabled, + ScaleToZeroEnabled: v.ScaleToZeroEnabled, + ModelName: v.ModelName, + ModelVersion: v.ModelVersion, + EnvironmentVars: v.EnvironmentVars, + InstanceProfileArn: v.InstanceProfileArn, + FoundationModel: foundationModelWireValue, + State: stateWireValue, + Creator: v.Creator, + CreationTimestamp: v.CreationTimestamp, + }, nil +} + +func servedModelFromWire(w *servedModelWire) (*ServedModel, error) { + if w == nil { + return nil, nil + } + externalModelPublicValue, err := externalModelFromWire(w.ExternalModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServedModel.ExternalModel", err) + } + foundationModelPublicValue, err := foundationModelFromWire(w.FoundationModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServedModel.FoundationModel", err) + } + statePublicValue, err := servedModelStateFromWire(w.State) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServedModel.State", err) + } + return &ServedModel{ + Name: w.Name, + ExternalModel: externalModelPublicValue, + EntityName: w.EntityName, + EntityVersion: w.EntityVersion, + MinProvisionedThroughput: w.MinProvisionedThroughput, + MaxProvisionedThroughput: w.MaxProvisionedThroughput, + MinProvisionedConcurrency: w.MinProvisionedConcurrency, + MaxProvisionedConcurrency: w.MaxProvisionedConcurrency, + WorkloadSize: w.WorkloadSize, + ProvisionedModelUnits: w.ProvisionedModelUnits, + BurstScalingEnabled: w.BurstScalingEnabled, + ScaleToZeroEnabled: w.ScaleToZeroEnabled, + ModelName: w.ModelName, + ModelVersion: w.ModelVersion, + EnvironmentVars: w.EnvironmentVars, + InstanceProfileArn: w.InstanceProfileArn, + FoundationModel: foundationModelPublicValue, + State: statePublicValue, + Creator: w.Creator, + CreationTimestamp: w.CreationTimestamp, + }, nil +} + +type servedModelLiteWire struct { + Name *string `json:"name,omitempty"` + ModelName *string `json:"model_name,omitempty"` + EntityName *string `json:"entity_name,omitempty"` + ModelVersion *string `json:"model_version,omitempty"` + EntityVersion *string `json:"entity_version,omitempty"` + ExternalModel *externalModelWire `json:"external_model,omitempty"` + FoundationModel *foundationModelWire `json:"foundation_model,omitempty"` +} + +func servedModelLiteFromWire(w *servedModelLiteWire) (*ServedModelLite, error) { + if w == nil { + return nil, nil + } + externalModelPublicValue, err := externalModelFromWire(w.ExternalModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServedModelLite.ExternalModel", err) + } + foundationModelPublicValue, err := foundationModelFromWire(w.FoundationModel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServedModelLite.FoundationModel", err) + } + return &ServedModelLite{ + Name: w.Name, + ModelName: w.ModelName, + EntityName: w.EntityName, + ModelVersion: w.ModelVersion, + EntityVersion: w.EntityVersion, + ExternalModel: externalModelPublicValue, + FoundationModel: foundationModelPublicValue, + }, nil +} + +type servedModelStateWire struct { + Deployment ServedModelDeploymentState `json:"deployment,omitempty"` + DeploymentStateMessage *string `json:"deployment_state_message,omitempty"` +} + +func servedModelStateToWire(v *ServedModelState) (*servedModelStateWire, error) { + if v == nil { + return nil, nil + } + return &servedModelStateWire{ + Deployment: v.Deployment, + DeploymentStateMessage: v.DeploymentStateMessage, + }, nil +} + +func servedModelStateFromWire(w *servedModelStateWire) (*ServedModelState, error) { + if w == nil { + return nil, nil + } + return &ServedModelState{ + Deployment: w.Deployment, + DeploymentStateMessage: w.DeploymentStateMessage, + }, nil +} + +type telemetryConfigWire struct { + TelemetryProfileId *string `json:"telemetry_profile_id,omitempty"` + TableNames *unityCatalogTableNamesWire `json:"table_names,omitempty"` + InferenceTableConfig *telemetryInferenceTableConfigWire `json:"inference_table_config,omitempty"` + EnabledTelemetryFeatures []TelemetryFeature `json:"enabled_telemetry_features,omitempty"` +} + +func telemetryConfigToWire(v *TelemetryConfig) (*telemetryConfigWire, error) { + if v == nil { + return nil, nil + } + inferenceTableConfigWireValue, err := telemetryInferenceTableConfigToWire(v.InferenceTableConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TelemetryConfig.InferenceTableConfig", err) + } + var telemetryProfileTelemetryProfileIdWire *string + var telemetryProfileTableNamesWire *unityCatalogTableNamesWire + switch value := v.TelemetryProfile.(type) { + case nil: + case *TelemetryConfig_TelemetryProfile_TelemetryProfileId: + if value != nil { + telemetryProfileTelemetryProfileIdWire = new(value.TelemetryProfileId) + } + case *TelemetryConfig_TelemetryProfile_TableNames: + if value != nil { + telemetryProfileTableNamesConverted, err := unityCatalogTableNamesToWire(&value.TableNames) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TelemetryConfig.TelemetryProfile.TableNames", err) + } + telemetryProfileTableNamesWire = telemetryProfileTableNamesConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "TelemetryConfig.TelemetryProfile", value) + } + return &telemetryConfigWire{ + TelemetryProfileId: telemetryProfileTelemetryProfileIdWire, + TableNames: telemetryProfileTableNamesWire, + InferenceTableConfig: inferenceTableConfigWireValue, + EnabledTelemetryFeatures: v.EnabledTelemetryFeatures, + }, nil +} + +func telemetryConfigFromWire(w *telemetryConfigWire) (*TelemetryConfig, error) { + if w == nil { + return nil, nil + } + telemetryProfileMembers := 0 + if w.TelemetryProfileId != nil { + telemetryProfileMembers++ + } + if w.TableNames != nil { + telemetryProfileMembers++ + } + if telemetryProfileMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "TelemetryConfig.TelemetryProfile") + } + inferenceTableConfigPublicValue, err := telemetryInferenceTableConfigFromWire(w.InferenceTableConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TelemetryConfig.InferenceTableConfig", err) + } + var telemetryProfileSelection isTelemetryConfig_TelemetryProfile + switch { + case w.TelemetryProfileId != nil: + telemetryProfileSelection = &TelemetryConfig_TelemetryProfile_TelemetryProfileId{TelemetryProfileId: *w.TelemetryProfileId} + case w.TableNames != nil: + telemetryProfileTableNamesConverted, err := unityCatalogTableNamesFromWire(w.TableNames) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TelemetryConfig.TelemetryProfile.TableNames", err) + } + telemetryProfileSelection = &TelemetryConfig_TelemetryProfile_TableNames{TableNames: *telemetryProfileTableNamesConverted} + } + return &TelemetryConfig{ + InferenceTableConfig: inferenceTableConfigPublicValue, + EnabledTelemetryFeatures: w.EnabledTelemetryFeatures, + TelemetryProfile: telemetryProfileSelection, + }, nil +} + +type telemetryInferenceTableConfigWire struct { + SamplingFraction *float64 `json:"sampling_fraction,omitempty"` + Name *string `json:"name,omitempty"` +} + +func telemetryInferenceTableConfigToWire(v *TelemetryInferenceTableConfig) (*telemetryInferenceTableConfigWire, error) { + if v == nil { + return nil, nil + } + return &telemetryInferenceTableConfigWire{ + SamplingFraction: v.SamplingFraction, + Name: v.Name, + }, nil +} + +func telemetryInferenceTableConfigFromWire(w *telemetryInferenceTableConfigWire) (*TelemetryInferenceTableConfig, error) { + if w == nil { + return nil, nil + } + return &TelemetryInferenceTableConfig{ + SamplingFraction: w.SamplingFraction, + Name: w.Name, + }, nil +} + +type trafficConfigWire struct { + Routes []routeWire `json:"routes,omitempty"` +} + +func trafficConfigToWire(v *TrafficConfig) (*trafficConfigWire, error) { + if v == nil { + return nil, nil + } + routesWireValue, err := convertSlice(v.Routes, routeToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TrafficConfig.Routes", err) + } + return &trafficConfigWire{ + Routes: routesWireValue, + }, nil +} + +func trafficConfigFromWire(w *trafficConfigWire) (*TrafficConfig, error) { + if w == nil { + return nil, nil + } + routesPublicValue, err := convertSlice(w.Routes, routeFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TrafficConfig.Routes", err) + } + return &TrafficConfig{ + Routes: routesPublicValue, + }, nil +} + +type unityCatalogTableNamesWire struct { + LogsTable *string `json:"logs_table,omitempty"` + MetricsTable *string `json:"metrics_table,omitempty"` + TracesTable *string `json:"traces_table,omitempty"` + AnnotationsTable *string `json:"annotations_table,omitempty"` +} + +func unityCatalogTableNamesToWire(v *UnityCatalogTableNames) (*unityCatalogTableNamesWire, error) { + if v == nil { + return nil, nil + } + return &unityCatalogTableNamesWire{ + LogsTable: v.LogsTable, + MetricsTable: v.MetricsTable, + TracesTable: v.TracesTable, + AnnotationsTable: v.AnnotationsTable, + }, nil +} + +func unityCatalogTableNamesFromWire(w *unityCatalogTableNamesWire) (*UnityCatalogTableNames, error) { + if w == nil { + return nil, nil + } + return &UnityCatalogTableNames{ + LogsTable: w.LogsTable, + MetricsTable: w.MetricsTable, + TracesTable: w.TracesTable, + AnnotationsTable: w.AnnotationsTable, + }, nil +} + +type updateInferenceEndpointNotificationsRequestWire struct { + Name *string `json:"name,omitempty"` + EmailNotifications *emailNotificationsWire `json:"email_notifications,omitempty"` +} + +func updateInferenceEndpointNotificationsRequestToWire(v *UpdateInferenceEndpointNotificationsRequest) (*updateInferenceEndpointNotificationsRequestWire, error) { + if v == nil { + return nil, nil + } + emailNotificationsWireValue, err := emailNotificationsToWire(v.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateInferenceEndpointNotificationsRequest.EmailNotifications", err) + } + return &updateInferenceEndpointNotificationsRequestWire{ + Name: v.Name, + EmailNotifications: emailNotificationsWireValue, + }, nil +} + +type updateInferenceEndpointNotificationsResponseWire struct { + Name *string `json:"name,omitempty"` + EmailNotifications *emailNotificationsWire `json:"email_notifications,omitempty"` +} + +func updateInferenceEndpointNotificationsResponseFromWire(w *updateInferenceEndpointNotificationsResponseWire) (*UpdateInferenceEndpointNotificationsResponse, error) { + if w == nil { + return nil, nil + } + emailNotificationsPublicValue, err := emailNotificationsFromWire(w.EmailNotifications) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateInferenceEndpointNotificationsResponse.EmailNotifications", err) + } + return &UpdateInferenceEndpointNotificationsResponse{ + Name: w.Name, + EmailNotifications: emailNotificationsPublicValue, + }, nil +} + +type usageTrackingConfigWire struct { + Enabled *bool `json:"enabled,omitempty"` +} + +func usageTrackingConfigToWire(v *UsageTrackingConfig) (*usageTrackingConfigWire, error) { + if v == nil { + return nil, nil + } + return &usageTrackingConfigWire{ + Enabled: v.Enabled, + }, nil +} + +func usageTrackingConfigFromWire(w *usageTrackingConfigWire) (*UsageTrackingConfig, error) { + if w == nil { + return nil, nil + } + return &UsageTrackingConfig{ + Enabled: w.Enabled, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/modelservingquery/.package.json b/modelservingquery/.package.json new file mode 100644 index 0000000..1218b64 --- /dev/null +++ b/modelservingquery/.package.json @@ -0,0 +1,3 @@ +{ + "package": "modelservingquery" +} diff --git a/modelservingquery/CHANGELOG.md b/modelservingquery/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/modelservingquery/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/modelservingquery/README.md b/modelservingquery/README.md new file mode 100644 index 0000000..77af608 --- /dev/null +++ b/modelservingquery/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/modelservingquery + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/modelservingquery@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/modelservingquery/v1" + +client, err := modelservingquery.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/modelservingquery/go.mod b/modelservingquery/go.mod new file mode 100644 index 0000000..9409f3b --- /dev/null +++ b/modelservingquery/go.mod @@ -0,0 +1,21 @@ +module github.com/databricks/sdk-go/modelservingquery + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 + github.com/google/go-cmp v0.7.0 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/modelservingquery/internal/version.go b/modelservingquery/internal/version.go new file mode 100644 index 0000000..2b63526 --- /dev/null +++ b/modelservingquery/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-modelservingquery" + +const Version = "0.0.1-dev.1" diff --git a/modelservingquery/v1/client.go b/modelservingquery/v1/client.go new file mode 100755 index 0000000..94c33cd --- /dev/null +++ b/modelservingquery/v1/client.go @@ -0,0 +1,148 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelservingquery + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/modelservingquery/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Query a serving endpoint +func (c *internalClient) Query(ctx context.Context, req *QueryEndpointRequest, opts ...call.Option) (*QueryEndpointResponse, error) { + wireReq, err := queryEndpointRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/serving-endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/invocations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *QueryEndpointResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, respHeader, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp queryEndpointResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = queryEndpointResponseFromWire(&wireResp) + if err != nil { + return err + } + if v := respHeader.Get("served-model-name"); v != "" { + h := v + resp.ServedModelName = &h + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/modelservingquery/v1/ext_query_dp.go b/modelservingquery/v1/ext_query_dp.go new file mode 100644 index 0000000..6e4d85b --- /dev/null +++ b/modelservingquery/v1/ext_query_dp.go @@ -0,0 +1,373 @@ +package modelservingquery + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "net/url" + "strings" + "sync" + "time" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/ops" +) + +// dpStateKey is the private key under which the route-optimization state is +// stored in the client's extension map. +type dpStateKey struct{} + +// dpState holds the route-optimization state for a Client, built once per +// client and cached in the extension map. +type dpState struct { + client *Client + + // cpTokens is the control-plane token provider used to mint data-plane + // tokens. It is nil when the credentials cannot mint OAuth tokens (for + // example a personal access token). + cpTokens auth.TokenProvider + + // endpoints caches the per-endpoint route-optimization state keyed by + // endpoint name (string -> *endpointState). + // + // An entry is evicted on a data-plane call failure so neither a stale + // endpoint URL / authorization detail nor a bad-but-unexpired data-plane + // token can wedge an endpoint permanently. + endpoints sync.Map +} + +// endpointState bundles a route-optimized endpoint's discovered info with the +// credentials scoped to it. The two are cached and evicted together: a +// data-plane failure drops the possibly bad token alongside the metadata, so +// the next call re-discovers and re-mints instead of replaying a stale token. +type endpointState struct { + info *dataPlaneInfo + creds auth.Credentials +} + +// dpState returns the route-optimization state for the client, building it once +// and caching it in the extension map. +func (c *Client) dpState() *dpState { + if v, ok := c.extensions.Load(dpStateKey{}); ok { + return v.(*dpState) + } + s := &dpState{client: c} + if tp, ok := c.credentials.(auth.TokenProvider); ok { + s.cpTokens = auth.NewCachedTokenProvider(tp) + } + actual, _ := c.extensions.LoadOrStore(dpStateKey{}, s) + return actual.(*dpState) +} + +// dataPlaneInfo is the minimal projection of a serving endpoint's data-plane +// query info needed to route a query directly to the data plane. +type dataPlaneInfo struct { + endpointURL string + authorizationDetails string +} + +// ErrRouteOptimizationUnavailable is returned by QueryOptimized when the query +// cannot be routed to the data plane: the client is not configured with +// OAuth-capable credentials, the request has no endpoint name, or the endpoint +// does not advertise data-plane query info. A caller that wants best-effort +// behavior can detect this with errors.Is and fall back to Query: +// +// resp, err := c.QueryOptimized(ctx, req) +// if errors.Is(err, ErrRouteOptimizationUnavailable) { +// resp, err = c.Query(ctx, req) +// } +var ErrRouteOptimizationUnavailable = errors.New("modelservingquery: route optimization unavailable for this endpoint") + +// QueryOptimized queries a serving endpoint directly on the data plane, +// bypassing the control plane for lower latency. +// +// It requires OAuth-capable credentials and an endpoint that advertises +// data-plane query info. When either is missing, or the request has no endpoint +// name, it returns an error wrapping ErrRouteOptimizationUnavailable; callers +// that want to fall back can test for it with errors.Is and call Query. +// +// Unlike Query, it never falls back to the control plane once the data-plane +// call is made: an error from that call is returned as is, so a billed inference +// is not silently retried elsewhere. It otherwise behaves like Query. +func (c *Client) QueryOptimized(ctx context.Context, req *QueryEndpointRequest, opts ...ops.Option) (*QueryEndpointResponse, error) { + dp := c.dpState() + if dp.cpTokens == nil || req.Name == nil { + return nil, ErrRouteOptimizationUnavailable + } + name := *req.Name + + ep, err := dp.endpointState(ctx, name, opts...) + if err != nil { + return nil, err + } + if ep == nil { + // The endpoint is not route-optimized. + return nil, fmt.Errorf("%w: endpoint %q", ErrRouteOptimizationUnavailable, name) + } + + resp, err := dp.query(ctx, req, ep, opts...) + if err != nil { + // Evict info and token source together so neither a stale URL nor a + // bad-but-unexpired token can wedge the endpoint. + dp.endpoints.Delete(name) + return nil, err + } + return resp, nil +} + +// endpointState returns the cached route-optimization state for the endpoint, +// discovering it via the control plane on a cache miss. It returns (nil, nil) +// when the endpoint is not route-optimized (no data-plane query info). Negative +// results are not cached. Each freshly discovered endpoint gets its own token +// source so evicting the endpoint also discards its cached data-plane token. +func (dp *dpState) endpointState(ctx context.Context, name string, opts ...ops.Option) (*endpointState, error) { + if v, ok := dp.endpoints.Load(name); ok { + return v.(*endpointState), nil + } + + info, err := dp.fetchDataPlaneInfo(ctx, name, opts...) + if err != nil { + return nil, err + } + if info == nil { + return nil, nil + } + ep := &endpointState{ + info: info, + creds: dp.dataPlaneCredentials(info.authorizationDetails), + } + actual, _ := dp.endpoints.LoadOrStore(name, ep) + return actual.(*endpointState), nil +} + +// servingEndpointDetailedWire is the minimal projection of the serving-endpoint +// GET response. Only the data-plane query info is decoded; everything else on +// the endpoint is ignored. This mirrors the wire shape of +// modelserving.ModelDataPlaneInfo without depending on that module, keeping +// modelservingquery self-contained. +type servingEndpointDetailedWire struct { + DataPlaneInfo *struct { + QueryInfo *struct { + EndpointURL *string `json:"endpoint_url,omitempty"` + AuthorizationDetails *string `json:"authorization_details,omitempty"` + } `json:"query_info,omitempty"` + } `json:"data_plane_info,omitempty"` +} + +// fetchDataPlaneInfo issues the control-plane GET that reveals whether the +// endpoint is route-optimized. It returns nil (no error) when the endpoint has +// no data-plane query info. The GET is signed with the client's control-plane +// credentials. +func (dp *dpState) fetchDataPlaneInfo(ctx context.Context, name string, opts ...ops.Option) (*dataPlaneInfo, error) { + c := dp.client + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/serving-endpoints/") + pb.singleSegment(name) + baseURL.Path, baseURL.RawPath = pb.build() + urlStr := baseURL.String() + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + var info *dataPlaneInfo + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: http.MethodGet, + URL: urlStr, + Credentials: c.credentials, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp servingEndpointDetailedWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + info = dataPlaneInfoFromWire(&wireResp) + return nil + } + + if err := ops.Execute(ctx, call, opts...); err != nil { + return nil, err + } + return info, nil +} + +// dataPlaneInfoFromWire projects the endpoint response to a dataPlaneInfo, +// returning nil when the endpoint does not advertise a data-plane endpoint URL. +func dataPlaneInfoFromWire(w *servingEndpointDetailedWire) *dataPlaneInfo { + if w.DataPlaneInfo == nil || w.DataPlaneInfo.QueryInfo == nil { + return nil + } + qi := w.DataPlaneInfo.QueryInfo + if qi.EndpointURL == nil || *qi.EndpointURL == "" { + return nil + } + info := &dataPlaneInfo{endpointURL: *qi.EndpointURL} + if qi.AuthorizationDetails != nil { + info.authorizationDetails = *qi.AuthorizationDetails + } + return info +} + +// query posts the request directly to the data-plane endpoint URL, using the +// endpoint's data-plane credentials. It mirrors the generated control-plane +// Query (body/response wire conversion, served-model-name header) but targets +// the absolute data-plane URL and signs with the data-plane token instead of +// the control-plane credentials. +func (dp *dpState) query(ctx context.Context, req *QueryEndpointRequest, ep *endpointState, opts ...ops.Option) (*QueryEndpointResponse, error) { + c := dp.client + info := ep.info + wireReq, err := queryEndpointRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + headers.Set("Accept", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + var resp *QueryEndpointResponse + call := func(ctx context.Context) error { + // The token is minted per attempt via ep.creds.AuthHeaders, so a + // refreshed token is used on retry. + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: http.MethodPost, + URL: info.endpointURL, + Credentials: ep.creds, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, respHeader, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp queryEndpointResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = queryEndpointResponseFromWire(&wireResp) + if err != nil { + return err + } + if v := respHeader.Get("served-model-name"); v != "" { + h := v + resp.ServedModelName = &h + } + return nil + } + + if err := ops.Execute(ctx, call, opts...); err != nil { + return nil, err + } + return resp, nil +} + +// dataPlaneCredentials returns credentials that authenticate a request with a +// data-plane token minted for the given authorization details by exchanging a +// fresh control-plane token. The underlying token is cached and refreshed +// asynchronously before it expires, with concurrent refreshes coalesced. +func (dp *dpState) dataPlaneCredentials(authDetails string) auth.Credentials { + tokens := auth.NewCachedTokenProvider(auth.TokenProviderFn(func(ctx context.Context) (*auth.Token, error) { + cpToken, err := dp.cpTokens.Token(ctx) + if err != nil { + return nil, err + } + return dp.exchangeToken(ctx, authDetails, cpToken) + })) + return auth.NewTokenCredentials("dataplane", tokens) +} + +const jwtBearerGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer" + +// exchangeToken swaps a control-plane token for a data-plane-scoped token via +// the workspace OIDC token endpoint, using the JWT-bearer grant with RFC 9396 +// authorization details. The request carries the assertion in its form body and +// is issued with nil credentials, so no control-plane signing is applied. +func (dp *dpState) exchangeToken(ctx context.Context, authDetails string, cpToken *auth.Token) (*auth.Token, error) { + c := dp.client + tokenURL := strings.TrimRight(c.host, "/") + "/oidc/v1/token" + + form := url.Values{} + form.Set("grant_type", jwtBearerGrantType) + form.Set("authorization_details", authDetails) + form.Set("assertion", cpToken.Value) + + headers := http.Header{} + headers.Set("Content-Type", "application/x-www-form-urlencoded") + headers.Set("Accept", "application/json") + + // Credentials is nil: the assertion in the form body is the credential, so + // the request must not also carry control-plane signing. + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: http.MethodPost, + URL: tokenURL, + Headers: headers, + Body: strings.NewReader(form.Encode()), + }) + if err != nil { + return nil, err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return nil, err + } + + var tokenResp struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + ExpiresIn int64 `json:"expires_in"` + } + if err := json.Unmarshal(respBody, &tokenResp); err != nil { + return nil, err + } + if tokenResp.AccessToken == "" { + return nil, fmt.Errorf("oidc token exchange: missing access_token (expires_in=%d)", tokenResp.ExpiresIn) + } + + token := &auth.Token{ + Value: tokenResp.AccessToken, + Type: tokenResp.TokenType, + } + if tokenResp.ExpiresIn > 0 { + token.Expiry = time.Now().Add(time.Duration(tokenResp.ExpiresIn) * time.Second) + } + return token, nil +} diff --git a/modelservingquery/v1/ext_query_dp_test.go b/modelservingquery/v1/ext_query_dp_test.go new file mode 100644 index 0000000..cc01d4e --- /dev/null +++ b/modelservingquery/v1/ext_query_dp_test.go @@ -0,0 +1,337 @@ +package modelservingquery + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/http/httptest" + "sync/atomic" + "testing" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/options/client" + "github.com/google/go-cmp/cmp" +) + +// patCreds is a static credential that only implements auth.Credentials, like a +// personal access token. It cannot mint OAuth tokens, so route optimization is +// not possible and QueryOptimized must report it as unavailable. +type patCreds struct{} + +func (patCreds) Name() string { return "pat" } + +func (patCreds) AuthHeaders(context.Context) ([]auth.Header, error) { + return []auth.Header{{Key: "Authorization", Value: "Bearer pat-token"}}, nil +} + +// oauthCreds implements auth.TokenCredentials (both AuthHeaders and Token), like +// an OAuth-based credential. Its presence makes route optimization possible. +type oauthCreds struct{} + +func (oauthCreds) Name() string { return "oauth" } + +func (oauthCreds) AuthHeaders(context.Context) ([]auth.Header, error) { + return []auth.Header{{Key: "Authorization", Value: "Bearer cp-token"}}, nil +} + +func (oauthCreds) Token(context.Context) (*auth.Token, error) { + return &auth.Token{Value: "cp-token", Type: "Bearer"}, nil +} + +const ( + testEndpointName = "my-endpoint" + dpAccessToken = "dp-access-token" + dpAuthDetails = "auth-details-blob" +) + +func newQueryTestClient(t *testing.T, server *httptest.Server, creds auth.Credentials) *Client { + t.Helper() + c, err := NewClient(context.Background(), + client.WithHost(server.URL), + client.WithHTTPClient(server.Client()), + client.WithCredentials(creds), + client.WithWorkspaceID("ws-123"), + client.WithLogger(slog.New(slog.NewTextHandler(io.Discard, nil))), + client.WithoutProfileResolution(), + ) + if err != nil { + t.Fatalf("NewClient: %v", err) + } + return c +} + +// counters records how many times each server route was hit. +type counters struct { + cpGet atomic.Int64 // GET /api/2.0/serving-endpoints/{name} + cpInvocations atomic.Int64 // POST /api/serving-endpoints/{name}/invocations + tokenExchange atomic.Int64 // POST /oidc/v1/token + dpInvoke atomic.Int64 // POST /dp/invocations +} + +// routeCounts is the plain-value expectation compared against counters. +type routeCounts struct { + cpGet int64 + cpInvocations int64 + tokenExchange int64 + dpInvoke int64 +} + +// serverConfig configures the mock server behavior for a test case. +type serverConfig struct { + // includeDataPlaneInfo controls whether the control-plane GET advertises a + // data-plane endpoint URL (i.e. the endpoint is route-optimized). + includeDataPlaneInfo bool + // tokenStatus is the HTTP status the token-exchange /oidc/v1/token route + // returns. Zero means 200 OK. + tokenStatus int + // dpStatus is the HTTP status the data-plane /dp/invocations route returns. + // Zero means 200 OK. + dpStatus int +} + +// captured records request details the assertions care about. +type captured struct { + dpAuthHeader string + dpWorkspaceIDHeader string + tokenAssertion string + tokenAuthDetails string +} + +func newMockServer(t *testing.T, cfg serverConfig, c *counters, cap *captured) *httptest.Server { + t.Helper() + + queryResp := mustMarshalJSON(t, &queryEndpointResponseWire{Model: new("served-model")}) + + var srv *httptest.Server + srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + + switch { + case r.Method == http.MethodGet && r.URL.Path == "/api/2.0/serving-endpoints/"+testEndpointName: + c.cpGet.Add(1) + body := servingEndpointGetPayload(t, cfg.includeDataPlaneInfo, srv.URL+"/dp/invocations") + _, _ = w.Write(body) + + case r.Method == http.MethodPost && r.URL.Path == "/oidc/v1/token": + c.tokenExchange.Add(1) + _ = r.ParseForm() + cap.tokenAssertion = r.Form.Get("assertion") + cap.tokenAuthDetails = r.Form.Get("authorization_details") + if cfg.tokenStatus != 0 && cfg.tokenStatus != http.StatusOK { + http.Error(w, `{"error":"invalid_grant"}`, cfg.tokenStatus) + return + } + _, _ = w.Write(mustMarshalJSON(t, map[string]any{ + "access_token": dpAccessToken, + "token_type": "Bearer", + "expires_in": 3600, + })) + + case r.Method == http.MethodPost && r.URL.Path == "/dp/invocations": + c.dpInvoke.Add(1) + cap.dpAuthHeader = r.Header.Get("Authorization") + cap.dpWorkspaceIDHeader = r.Header.Get("X-Databricks-Workspace-Id") + if cfg.dpStatus != 0 && cfg.dpStatus != http.StatusOK { + http.Error(w, `{"error_code":"INTERNAL","message":"boom"}`, cfg.dpStatus) + return + } + w.Header().Set("served-model-name", "served-model") + _, _ = w.Write(queryResp) + + case r.Method == http.MethodPost && r.URL.Path == "/api/serving-endpoints/"+testEndpointName+"/invocations": + c.cpInvocations.Add(1) + w.Header().Set("served-model-name", "served-model") + _, _ = w.Write(queryResp) + + default: + http.Error(w, fmt.Sprintf(`{"error":"not found: %s %s"}`, r.Method, r.URL.Path), http.StatusNotFound) + } + })) + return srv +} + +func servingEndpointGetPayload(t *testing.T, includeDataPlaneInfo bool, dpURL string) []byte { + t.Helper() + payload := map[string]any{"name": testEndpointName} + if includeDataPlaneInfo { + payload["data_plane_info"] = map[string]any{ + "query_info": map[string]any{ + "endpoint_url": dpURL, + "authorization_details": dpAuthDetails, + }, + } + } + return mustMarshalJSON(t, payload) +} + +func mustMarshalJSON(t *testing.T, v any) []byte { + t.Helper() + b, err := json.Marshal(v) + if err != nil { + t.Fatalf("marshal: %v", err) + } + return b +} + +func TestQueryOptimized(t *testing.T) { + testCases := []struct { + name string + creds auth.Credentials + cfg serverConfig + calls int + // wantErr is the sentinel every call must match with errors.Is: nil for + // success or ErrRouteOptimizationUnavailable. + wantErr error + // wantAPIError is set when the call instead fails with an opaque + // *apierr.APIError (data-plane or token-exchange failures), which carries + // no sentinel to match against. + wantAPIError bool + want routeCounts + }{ + { + name: "non-OAuth credentials are unavailable without any request", + creds: patCreds{}, + cfg: serverConfig{includeDataPlaneInfo: true}, + calls: 1, + wantErr: ErrRouteOptimizationUnavailable, + want: routeCounts{}, + }, + { + name: "endpoint without data-plane info is unavailable after detection", + creds: oauthCreds{}, + cfg: serverConfig{includeDataPlaneInfo: false}, + calls: 1, + wantErr: ErrRouteOptimizationUnavailable, + want: routeCounts{cpGet: 1}, + }, + { + name: "route-optimized endpoint caches info and token across calls", + creds: oauthCreds{}, + cfg: serverConfig{includeDataPlaneInfo: true}, + calls: 2, + // Detection GET and token exchange fire once and are reused; only + // the billed data-plane invocation repeats. + want: routeCounts{cpGet: 1, tokenExchange: 1, dpInvoke: 2}, + }, + { + name: "data-plane failure returns the error and evicts the endpoint", + creds: oauthCreds{}, + cfg: serverConfig{includeDataPlaneInfo: true, dpStatus: http.StatusInternalServerError}, + calls: 2, + wantAPIError: true, + // Eviction re-runs detection and token exchange on the second call; + // the control plane is never used as a fallback. + want: routeCounts{cpGet: 2, tokenExchange: 2, dpInvoke: 2}, + }, + { + name: "token-exchange failure returns the error and evicts the endpoint", + creds: oauthCreds{}, + cfg: serverConfig{includeDataPlaneInfo: true, tokenStatus: http.StatusUnauthorized}, + calls: 2, + wantAPIError: true, + // The data plane is never reached when minting fails; eviction + // re-runs detection and exchange on the second call. + want: routeCounts{cpGet: 2, tokenExchange: 2}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var c counters + var cap captured + srv := newMockServer(t, tc.cfg, &c, &cap) + defer srv.Close() + + cl := newQueryTestClient(t, srv, tc.creds) + + for i := range tc.calls { + resp, gotErr := cl.QueryOptimized(context.Background(), &QueryEndpointRequest{Name: new(testEndpointName)}) + + if tc.wantAPIError { + if _, ok := errors.AsType[*apierr.APIError](gotErr); !ok { + t.Fatalf("call %d: error = %v, want an *apierr.APIError", i, gotErr) + } + continue + } + + if !errors.Is(gotErr, tc.wantErr) { + t.Fatalf("call %d: error = %v, want %v", i, gotErr, tc.wantErr) + } + if tc.wantErr == nil && (resp.ServedModelName == nil || *resp.ServedModelName != "served-model") { + t.Errorf("call %d: served-model-name header not applied: %+v", i, resp.ServedModelName) + } + } + + got := routeCounts{ + cpGet: c.cpGet.Load(), + cpInvocations: c.cpInvocations.Load(), + tokenExchange: c.tokenExchange.Load(), + dpInvoke: c.dpInvoke.Load(), + } + if diff := cmp.Diff(tc.want, got, cmp.AllowUnexported(routeCounts{})); diff != "" { + t.Errorf("route hit counts mismatch (-want +got):\n%s", diff) + } + }) + } +} + +// TestQueryOptimized_DataPlaneRequest checks the data-plane call carries the +// exchanged token and workspace id, and that the exchange forwards the +// control-plane token and the endpoint's authorization details. +func TestQueryOptimized_DataPlaneRequest(t *testing.T) { + var c counters + var cap captured + srv := newMockServer(t, serverConfig{includeDataPlaneInfo: true}, &c, &cap) + defer srv.Close() + + cl := newQueryTestClient(t, srv, oauthCreds{}) + if _, err := cl.QueryOptimized(context.Background(), &QueryEndpointRequest{Name: new(testEndpointName)}); err != nil { + t.Fatalf("QueryOptimized: %v", err) + } + + if cap.dpAuthHeader != "Bearer "+dpAccessToken { + t.Errorf("data-plane Authorization = %q, want %q", cap.dpAuthHeader, "Bearer "+dpAccessToken) + } + if cap.dpWorkspaceIDHeader != "ws-123" { + t.Errorf("data-plane workspace id = %q, want %q", cap.dpWorkspaceIDHeader, "ws-123") + } + if cap.tokenAssertion != "cp-token" { + t.Errorf("token exchange assertion = %q, want %q", cap.tokenAssertion, "cp-token") + } + if cap.tokenAuthDetails != dpAuthDetails { + t.Errorf("token exchange authorization_details = %q, want %q", cap.tokenAuthDetails, dpAuthDetails) + } +} + +// TestServingEndpointWireProjection guards the minimal wire projection used for +// detection against a representative response body. +func TestServingEndpointWireProjection(t *testing.T) { + body := servingEndpointGetPayload(t, true, "https://dp.example/invocations") + var w servingEndpointDetailedWire + if err := json.Unmarshal(body, &w); err != nil { + t.Fatalf("unmarshal: %v", err) + } + got := dataPlaneInfoFromWire(&w) + want := &dataPlaneInfo{ + endpointURL: "https://dp.example/invocations", + authorizationDetails: dpAuthDetails, + } + if diff := cmp.Diff(want, got, cmp.AllowUnexported(dataPlaneInfo{})); diff != "" { + t.Errorf("dataPlaneInfoFromWire mismatch (-want +got):\n%s", diff) + } + + // Missing data-plane info projects to nil (not route-optimized). + empty := servingEndpointGetPayload(t, false, "") + var we servingEndpointDetailedWire + if err := json.Unmarshal(empty, &we); err != nil { + t.Fatalf("unmarshal: %v", err) + } + if got := dataPlaneInfoFromWire(&we); got != nil { + t.Errorf("dataPlaneInfoFromWire on endpoint without data-plane info = %+v, want nil", got) + } +} diff --git a/modelservingquery/v1/genhelper.go b/modelservingquery/v1/genhelper.go new file mode 100755 index 0000000..f9f5942 --- /dev/null +++ b/modelservingquery/v1/genhelper.go @@ -0,0 +1,188 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelservingquery + +import ( + "context" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/modelservingquery/v1/model.go b/modelservingquery/v1/model.go new file mode 100755 index 0000000..c977fe6 --- /dev/null +++ b/modelservingquery/v1/model.go @@ -0,0 +1,172 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelservingquery + +import "encoding/json" + +// The role of the message. One of [system, user, assistant]. +type ChatMessageRole string + +const ( + ChatMessageRole_Unspecified ChatMessageRole = "" + ChatMessageRole_System ChatMessageRole = "system" + ChatMessageRole_User ChatMessageRole = "user" + ChatMessageRole_Assistant ChatMessageRole = "assistant" +) + +// This will always be 'embedding'. +type EmbeddingsV1ResponseEmbeddingElementObject string + +const ( + EmbeddingsV1ResponseEmbeddingElementObject_Unspecified EmbeddingsV1ResponseEmbeddingElementObject = "" + EmbeddingsV1ResponseEmbeddingElementObject_Embedding EmbeddingsV1ResponseEmbeddingElementObject = "embedding" +) + +// The type of object returned by the __external/foundation model__ serving +// endpoint, one of [text_completion, chat.completion, list (of embeddings)]. +type QueryEndpointResponseObject string + +const ( + QueryEndpointResponseObject_Unspecified QueryEndpointResponseObject = "" + QueryEndpointResponseObject_TextCompletion QueryEndpointResponseObject = "text_completion" + QueryEndpointResponseObject_ChatCompletion QueryEndpointResponseObject = "chat.completion" + QueryEndpointResponseObject_List QueryEndpointResponseObject = "list" +) + +type ChatMessage struct { + // The role of the message. One of [system, user, assistant]. + Role ChatMessageRole + // The content of the message. + Content *string +} + +type DataframeSplitInput struct { + // Index array for the dataframe + Index []int + // Columns array for the dataframe + Columns []json.RawMessage + // Data array for the dataframe + Data []json.RawMessage +} + +type EmbeddingsV1ResponseEmbeddingElement struct { + // The embedding vector + Embedding []float64 + // The index of the embedding in the response. + Index *int + // This will always be 'embedding'. + Object EmbeddingsV1ResponseEmbeddingElementObject +} + +type ExternalModelUsageElement struct { + // The number of tokens in the prompt. + PromptTokens *int + // The number of tokens in the chat/completions response. + CompletionTokens *int + // The total number of tokens in the prompt and response. + TotalTokens *int +} + +type QueryEndpointRequest struct { + // The name of the serving endpoint. This field is required and is provided via + // the path parameter. + Name *string + // The prompt string (or array of strings) field used ONLY for __completions + // external & foundation model__ serving endpoints and should only be used with + // other completions query fields. + Prompt json.RawMessage + // The input string (or array of strings) field used ONLY for __embeddings + // external & foundation model__ serving endpoints and is the only field (along + // with extra_params if needed) used by embeddings queries. + Input json.RawMessage + // The messages field used ONLY for __chat external & foundation model__ serving + // endpoints. This is an array of ChatMessage objects and should only be used + // with other chat query fields. + Messages []ChatMessage + // The temperature field used ONLY for __completions__ and __chat external & + // foundation model__ serving endpoints. This is a float between 0.0 and 2.0 + // with a default of 1.0 and should only be used with other chat/completions + // query fields. + Temperature *float64 + // The stop sequences field used ONLY for __completions__ and __chat external & + // foundation model__ serving endpoints. This is a list of strings and should + // only be used with other chat/completions query fields. + Stop []string + // The max tokens field used ONLY for __completions__ and __chat external & + // foundation model__ serving endpoints. This is an integer and should only be + // used with other chat/completions query fields. + MaxTokens *int + // The n (number of candidates) field used ONLY for __completions__ and __chat + // external & foundation model__ serving endpoints. This is an integer between 1 + // and 5 with a default of 1 and should only be used with other chat/completions + // query fields. + N *int + // The stream field used ONLY for __completions__ and __chat external & + // foundation model__ serving endpoints. This is a boolean defaulting to false + // and should only be used with other chat/completions query fields. + Stream *bool + // The extra parameters field used ONLY for __completions, chat,__ and + // __embeddings external & foundation model__ serving endpoints. This is a map + // of strings and should only be used with other external/foundation model query + // fields. + ExtraParams map[string]string + // Pandas Dataframe input in the records orientation. + DataframeRecords []json.RawMessage + // Pandas Dataframe input in the split orientation. + DataframeSplit *DataframeSplitInput + // Tensor-based input in row format. + Instances []json.RawMessage + // Tensor-based input in columnar format. + Inputs json.RawMessage + // Optional user-provided request identifier that will be recorded in the + // inference table and the usage tracking table. + ClientRequestId *string + // Optional user-provided context that will be recorded in the usage tracking + // table. + UsageContext map[string]string +} + +type QueryEndpointResponse struct { + // The list of choices returned by the __chat or completions external/foundation + // model__ serving endpoint. + Choices []V1ResponseChoiceElement + // The list of the embeddings returned by the __embeddings external/foundation + // model__ serving endpoint. + Data []EmbeddingsV1ResponseEmbeddingElement + // The name of the __external/foundation model__ used for querying. This is the + // name of the model that was specified in the endpoint config. + Model *string + // The usage object that may be returned by the __external/foundation model__ + // serving endpoint. This contains information about the number of tokens used + // in the prompt and response. + Usage *ExternalModelUsageElement + // The ID of the query that may be returned by a __completions or chat + // external/foundation model__ serving endpoint. + Id *string + // The timestamp in seconds when the query was created in Unix time returned by + // a __completions or chat external/foundation model__ serving endpoint. + Created *int64 + // The type of object returned by the __external/foundation model__ serving + // endpoint, one of [text_completion, chat.completion, list (of embeddings)]. + Object QueryEndpointResponseObject + // The predictions returned by the serving endpoint. + Predictions []json.RawMessage + // The outputs of the feature serving endpoint. + Outputs []json.RawMessage + // The name of the served model that served the request. This is useful when + // there are multiple models behind the same endpoint with traffic split. + ServedModelName *string +} + +type V1ResponseChoiceElement struct { + // The text response from the __completions__ endpoint. + Text *string + // The message response from the __chat__ endpoint. + Message *ChatMessage + // The index of the choice in the __chat or completions__ response. + Index *int + // The finish reason returned by the endpoint. + FinishReason *string + // The logprobs returned only by the __completions__ endpoint. + Logprobs *int +} diff --git a/modelservingquery/v1/wire.go b/modelservingquery/v1/wire.go new file mode 100755 index 0000000..e5672de --- /dev/null +++ b/modelservingquery/v1/wire.go @@ -0,0 +1,216 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package modelservingquery + +import ( + "encoding/json" + "fmt" +) + +type chatMessageWire struct { + Role ChatMessageRole `json:"role,omitempty"` + Content *string `json:"content,omitempty"` +} + +func chatMessageToWire(v *ChatMessage) (*chatMessageWire, error) { + if v == nil { + return nil, nil + } + return &chatMessageWire{ + Role: v.Role, + Content: v.Content, + }, nil +} + +func chatMessageFromWire(w *chatMessageWire) (*ChatMessage, error) { + if w == nil { + return nil, nil + } + return &ChatMessage{ + Role: w.Role, + Content: w.Content, + }, nil +} + +type dataframeSplitInputWire struct { + Index []int `json:"index,omitempty"` + Columns []json.RawMessage `json:"columns,omitempty"` + Data []json.RawMessage `json:"data,omitempty"` +} + +func dataframeSplitInputToWire(v *DataframeSplitInput) (*dataframeSplitInputWire, error) { + if v == nil { + return nil, nil + } + return &dataframeSplitInputWire{ + Index: v.Index, + Columns: v.Columns, + Data: v.Data, + }, nil +} + +type embeddingsV1ResponseEmbeddingElementWire struct { + Embedding []float64 `json:"embedding,omitempty"` + Index *int `json:"index,omitempty"` + Object EmbeddingsV1ResponseEmbeddingElementObject `json:"object,omitempty"` +} + +func embeddingsV1ResponseEmbeddingElementFromWire(w *embeddingsV1ResponseEmbeddingElementWire) (*EmbeddingsV1ResponseEmbeddingElement, error) { + if w == nil { + return nil, nil + } + return &EmbeddingsV1ResponseEmbeddingElement{ + Embedding: w.Embedding, + Index: w.Index, + Object: w.Object, + }, nil +} + +type externalModelUsageElementWire struct { + PromptTokens *int `json:"prompt_tokens,omitempty"` + CompletionTokens *int `json:"completion_tokens,omitempty"` + TotalTokens *int `json:"total_tokens,omitempty"` +} + +func externalModelUsageElementFromWire(w *externalModelUsageElementWire) (*ExternalModelUsageElement, error) { + if w == nil { + return nil, nil + } + return &ExternalModelUsageElement{ + PromptTokens: w.PromptTokens, + CompletionTokens: w.CompletionTokens, + TotalTokens: w.TotalTokens, + }, nil +} + +type queryEndpointRequestWire struct { + Name *string `json:"name,omitempty"` + Prompt json.RawMessage `json:"prompt,omitempty"` + Input json.RawMessage `json:"input,omitempty"` + Messages []chatMessageWire `json:"messages,omitempty"` + Temperature *float64 `json:"temperature,omitempty"` + Stop []string `json:"stop,omitempty"` + MaxTokens *int `json:"max_tokens,omitempty"` + N *int `json:"n,omitempty"` + Stream *bool `json:"stream,omitempty"` + ExtraParams map[string]string `json:"extra_params,omitempty"` + DataframeRecords []json.RawMessage `json:"dataframe_records,omitempty"` + DataframeSplit *dataframeSplitInputWire `json:"dataframe_split,omitempty"` + Instances []json.RawMessage `json:"instances,omitempty"` + Inputs json.RawMessage `json:"inputs,omitempty"` + ClientRequestId *string `json:"client_request_id,omitempty"` + UsageContext map[string]string `json:"usage_context,omitempty"` +} + +func queryEndpointRequestToWire(v *QueryEndpointRequest) (*queryEndpointRequestWire, error) { + if v == nil { + return nil, nil + } + messagesWireValue, err := convertSlice(v.Messages, chatMessageToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryEndpointRequest.Messages", err) + } + dataframeSplitWireValue, err := dataframeSplitInputToWire(v.DataframeSplit) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryEndpointRequest.DataframeSplit", err) + } + return &queryEndpointRequestWire{ + Name: v.Name, + Prompt: v.Prompt, + Input: v.Input, + Messages: messagesWireValue, + Temperature: v.Temperature, + Stop: v.Stop, + MaxTokens: v.MaxTokens, + N: v.N, + Stream: v.Stream, + ExtraParams: v.ExtraParams, + DataframeRecords: v.DataframeRecords, + DataframeSplit: dataframeSplitWireValue, + Instances: v.Instances, + Inputs: v.Inputs, + ClientRequestId: v.ClientRequestId, + UsageContext: v.UsageContext, + }, nil +} + +type queryEndpointResponseWire struct { + Choices []v1ResponseChoiceElementWire `json:"choices,omitempty"` + Data []embeddingsV1ResponseEmbeddingElementWire `json:"data,omitempty"` + Model *string `json:"model,omitempty"` + Usage *externalModelUsageElementWire `json:"usage,omitempty"` + Id *string `json:"id,omitempty"` + Created *int64 `json:"created,omitempty"` + Object QueryEndpointResponseObject `json:"object,omitempty"` + Predictions []json.RawMessage `json:"predictions,omitempty"` + Outputs []json.RawMessage `json:"outputs,omitempty"` +} + +func queryEndpointResponseFromWire(w *queryEndpointResponseWire) (*QueryEndpointResponse, error) { + if w == nil { + return nil, nil + } + choicesPublicValue, err := convertSlice(w.Choices, v1ResponseChoiceElementFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryEndpointResponse.Choices", err) + } + dataPublicValue, err := convertSlice(w.Data, embeddingsV1ResponseEmbeddingElementFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryEndpointResponse.Data", err) + } + usagePublicValue, err := externalModelUsageElementFromWire(w.Usage) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryEndpointResponse.Usage", err) + } + return &QueryEndpointResponse{ + Choices: choicesPublicValue, + Data: dataPublicValue, + Model: w.Model, + Usage: usagePublicValue, + Id: w.Id, + Created: w.Created, + Object: w.Object, + Predictions: w.Predictions, + Outputs: w.Outputs, + }, nil +} + +type v1ResponseChoiceElementWire struct { + Text *string `json:"text,omitempty"` + Message *chatMessageWire `json:"message,omitempty"` + Index *int `json:"index,omitempty"` + FinishReason *string `json:"finishReason,omitempty"` + Logprobs *int `json:"logprobs,omitempty"` +} + +func v1ResponseChoiceElementFromWire(w *v1ResponseChoiceElementWire) (*V1ResponseChoiceElement, error) { + if w == nil { + return nil, nil + } + messagePublicValue, err := chatMessageFromWire(w.Message) + if err != nil { + return nil, fmt.Errorf("%s: %w", "V1ResponseChoiceElement.Message", err) + } + return &V1ResponseChoiceElement{ + Text: w.Text, + Message: messagePublicValue, + Index: w.Index, + FinishReason: w.FinishReason, + Logprobs: w.Logprobs, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/networking/.package.json b/networking/.package.json new file mode 100644 index 0000000..ef4b493 --- /dev/null +++ b/networking/.package.json @@ -0,0 +1,3 @@ +{ + "package": "networking" +} diff --git a/networking/CHANGELOG.md b/networking/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/networking/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/networking/README.md b/networking/README.md new file mode 100644 index 0000000..768ab8e --- /dev/null +++ b/networking/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/networking + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/networking@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/networking/v1" + +client, err := networking.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/networking/go.mod b/networking/go.mod new file mode 100644 index 0000000..46988f8 --- /dev/null +++ b/networking/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/networking + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/networking/internal/version.go b/networking/internal/version.go new file mode 100644 index 0000000..f625ee2 --- /dev/null +++ b/networking/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-networking" + +const Version = "0.0.1-dev.1" diff --git a/networking/v1/client.go b/networking/v1/client.go new file mode 100755 index 0000000..92dc82a --- /dev/null +++ b/networking/v1/client.go @@ -0,0 +1,3411 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package networking + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/networking/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates an IP access list for the account. +// +// A list can be an allow list or a block list. See the top of this file for a +// description of how the server treats allow lists and block lists at runtime. +// +// When creating or updating an IP access list: +// +// * For all allow lists and block lists combined, the API supports a maximum of +// 1000 IP/CIDR values, where one CIDR counts as a single value. Attempts to +// exceed that number return error 400 with `error_code` value `QUOTA_EXCEEDED`. +// * If the new list would block the calling user's current IP, error 400 is +// returned with `error_code` value `INVALID_STATE`. +// +// It can take a few minutes for the changes to take effect. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateAccountIpAccessList(ctx context.Context, req *CreateAccountIpAccessListRequest, opts ...call.Option) (*CreateAccountIpAccessListResponse, error) { + wireReq, err := createAccountIpAccessListRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/ip-access-lists") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateAccountIpAccessListResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createAccountIpAccessListResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createAccountIpAccessListResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes an IP access list, specified by its list ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteAccountIpAccessList(ctx context.Context, req *DeleteAccountIpAccessListRequest, opts ...call.Option) (*DeleteAccountIpAccessListResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/ip-access-lists/") + pb.singleSegment(*req.ListId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteAccountIpAccessListResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteAccountIpAccessListResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an IP access list, specified by its list ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetAccountIpAccessList(ctx context.Context, req *GetAccountIpAccessListRequest, opts ...call.Option) (*GetAccountIpAccessListResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/ip-access-lists/") + pb.singleSegment(*req.ListId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetAccountIpAccessListResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getAccountIpAccessListResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getAccountIpAccessListResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets all IP access lists for the specified account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListAccountIpAccessLists(ctx context.Context, req *ListAccountIpAccessListsRequest, opts ...call.Option) (*ListAccountIpAccessListsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/ip-access-lists") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAccountIpAccessListsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAccountIpAccessListsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAccountIpAccessListsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Replaces an IP access list, specified by its ID. +// +// A list can include allow lists and block lists. See the top of this file for +// a description of how the server treats allow lists and block lists at run +// time. When replacing an IP access list: * For all allow lists and block lists +// combined, the API supports a maximum of 1000 IP/CIDR values, where one CIDR +// counts as a single value. Attempts to exceed that number return error 400 +// with `error_code` value `QUOTA_EXCEEDED`. * If the resulting list would block +// the calling user's current IP, error 400 is returned with `error_code` value +// `INVALID_STATE`. It can take a few minutes for the changes to take effect. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ReplaceAccountIpAccessList(ctx context.Context, req *ReplaceAccountIpAccessListRequest, opts ...call.Option) (*ReplaceAccountIpAccessListResponse, error) { + wireReq, err := replaceAccountIpAccessListRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/ip-access-lists/") + pb.singleSegment(*req.ListId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ReplaceAccountIpAccessListResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp replaceAccountIpAccessListResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = replaceAccountIpAccessListResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an existing IP access list, specified by its ID. +// +// A list can include allow lists and block lists. See the top of this file for +// a description of how the server treats allow lists and block lists at run +// time. +// +// When updating an IP access list: +// +// * For all allow lists and block lists combined, the API supports a maximum of +// 1000 IP/CIDR values, where one CIDR counts as a single value. Attempts to +// exceed that number return error 400 with `error_code` value `QUOTA_EXCEEDED`. +// * If the updated list would block the calling user's current IP, error 400 is +// returned with `error_code` value `INVALID_STATE`. +// +// It can take a few minutes for the changes to take effect. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateAccountIpAccessList(ctx context.Context, req *UpdateAccountIpAccessListRequest, opts ...call.Option) (*UpdateAccountIpAccessListResponse, error) { + wireReq, err := updateAccountIpAccessListRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/ip-access-lists/") + pb.singleSegment(*req.ListId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateAccountIpAccessListResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateAccountIpAccessListResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateAccountIpAccessListResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new network connectivity endpoint that enables private connectivity +// between your network resources and services. +// +// After creation, the endpoint is initially in the PENDING state. The +// endpoint service automatically reviews and approves the endpoint +// within a few minutes. Use the GET method to retrieve the latest endpoint +// state. +// +// An endpoint can be used only after it reaches the APPROVED state. +func (c *internalClient) CreateEndpoint(ctx context.Context, req *CreateEndpointRequest, opts ...call.Option) (*Endpoint, error) { + wireReq, err := createEndpointRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Endpoint) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/networking/v1/") + pb.singleSegment(*req.Parent) + pb.literal("/endpoints") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Endpoint + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp endpointWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = endpointFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a network endpoint. This will remove the endpoint configuration from +// . Depending on the endpoint type and use case, you may also need +// to delete corresponding network resources in your cloud provider account. +func (c *internalClient) DeleteEndpoint(ctx context.Context, req *DeleteEndpointRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/networking/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets details of a specific network endpoint. +func (c *internalClient) GetEndpoint(ctx context.Context, req *GetEndpointRequest, opts ...call.Option) (*Endpoint, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/networking/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Endpoint + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp endpointWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = endpointFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists all network connectivity endpoints for the account. +func (c *internalClient) ListEndpoints(ctx context.Context, req *ListEndpointsRequest, opts ...call.Option) (*ListEndpointsResponse, error) { + wireReq, err := listEndpointsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/networking/v1/") + pb.singleSegment(*req.Parent) + pb.literal("/endpoints") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListEndpointsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listEndpointsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listEndpointsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListEndpointsIter returns an iterator that iterates +// over the results of ListEndpoints. +// +// For example: +// +// for item, err := range c.ListEndpointsIter(ctx, &ListEndpointsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListEndpoints call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListEndpoints directly. +func (c *internalClient) ListEndpointsIter(ctx context.Context, req *ListEndpointsRequest, opts ...call.Option) iter.Seq2[*Endpoint, error] { + return func(yield func(*Endpoint, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListEndpointsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListEndpoints(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Items { + if !yield(&resp.Items[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Creates an IP access list for this workspace. +// +// A list can be an allow list or a block list. See the top of this file for a +// description of how the server treats allow lists and block lists at runtime. +// +// When creating or updating an IP access list: +// +// * For all allow lists and block lists combined, the API supports a maximum of +// 1000 IP/CIDR values, where one CIDR counts as a single value. Attempts to +// exceed that number return error 400 with `error_code` value `QUOTA_EXCEEDED`. +// * If the new list would block the calling user's current IP, error 400 is +// returned with `error_code` value `INVALID_STATE`. +// +// It can take a few minutes for the changes to take effect. **Note**: Your new +// IP access list has no effect until you enable the feature. See +// [workspaceconf/setStatus] +// +// [workspaceconf/setStatus]: https://docs.databricks.com/api/workspace/workspaceconf/setstatus +func (c *internalClient) CreateIpAccessList(ctx context.Context, req *CreateIpAccessListRequest, opts ...call.Option) (*CreateIpAccessListResponse, error) { + wireReq, err := createIpAccessListRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/ip-access-lists" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateIpAccessListResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createIpAccessListResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createIpAccessListResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes an IP access list, specified by its list ID. +func (c *internalClient) DeleteIpAccessList(ctx context.Context, req *DeleteIpAccessListRequest, opts ...call.Option) (*DeleteIpAccessListResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/ip-access-lists/") + pb.singleSegment(*req.ListId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteIpAccessListResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteIpAccessListResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an IP access list, specified by its list ID. +func (c *internalClient) GetIpAccessList(ctx context.Context, req *GetIpAccessListRequest, opts ...call.Option) (*GetIpAccessListResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/ip-access-lists/") + pb.singleSegment(*req.ListId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetIpAccessListResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getIpAccessListResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getIpAccessListResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets all IP access lists for the specified workspace. +func (c *internalClient) ListIpAccessLists(ctx context.Context, req *ListIpAccessLists, opts ...call.Option) (*ListIpAccessListsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/ip-access-lists" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListIpAccessListsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listIpAccessListsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listIpAccessListsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Replaces an IP access list, specified by its ID. +// +// A list can include allow lists and block lists. See the top of this file for +// a description of how the server treats allow lists and block lists at run +// time. When replacing an IP access list: * For all allow lists and block lists +// combined, the API supports a maximum of 1000 IP/CIDR values, where one CIDR +// counts as a single value. Attempts to exceed that number return error 400 +// with `error_code` value `QUOTA_EXCEEDED`. * If the resulting list would block +// the calling user's current IP, error 400 is returned with `error_code` value +// `INVALID_STATE`. It can take a few minutes for the changes to take effect. +// Note that your resulting IP access list has no effect until you enable the +// feature. See [workspaceconf/setStatus]. +// +// [workspaceconf/setStatus]: https://docs.databricks.com/api/workspace/workspaceconf/setstatus +func (c *internalClient) ReplaceIpAccessList(ctx context.Context, req *ReplaceIpAccessListRequest, opts ...call.Option) (*ReplaceIpAccessListResponse, error) { + wireReq, err := replaceIpAccessListRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/ip-access-lists/") + pb.singleSegment(*req.ListId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ReplaceIpAccessListResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp replaceIpAccessListResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = replaceIpAccessListResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an existing IP access list, specified by its ID. +// +// A list can include allow lists and block lists. See the top of this file for +// a description of how the server treats allow lists and block lists at run +// time. +// +// When updating an IP access list: +// +// * For all allow lists and block lists combined, the API supports a maximum of +// 1000 IP/CIDR values, where one CIDR counts as a single value. Attempts to +// exceed that number return error 400 with `error_code` value `QUOTA_EXCEEDED`. +// * If the updated list would block the calling user's current IP, error 400 is +// returned with `error_code` value `INVALID_STATE`. +// +// It can take a few minutes for the changes to take effect. Note that your +// resulting IP access list has no effect until you enable the feature. See +// [workspaceconf/setStatus]. +// +// [workspaceconf/setStatus]: https://docs.databricks.com/api/workspace/workspaceconf/setstatus +func (c *internalClient) UpdateIpAccessList(ctx context.Context, req *UpdateIpAccessListRequest, opts ...call.Option) (*UpdateIpAccessListResponse, error) { + wireReq, err := updateIpAccessListRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/ip-access-lists/") + pb.singleSegment(*req.ListId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateIpAccessListResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateIpAccessListResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateIpAccessListResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a network connectivity configuration (NCC), which provides stable +// Azure service subnets when accessing your Azure Storage accounts. You can +// also use a network connectivity configuration to create managed +// private endpoints so that serverless compute resources privately +// access your resources. +// +// **IMPORTANT**: After you create the network connectivity configuration, you +// must assign one or more workspaces to the new network connectivity +// configuration. You can share one network connectivity configuration with +// multiple workspaces from the same Azure region within the same +// account. See [configure serverless secure connectivity]. +// +// [configure serverless secure connectivity]: https://learn.microsoft.com/azure/databricks/security/network/serverless-network-security +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateNetworkConnectivityConfigPublic(ctx context.Context, req *CreateNetworkConnectivityConfigRequest, opts ...call.Option) (*NetworkConnectivityConfig, error) { + wireReq, err := createNetworkConnectivityConfigRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.NetworkConnectivityConfig) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-connectivity-configs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *NetworkConnectivityConfig + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp networkConnectivityConfigWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = networkConnectivityConfigFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a network connectivity configuration. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteNetworkConnectivityConfigPublic(ctx context.Context, req *DeleteNetworkConnectivityConfigRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-connectivity-configs/") + pb.singleSegment(*req.NetworkConnectivityConfigId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets a network connectivity configuration. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetNetworkConnectivityConfigPublic(ctx context.Context, req *GetNetworkConnectivityConfigRequest, opts ...call.Option) (*NetworkConnectivityConfig, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-connectivity-configs/") + pb.singleSegment(*req.NetworkConnectivityConfigId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *NetworkConnectivityConfig + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp networkConnectivityConfigWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = networkConnectivityConfigFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of network connectivity configurations. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListNetworkConnectivityConfigsPublic(ctx context.Context, req *ListNetworkConnectivityConfigsRequest, opts ...call.Option) (*ListNetworkConnectivityConfigsResponse, error) { + wireReq, err := listNetworkConnectivityConfigsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-connectivity-configs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListNetworkConnectivityConfigsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listNetworkConnectivityConfigsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listNetworkConnectivityConfigsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListNetworkConnectivityConfigsPublicIter returns an iterator that iterates +// over the results of ListNetworkConnectivityConfigsPublic. +// +// For example: +// +// for item, err := range c.ListNetworkConnectivityConfigsPublicIter(ctx, &ListNetworkConnectivityConfigsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListNetworkConnectivityConfigsPublic call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListNetworkConnectivityConfigsPublic directly. +func (c *internalClient) ListNetworkConnectivityConfigsPublicIter(ctx context.Context, req *ListNetworkConnectivityConfigsRequest, opts ...call.Option) iter.Seq2[*NetworkConnectivityConfig, error] { + return func(yield func(*NetworkConnectivityConfig, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListNetworkConnectivityConfigsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListNetworkConnectivityConfigsPublic(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Items { + if !yield(&resp.Items[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Create a private endpoint rule for the specified network connectivity config +// object. Once the object is created, asynchronously provisions a +// new Azure private endpoint to your specified Azure resource. +// +// **IMPORTANT**: You must use Azure portal or other Azure tools to approve the +// private endpoint to complete the connection. To get the information of the +// private endpoint created, make a `GET` request on the new private endpoint +// rule. See [serverless private link]. +// +// [serverless private link]: https://learn.microsoft.com/azure/databricks/security/network/serverless-network-security/serverless-private-link +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateNccPrivateEndpointRule(ctx context.Context, req *CreateNccPrivateEndpointRuleRequest, opts ...call.Option) (*NccPrivateEndpointRule, error) { + wireReq, err := createNccPrivateEndpointRuleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.PrivateEndpointRule) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-connectivity-configs/") + pb.singleSegment(*req.NetworkConnectivityConfigId) + pb.literal("/private-endpoint-rules") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *NccPrivateEndpointRule + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp nccPrivateEndpointRuleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = nccPrivateEndpointRuleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Initiates deleting a private endpoint rule. If the connection state is +// PENDING or EXPIRED, the private endpoint is immediately deleted. Otherwise, +// the private endpoint is deactivated and will be deleted after one day of +// deactivation. When a private endpoint is deactivated, the `deactivated` field +// is set to `true` and the private endpoint is not available to your serverless +// compute resources. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteNccPrivateEndpointRule(ctx context.Context, req *DeleteNccPrivateEndpointRuleRequest, opts ...call.Option) (*NccPrivateEndpointRule, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-connectivity-configs/") + pb.singleSegment(*req.NetworkConnectivityConfigId) + pb.literal("/private-endpoint-rules/") + pb.singleSegment(*req.PrivateEndpointRuleId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *NccPrivateEndpointRule + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp nccPrivateEndpointRuleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = nccPrivateEndpointRuleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the private endpoint rule. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetNccPrivateEndpointRule(ctx context.Context, req *GetNccPrivateEndpointRuleRequest, opts ...call.Option) (*NccPrivateEndpointRule, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-connectivity-configs/") + pb.singleSegment(*req.NetworkConnectivityConfigId) + pb.literal("/private-endpoint-rules/") + pb.singleSegment(*req.PrivateEndpointRuleId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *NccPrivateEndpointRule + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp nccPrivateEndpointRuleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = nccPrivateEndpointRuleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of private endpoint rules. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListNccPrivateEndpointRules(ctx context.Context, req *ListNccPrivateEndpointRulesRequest, opts ...call.Option) (*ListNccPrivateEndpointRulesResponse, error) { + wireReq, err := listNccPrivateEndpointRulesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-connectivity-configs/") + pb.singleSegment(*req.NetworkConnectivityConfigId) + pb.literal("/private-endpoint-rules") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListNccPrivateEndpointRulesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listNccPrivateEndpointRulesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listNccPrivateEndpointRulesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListNccPrivateEndpointRulesIter returns an iterator that iterates +// over the results of ListNccPrivateEndpointRules. +// +// For example: +// +// for item, err := range c.ListNccPrivateEndpointRulesIter(ctx, &ListNccPrivateEndpointRulesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListNccPrivateEndpointRules call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListNccPrivateEndpointRules directly. +func (c *internalClient) ListNccPrivateEndpointRulesIter(ctx context.Context, req *ListNccPrivateEndpointRulesRequest, opts ...call.Option) iter.Seq2[*NccPrivateEndpointRule, error] { + return func(yield func(*NccPrivateEndpointRule, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListNccPrivateEndpointRulesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListNccPrivateEndpointRules(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Items { + if !yield(&resp.Items[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates a private endpoint rule. Currently only a private endpoint rule to +// customer-managed resources is allowed to be updated. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateNccPrivateEndpointRule(ctx context.Context, req *UpdateNccPrivateEndpointRuleRequest, opts ...call.Option) (*NccPrivateEndpointRule, error) { + wireReq, err := updateNccPrivateEndpointRuleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.PrivateEndpointRule) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-connectivity-configs/") + pb.singleSegment(*req.NetworkConnectivityConfigId) + pb.literal("/private-endpoint-rules/") + pb.singleSegment(*req.PrivateEndpointRuleId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *NccPrivateEndpointRule + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp nccPrivateEndpointRuleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = nccPrivateEndpointRuleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new network policy to manage which network destinations can be +// accessed from the environment. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateNetworkPolicyRpc(ctx context.Context, req *CreateNetworkPolicyRequest, opts ...call.Option) (*AccountNetworkPolicy, error) { + wireReq, err := createNetworkPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.NetworkPolicy) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-policies") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountNetworkPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountNetworkPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountNetworkPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a network policy. Cannot be called on 'default-policy'. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteNetworkPolicyRpc(ctx context.Context, req *DeleteNetworkPolicyRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-policies/") + pb.singleSegment(*req.NetworkPolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets a network policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetNetworkPolicyRpc(ctx context.Context, req *GetNetworkPolicyRequest, opts ...call.Option) (*AccountNetworkPolicy, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-policies/") + pb.singleSegment(*req.NetworkPolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountNetworkPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountNetworkPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountNetworkPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of network policies. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListNetworkPoliciesRpc(ctx context.Context, req *ListNetworkPoliciesRequest, opts ...call.Option) (*ListNetworkPoliciesResponse, error) { + wireReq, err := listNetworkPoliciesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-policies") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListNetworkPoliciesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listNetworkPoliciesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listNetworkPoliciesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListNetworkPoliciesRpcIter returns an iterator that iterates +// over the results of ListNetworkPoliciesRpc. +// +// For example: +// +// for item, err := range c.ListNetworkPoliciesRpcIter(ctx, &ListNetworkPoliciesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListNetworkPoliciesRpc call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListNetworkPoliciesRpc directly. +func (c *internalClient) ListNetworkPoliciesRpcIter(ctx context.Context, req *ListNetworkPoliciesRequest, opts ...call.Option) iter.Seq2[*AccountNetworkPolicy, error] { + return func(yield func(*AccountNetworkPolicy, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListNetworkPoliciesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListNetworkPoliciesRpc(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Items { + if !yield(&resp.Items[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates a network policy. This allows you to modify the configuration of a +// network policy. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateNetworkPolicyRpc(ctx context.Context, req *UpdateNetworkPolicyRequest, opts ...call.Option) (*AccountNetworkPolicy, error) { + wireReq, err := updateNetworkPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.NetworkPolicy) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/network-policies/") + pb.singleSegment(*req.NetworkPolicyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountNetworkPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountNetworkPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountNetworkPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a network configuration that represents an VPC and its +// resources. The VPC will be used for new clusters. This requires +// a pre-existing VPC and subnets. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateNetworkPublic(ctx context.Context, req *CreateNetworkRequest, opts ...call.Option) (*Network, error) { + wireReq, err := createNetworkRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/networks") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Network + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp networkWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = networkFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a private access settings configuration, which represents network +// access restrictions for workspace resources. Private access settings +// configure whether workspaces can be accessed from the public internet or only +// from private endpoints. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreatePrivateAccessSettingsPublic(ctx context.Context, req *CreatePrivateAccessSettingsRequest, opts ...call.Option) (*PrivateAccessSettings, error) { + wireReq, err := createPrivateAccessSettingsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/private-access-settings") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PrivateAccessSettings + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp privateAccessSettingsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = privateAccessSettingsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a VPC endpoint configuration, which represents a [VPC endpoint] +// object in AWS used to communicate privately with over [AWS +// PrivateLink]. +// +// After you create the VPC endpoint configuration, the [endpoint +// service] automatically accepts the VPC endpoint. +// +// Before configuring PrivateLink, read the [ article about +// PrivateLink]. +// +// [ article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html +// [AWS PrivateLink]: https://aws.amazon.com/privatelink +// [VPC endpoint]: https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints.html +// [endpoint service]: https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-share-your-services.html +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateVpcEndpointPublic(ctx context.Context, req *CreateVpcEndpointRequest, opts ...call.Option) (*VpcEndpoint, error) { + wireReq, err := createVpcEndpointRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/vpc-endpoints") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *VpcEndpoint + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp vpcEndpointWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = vpcEndpointFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a network configuration, which represents a cloud VPC +// and its resources. You cannot delete a network that is associated with a +// workspace. +// +// This operation is available only if your account is on the E2 version of the +// platform. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteNetworkPublic(ctx context.Context, req *DeleteNetworkRequest, opts ...call.Option) (*Network, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/networks/") + pb.singleSegment(*req.NetworkId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Network + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp networkWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = networkFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a private access settings configuration, both specified +// by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeletePrivateAccessSettingsPublic(ctx context.Context, req *DeletePrivateAccessSettingsRequest, opts ...call.Option) (*PrivateAccessSettings, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/private-access-settings/") + pb.singleSegment(*req.PrivateAccessSettingsId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PrivateAccessSettings + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp privateAccessSettingsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = privateAccessSettingsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a Databricks VPC endpoint configuration. You cannot delete a VPC +// endpoint configuration that is associated with any workspace. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteVpcEndpointPublic(ctx context.Context, req *DeleteVpcEndpointRequest, opts ...call.Option) (*VpcEndpoint, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/vpc-endpoints/") + pb.singleSegment(*req.VpcEndpointId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *VpcEndpoint + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp vpcEndpointWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = vpcEndpointFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a network configuration, which represents a cloud VPC and +// its resources. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetNetworkPublic(ctx context.Context, req *GetNetworkRequest, opts ...call.Option) (*Network, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/networks/") + pb.singleSegment(*req.NetworkId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Network + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp networkWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = networkFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a private access settings configuration, both specified by +// ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetPrivateAccessSettingsPublic(ctx context.Context, req *GetPrivateAccessSettingsRequest, opts ...call.Option) (*PrivateAccessSettings, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/private-access-settings/") + pb.singleSegment(*req.PrivateAccessSettingsId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PrivateAccessSettings + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp privateAccessSettingsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = privateAccessSettingsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a VPC endpoint configuration, which represents a [VPC endpoint] object +// in AWS used to communicate privately with over [AWS +// PrivateLink]. +// +// [AWS PrivateLink]: https://aws.amazon.com/privatelink +// [VPC endpoint]: https://docs.aws.amazon.com/vpc/latest/privatelink/concepts.html +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetVpcEndpointPublic(ctx context.Context, req *GetVpcEndpointRequest, opts ...call.Option) (*VpcEndpoint, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/vpc-endpoints/") + pb.singleSegment(*req.VpcEndpointId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *VpcEndpoint + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp vpcEndpointWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = vpcEndpointFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists network configurations for an account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListNetworkPublic(ctx context.Context, req *ListNetworkRequest, opts ...call.Option) (*ListNetworkResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/networks") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListNetworkResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp []networkWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + convertedResponseBody, err := convertSlice(wireResp, networkFromWire) + if err != nil { + return fmt.Errorf("ListNetworkResponse.Networks: %w", err) + } + resp = &ListNetworkResponse{ + Networks: convertedResponseBody, + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists private access settings for an account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListPrivateAccessSettingsPublic(ctx context.Context, req *ListPrivateAccessSettingsRequest, opts ...call.Option) (*ListPrivateAccessSettingsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/private-access-settings") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPrivateAccessSettingsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp []privateAccessSettingsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + convertedResponseBody, err := convertSlice(wireResp, privateAccessSettingsFromWire) + if err != nil { + return fmt.Errorf("ListPrivateAccessSettingsResponse.PrivateAccessSettings: %w", err) + } + resp = &ListPrivateAccessSettingsResponse{ + PrivateAccessSettings: convertedResponseBody, + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists Databricks VPC endpoint configurations for an account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListVpcEndpointPublic(ctx context.Context, req *ListVpcEndpointRequest, opts ...call.Option) (*ListVpcEndpointResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/vpc-endpoints") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListVpcEndpointResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp []vpcEndpointWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + convertedResponseBody, err := convertSlice(wireResp, vpcEndpointFromWire) + if err != nil { + return fmt.Errorf("ListVpcEndpointResponse.VpcEndpoints: %w", err) + } + resp = &ListVpcEndpointResponse{ + VpcEndpoints: convertedResponseBody, + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an existing private access settings object, which specifies how your +// workspace is accessed over AWS PrivateLink. To use AWS PrivateLink, a +// workspace must have a private access settings object referenced by ID in the +// workspace's private_access_settings_id property. This operation completely +// overwrites your existing private access settings object attached to your +// workspaces. All workspaces attached to the private access settings are +// affected by any change. If public_access_enabled, private_access_level, or +// allowed_vpc_endpoint_ids are updated, effects of these changes might take +// several minutes to propagate to the workspace API. You can share one private +// access settings object with multiple workspaces in a single account. However, +// private access settings are specific to AWS regions, so only workspaces in +// the same AWS region can use a given private access settings object. Before +// configuring PrivateLink, read the article about PrivateLink. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdatePrivateAccessSettingsPublic(ctx context.Context, req *UpdatePrivateAccessSettingsRequest, opts ...call.Option) (*PrivateAccessSettings, error) { + wireReq, err := updatePrivateAccessSettingsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.CustomerFacingPrivateAccessSettings) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/private-access-settings/") + pb.singleSegment(*req.CustomerFacingPrivateAccessSettings.PrivateAccessSettingsId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PrivateAccessSettings + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp privateAccessSettingsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = privateAccessSettingsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the network option for a workspace. Every workspace has exactly one +// network policy binding, with 'default-policy' used if no explicit assignment +// exists. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetWorkspaceNetworkOptionRpc(ctx context.Context, req *GetWorkspaceNetworkOptionRequest, opts ...call.Option) (*WorkspaceNetworkOption, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/network") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *WorkspaceNetworkOption + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp workspaceNetworkOptionWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = workspaceNetworkOptionFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the network option for a workspace. This operation associates the +// workspace with the specified network policy. To revert to the default policy, +// specify 'default-policy' as the network_policy_id. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateWorkspaceNetworkOptionRpc(ctx context.Context, req *UpdateWorkspaceNetworkOptionRequest, opts ...call.Option) (*WorkspaceNetworkOption, error) { + wireReq, err := updateWorkspaceNetworkOptionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.WorkspaceNetworkOption) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/network") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *WorkspaceNetworkOption + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp workspaceNetworkOptionWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = workspaceNetworkOptionFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/networking/v1/genhelper.go b/networking/v1/genhelper.go new file mode 100755 index 0000000..3aadb38 --- /dev/null +++ b/networking/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package networking + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/networking/v1/model.go b/networking/v1/model.go new file mode 100755 index 0000000..438d17b --- /dev/null +++ b/networking/v1/model.go @@ -0,0 +1,1986 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package networking + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// The target resources that are supported by Network Connectivity Config. Note: +// some egress types can support general types that are not defined in +// EgressResourceType. E.g.: Azure private endpoint supports private link +// enabled Azure services. +type EgressResourceType string + +const ( + EgressResourceType_Unspecified EgressResourceType = "" + EgressResourceType_AzureBlobStorage EgressResourceType = "AZURE_BLOB_STORAGE" +) + +type EndpointState string + +const ( + EndpointState_Unspecified EndpointState = "" + // The endpoint is pending approval. + EndpointState_Pending EndpointState = "PENDING" + // The endpoint has been approved and is ready for use. + EndpointState_Approved EndpointState = "APPROVED" + // The endpoint encountered some issues during setup. + EndpointState_Failed EndpointState = "FAILED" + // The endpoint was once established but later disconnected. This endpoint + // doesn't provide connectivity. + EndpointState_Disconnected EndpointState = "DISCONNECTED" +) + +// Type of IP access list. Valid values are as follows and are case-sensitive: +// +// * `ALLOW`: An allow list. Include this IP or range. * `BLOCK`: A block list. +// Exclude this IP or range. IP addresses in the block list are excluded even if +// they are included in an allow list. +type IpAccessListType string + +const ( + IpAccessListType_Unspecified IpAccessListType = "" + IpAccessListType_Allow IpAccessListType = "ALLOW" + // Blocks the associated CIDRs. + IpAccessListType_Block IpAccessListType = "BLOCK" +) + +type PrivateAccessLevel string + +const ( + PrivateAccessLevel_Unspecified PrivateAccessLevel = "" + // Only specifically listed endpoints can access my workspace + PrivateAccessLevel_Endpoint PrivateAccessLevel = "ENDPOINT" + // Only endpoints in the same account can access my workspace + PrivateAccessLevel_Account PrivateAccessLevel = "ACCOUNT" +) + +type VpcEndpointUseCase string + +const ( + VpcEndpointUseCase_Unspecified VpcEndpointUseCase = "" + VpcEndpointUseCase_WorkspaceAccess VpcEndpointUseCase = "WORKSPACE_ACCESS" + VpcEndpointUseCase_DataplaneRelayAccess VpcEndpointUseCase = "DATAPLANE_RELAY_ACCESS" + // General access, replaces WORKSPACE_ACCESS in customer-facing API. + VpcEndpointUseCase_GeneralAccess VpcEndpointUseCase = "GENERAL_ACCESS" +) + +type VpcStatus string + +const ( + VpcStatus_Unspecified VpcStatus = "" + VpcStatus_Valid VpcStatus = "VALID" + VpcStatus_Broken VpcStatus = "BROKEN" + VpcStatus_Unattached VpcStatus = "UNATTACHED" + // Some optional tests are failing for this Vpc, see NetworkWarning for more + // information + VpcStatus_Warned VpcStatus = "WARNED" +) + +// Type of IP access list. Valid values are as follows and are case-sensitive: +// +// * `ALLOW`: An allow list. Include this IP or range. * `BLOCK`: A block list. +// Exclude this IP or range. IP addresses in the block list are excluded even if +// they are included in an allow list. +type AccountIpAccessListType_IpAccessListType string + +const ( + AccountIpAccessListType_IpAccessListType_Unspecified AccountIpAccessListType_IpAccessListType = "" + // Allows the associated CIDRs. + AccountIpAccessListType_IpAccessListType_Allow AccountIpAccessListType_IpAccessListType = "ALLOW" + // Blocks the associated CIDRs. + AccountIpAccessListType_IpAccessListType_Block AccountIpAccessListType_IpAccessListType = "BLOCK" +) + +type EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination_InternetDestinationType string + +const ( + EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination_InternetDestinationType_Unspecified EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination_InternetDestinationType = "" + // This is defined as `FQDN` in settings-policy/api/proto/messages.proto. + // Translation is done in + // accounts-lake-net-manager/src/util/NetworkPolicySettingUtil.scala. + EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination_InternetDestinationType_DnsName EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination_InternetDestinationType = "DNS_NAME" +) + +// The values should match the list of workloads used in networkconfig.proto +type EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_DryRunModeProductFilter string + +const ( + EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_DryRunModeProductFilter_Unspecified EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_DryRunModeProductFilter = "" + // SQL Warehouse product + EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_DryRunModeProductFilter_Dbsql EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_DryRunModeProductFilter = "DBSQL" + // Machine Learning serving product + EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_DryRunModeProductFilter_MlServing EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_DryRunModeProductFilter = "ML_SERVING" +) + +type EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_EnforcementMode string + +const ( + EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_EnforcementMode_Unspecified EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_EnforcementMode = "" + // Blocks traffic that violates network policy. This is the default mode. + EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_EnforcementMode_Enforced EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_EnforcementMode = "ENFORCED" + // Logs violations without blocking traffic. Useful for testing policies before + // enforcement. + EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_EnforcementMode_DryRun EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_EnforcementMode = "DRY_RUN" +) + +// At which level can and managed compute access +// Internet. FULL_ACCESS: can access Internet. No blocking rules +// will apply. RESTRICTED_ACCESS: can only access explicitly +// allowed internet and storage destinations, as well as UC connections and +// external locations. +type EgressNetworkPolicy_NetworkAccessPolicy_RestrictionMode string + +const ( + EgressNetworkPolicy_NetworkAccessPolicy_RestrictionMode_Unspecified EgressNetworkPolicy_NetworkAccessPolicy_RestrictionMode = "" + EgressNetworkPolicy_NetworkAccessPolicy_RestrictionMode_FullAccess EgressNetworkPolicy_NetworkAccessPolicy_RestrictionMode = "FULL_ACCESS" + EgressNetworkPolicy_NetworkAccessPolicy_RestrictionMode_RestrictedAccess EgressNetworkPolicy_NetworkAccessPolicy_RestrictionMode = "RESTRICTED_ACCESS" +) + +type EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType string + +const ( + EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType_Unspecified EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType = "" + // AWS_S3 can be used both for direct AWS S3 access and for cross-cloud access + // from Azure and GCP When used in an Azure/GCP context, this indicates + // cross-cloud access from Azure/GCP to the specified S3 bucket + EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType_AwsS3 EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType = "AWS_S3" + EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType_AzureStorage EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType = "AZURE_STORAGE" + EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType_GoogleCloudStorage EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType = "GOOGLE_CLOUD_STORAGE" +) + +type EndpointUseCase_EndpointUseCase string + +const ( + EndpointUseCase_EndpointUseCase_Unspecified EndpointUseCase_EndpointUseCase = "" + // service-direct frontend private link connectivity. + EndpointUseCase_EndpointUseCase_ServiceDirect EndpointUseCase_EndpointUseCase = "SERVICE_DIRECT" +) + +// Qualifies the breadth of API access permitted by an ingress network policy +// rule. API_SCOPE_QUALIFIER_READ narrows matching to read-only variants of the +// listed scopes; API_SCOPE_QUALIFIER_ALL matches any scope. When unset, scopes +// match exactly as listed. +type IngressNetworkPolicy_ApiScopeQualifier string + +const ( + IngressNetworkPolicy_ApiScopeQualifier_Unspecified IngressNetworkPolicy_ApiScopeQualifier = "" + // Narrows matching to read-only variants of the listed scopes (e.g. GET/HEAD + // requests). + IngressNetworkPolicy_ApiScopeQualifier_ApiScopeQualifierRead IngressNetworkPolicy_ApiScopeQualifier = "API_SCOPE_QUALIFIER_READ" + // Matches any scope regardless of access level. + IngressNetworkPolicy_ApiScopeQualifier_ApiScopeQualifierAll IngressNetworkPolicy_ApiScopeQualifier = "API_SCOPE_QUALIFIER_ALL" +) + +type IngressNetworkPolicy_Authentication_IdentityType string + +const ( + IngressNetworkPolicy_Authentication_IdentityType_Unspecified IngressNetworkPolicy_Authentication_IdentityType = "" + IngressNetworkPolicy_Authentication_IdentityType_IdentityTypeAllUsers IngressNetworkPolicy_Authentication_IdentityType = "IDENTITY_TYPE_ALL_USERS" + IngressNetworkPolicy_Authentication_IdentityType_IdentityTypeAllServicePrincipals IngressNetworkPolicy_Authentication_IdentityType = "IDENTITY_TYPE_ALL_SERVICE_PRINCIPALS" + IngressNetworkPolicy_Authentication_IdentityType_IdentityTypeSelectedIdentities IngressNetworkPolicy_Authentication_IdentityType = "IDENTITY_TYPE_SELECTED_IDENTITIES" +) + +type IngressNetworkPolicy_AuthenticationIdentity_PrincipalType string + +const ( + IngressNetworkPolicy_AuthenticationIdentity_PrincipalType_Unspecified IngressNetworkPolicy_AuthenticationIdentity_PrincipalType = "" + IngressNetworkPolicy_AuthenticationIdentity_PrincipalType_PrincipalTypeUser IngressNetworkPolicy_AuthenticationIdentity_PrincipalType = "PRINCIPAL_TYPE_USER" + IngressNetworkPolicy_AuthenticationIdentity_PrincipalType_PrincipalTypeServicePrincipal IngressNetworkPolicy_AuthenticationIdentity_PrincipalType = "PRINCIPAL_TYPE_SERVICE_PRINCIPAL" +) + +type IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode string + +const ( + IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode_Unspecified IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode = "" + IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode_FullAccess IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode = "FULL_ACCESS" + IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode_RestrictedAccess IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode = "RESTRICTED_ACCESS" + // Cross-workspace ingress is not governed by this policy. Traffic from other + // workspaces is subject only to the workspace's pre-existing network controls, + // not to the allow and deny rules configured here. + IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode_LegacyMode IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode = "LEGACY_MODE" +) + +// The restriction mode for private access. In ALLOW_ALL_REGISTERED_ENDPOINTS +// mode, requests arriving through any endpoint registered to the account are +// allowed, and deny rules and allow rules cannot be set. In RESTRICTED_ACCESS +// mode, access is restricted based on deny rules and allow rules; requests that +// do not match any allow rule are denied. +type IngressNetworkPolicy_PrivateAccess_RestrictionMode string + +const ( + IngressNetworkPolicy_PrivateAccess_RestrictionMode_Unspecified IngressNetworkPolicy_PrivateAccess_RestrictionMode = "" + // Allows requests arriving through any endpoint registered to the account. Deny + // rules and allow rules cannot be set in this mode. + IngressNetworkPolicy_PrivateAccess_RestrictionMode_AllowAllRegisteredEndpoints IngressNetworkPolicy_PrivateAccess_RestrictionMode = "ALLOW_ALL_REGISTERED_ENDPOINTS" + // Restricts access based on deny rules and allow rules. Requests that do not + // match any allow rule are denied. + IngressNetworkPolicy_PrivateAccess_RestrictionMode_RestrictedAccess IngressNetworkPolicy_PrivateAccess_RestrictionMode = "RESTRICTED_ACCESS" +) + +type IngressNetworkPolicy_PublicAccess_RestrictionMode string + +const ( + IngressNetworkPolicy_PublicAccess_RestrictionMode_Unspecified IngressNetworkPolicy_PublicAccess_RestrictionMode = "" + IngressNetworkPolicy_PublicAccess_RestrictionMode_FullAccess IngressNetworkPolicy_PublicAccess_RestrictionMode = "FULL_ACCESS" + IngressNetworkPolicy_PublicAccess_RestrictionMode_RestrictedAccess IngressNetworkPolicy_PublicAccess_RestrictionMode = "RESTRICTED_ACCESS" +) + +type NccPrivateEndpointRule_PrivateLinkConnectionState string + +const ( + NccPrivateEndpointRule_PrivateLinkConnectionState_Unspecified NccPrivateEndpointRule_PrivateLinkConnectionState = "" + // The endpoint has been approved and is ready to use in your serverless compute + // resources. + NccPrivateEndpointRule_PrivateLinkConnectionState_Established NccPrivateEndpointRule_PrivateLinkConnectionState = "ESTABLISHED" + // Connection was rejected by the private link resource owner. + NccPrivateEndpointRule_PrivateLinkConnectionState_Rejected NccPrivateEndpointRule_PrivateLinkConnectionState = "REJECTED" + // Connection was removed by the private link resource owner, the private + // endpoint becomes informative and should be deleted for clean-up. + NccPrivateEndpointRule_PrivateLinkConnectionState_Disconnected NccPrivateEndpointRule_PrivateLinkConnectionState = "DISCONNECTED" + // If the endpoint was created but not approved in 14 days, it will be EXPIRED. + NccPrivateEndpointRule_PrivateLinkConnectionState_Expired NccPrivateEndpointRule_PrivateLinkConnectionState = "EXPIRED" + // The endpoint has been created and pending approval. + NccPrivateEndpointRule_PrivateLinkConnectionState_Pending NccPrivateEndpointRule_PrivateLinkConnectionState = "PENDING" + // The endpoint creation is in progress. + NccPrivateEndpointRule_PrivateLinkConnectionState_Creating NccPrivateEndpointRule_PrivateLinkConnectionState = "CREATING" + // The endpoint creation failed. + NccPrivateEndpointRule_PrivateLinkConnectionState_CreateFailed NccPrivateEndpointRule_PrivateLinkConnectionState = "CREATE_FAILED" +) + +type NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState string + +const ( + NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState_Unspecified NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState = "" + // The endpoint has been approved and is ready to use in your serverless compute + // resources. + NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState_Established NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState = "ESTABLISHED" + // Connection was rejected by the private link resource owner. + NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState_Rejected NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState = "REJECTED" + // Connection was removed by the private link resource owner, the private + // endpoint becomes informative and should be deleted for clean-up. + NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState_Disconnected NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState = "DISCONNECTED" + // If the endpoint is created but not approved in 14 days, it is EXPIRED. + NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState_Expired NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState = "EXPIRED" + // The endpoint has been created and pending approval. + NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState_Pending NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState = "PENDING" + // The endpoint creation is in progress. + NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState_Creating NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState = "CREATING" + // The endpoint creation failed. + NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState_CreateFailed NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState = "CREATE_FAILED" +) + +type NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState string + +const ( + NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState_Unspecified NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState = "" + // The endpoint has been created and pending approval. + NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState_Init NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState = "INIT" + // The endpoint has been approved and is ready to use in your serverless compute + // resources. + NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState_Established NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState = "ESTABLISHED" + // Connection was rejected by the private link resource owner. + NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState_Rejected NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState = "REJECTED" + // Connection was removed by the private link resource owner, the private + // endpoint becomes informative and should be deleted for clean-up. + NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState_Disconnected NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState = "DISCONNECTED" + // If the endpoint was created but not approved in 14 days, it will be EXPIRED. + NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState_Expired NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState = "EXPIRED" + // The endpoint has been created and pending approval. + NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState_Pending NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState = "PENDING" + // The endpoint creation is in progress. + NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState_Creating NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState = "CREATING" + // The endpoint creation failed. + NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState_CreateFailed NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState = "CREATE_FAILED" +) + +// Definition of an IP Access list. +type AccountIpAccessList struct { + // Universally unique identifier (UUID) of the IP access list. + ListId *string + // Label for the IP access list. This **cannot** be empty. + Label *string + IpAddresses []string + // Total number of IP or CIDR values. + AddressCount *int + ListType AccountIpAccessListType_IpAccessListType + // Creation timestamp in milliseconds. + CreatedAt *int64 + // The ID of the user that created this list. + CreatedBy *int64 + // Update timestamp in milliseconds. + UpdatedAt *int64 + // The ID of the user that last updated this list. + UpdatedBy *int64 + // Specifies whether this IP access list is enabled. + Enabled *bool +} + +type AccountIpAccessListType struct { +} + +type AccountNetworkPolicy struct { + // The unique identifier for the network policy. + NetworkPolicyId *string + // The associated account ID for this Network Policy object. + AccountId *string + // The network policies applying for egress traffic. + Egress *EgressNetworkPolicy + // The network policies applying for ingress traffic. + Ingress *IngressNetworkPolicy + // The ingress policy for dry run mode. Dry run will always run even if the + // request is allowed by the ingress policy. When this field is set, the policy + // will be evaluated and emit logs only without blocking requests. + IngressDryRun *IngressNetworkPolicy +} + +type AwsVpcEndpointInfo struct { + // The ID of the underlying VPC endpoint in AWS. Provided by the customer when + // registering an existing AWS VPC endpoint. + AwsVpcEndpointId *string + // The ID of the Databricks VPC endpoint service that this endpoint connects to. + AwsEndpointServiceId *string + // The AWS account ID in which this VPC endpoint lives. + AwsAccountId *string +} + +type AzurePrivateEndpointInfo struct { + // The name of the Private Endpoint in the Azure subscription. + PrivateEndpointName *string + // The GUID of the Private Endpoint resource in the Azure subscription. This is + // assigned by Azure when the user sets up the Private Endpoint. + PrivateEndpointResourceGuid *string + // The full resource ID of the Private Endpoint. + PrivateEndpointResourceId *string + // The resource ID of the Databricks Private Link Service that this Private + // Endpoint connects to. + PrivateLinkServiceId *string +} + +// Details required to configure a block list or allow list.. +type CreateAccountIpAccessListRequest struct { + AccountId *string + Label *string + ListType AccountIpAccessListType_IpAccessListType + IpAddresses []string +} + +// An IP access list was successfully created.. +type CreateAccountIpAccessListResponse struct { + IpAccessList *AccountIpAccessList +} + +type CreateEndpointRequest struct { + // The parent resource name of the account under which the endpoint is created. + // Format: `accounts/{account_id}`. + Parent *string + Endpoint *Endpoint +} + +// Details required to configure a block list or allow list.. +type CreateIpAccessListRequest struct { + // Label for the IP access list. This **cannot** be empty. + Label *string + ListType IpAccessListType + IpAddresses []string +} + +// An IP access list was successfully created.. +type CreateIpAccessListResponse struct { + IpAccessList *IpAccessList +} + +// Properties of the new private endpoint rule.. +type CreateNccPrivateEndpointRuleRequest struct { + // Your Network Connectivity Configuration ID. + NetworkConnectivityConfigId *string + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + PrivateEndpointRule *CreatePrivateEndpointRule +} + +// Properties of the new network connectivity configuration.. +type CreateNetworkConnectivityConfigRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + NetworkConnectivityConfig *CreateNetworkConnectivityConfiguration +} + +// Properties of the new network connectivity configuration.. +type CreateNetworkConnectivityConfiguration struct { + // network connectivity configuration ID. + NetworkConnectivityConfigId *string + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // The name of the network connectivity configuration. The name can contain + // alphanumeric characters, hyphens, and underscores. The length must be between + // 3 and 30 characters. The name must match the regular expression + // ^[0-9a-zA-Z-_]{3,30}$ + Name *string + // The region for the network connectivity configuration. Only workspaces in the + // same region can be attached to the network connectivity configuration. + Region *string + // The network connectivity rules that apply to network traffic from your + // serverless compute resources. + EgressConfig *CustomerFacingNetworkConnectivityConfigEgressConfig + // Time in epoch milliseconds when this object was updated. + UpdatedTime *int64 + // Time in epoch milliseconds when this object was created. + CreationTime *int64 +} + +type CreateNetworkPolicyRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // Network policy configuration details. + NetworkPolicy *AccountNetworkPolicy +} + +type CreateNetworkRequest struct { + AccountId *string + // The human-readable name of the network configuration. + NetworkName *string + // The ID of the VPC associated with this network configuration. VPC IDs can be + // used in multiple networks. + VpcId *string + // IDs of at least two subnets associated with this network. Subnet IDs + // **cannot** be used in multiple network configurations. + SubnetIds []string + // IDs of one to five security groups associated with this network. Security + // group IDs **cannot** be used in multiple network configurations. + SecurityGroupIds []string + VpcEndpoints *NetworkVpcEndpoints + GcpNetworkInfo *GcpNetworkInfo +} + +type CreatePrivateAccessSettingsRequest struct { + AccountId *string + // The human-readable name of the private access settings object. + PrivateAccessSettingsName *string + // The AWS region for workspaces attached to this private access settings + // object. + Region *string + // Determines if the workspace can be accessed over public internet. For fully + // private workspaces, you can optionally specify false, but only if you + // implement both the front-end and the back-end PrivateLink connections. + // Otherwise, specify true, which means that public access is enabled. + PublicAccessEnabled *bool + // The private access level controls which VPC endpoints can connect to the UI + // or API of any workspace that attaches this private access settings object. + // `ACCOUNT` level access (the default) allows only VPC endpoints that are + // registered in your account connect to your workspace. `ENDPOINT` + // level access allows only specified VPC endpoints connect to your workspace. + // For details, see allowed_vpc_endpoint_ids. + PrivateAccessLevel PrivateAccessLevel + // An array of Databricks VPC endpoint IDs. This is the ID returned + // when registering the VPC endpoint configuration in your account. + // This is not the ID of the VPC endpoint in AWS. Only used when + // private_access_level is set to ENDPOINT. This is an allow list of VPC + // endpoints registered in your account that can connect to your + // workspace over AWS PrivateLink. Note: If hybrid access to your workspace is + // enabled by setting public_access_enabled to true, this control only works for + // PrivateLink connections. To control how your workspace is accessed via public + // internet, see IP access lists. + AllowedVpcEndpointIds []string +} + +// Properties of the new private endpoint rule. Note that you must approve the +// endpoint in Azure portal after initialization.. +type CreatePrivateEndpointRule struct { + // The ID of a private endpoint rule. + RuleId *string + // The ID of a network connectivity configuration, which is the parent resource + // of this private endpoint rule object. + NetworkConnectivityConfigId *string + // The current status of this private endpoint. The private endpoint rules are + // effective only if the connection state is ESTABLISHED. Remember that you must + // approve new endpoints on your resources in the Cloud console before they take + // effect. The possible values are: - PENDING: The endpoint has been created and + // pending approval. - ESTABLISHED: The endpoint has been approved and is ready + // to use in your serverless compute resources. - REJECTED: Connection was + // rejected by the private link resource owner. - DISCONNECTED: Connection was + // removed by the private link resource owner, the private endpoint becomes + // informative and should be deleted for clean-up. - EXPIRED: If the endpoint + // was created but not approved in 14 days, it will be EXPIRED. - CREATING: The + // endpoint creation is in progress. Once successfully created, the state will + // transition to PENDING. - CREATE_FAILED: The endpoint creation failed. You can + // check the error_message field for more details. + ConnectionState NccPrivateEndpointRule_PrivateLinkConnectionState + // Only used by private endpoints to customer-managed private endpoint services. + // + // Domain names of target private link service. When updating this field, the + // full list of target domain_names must be specified. + DomainNames []string + // Time in epoch milliseconds when this object was created. + CreationTime *int64 + // Time in epoch milliseconds when this object was updated. + UpdatedTime *int64 + // Whether this private endpoint is deactivated. + Deactivated *bool + // Time in epoch milliseconds when this object was deactivated. + DeactivatedAt *int64 + ErrorMessage *string + // The Azure resource ID of the target resource. + ResourceId *string + // Not used by customer-managed private endpoint services. + // + // The sub-resource type (group ID) of the target resource. Note that to connect + // to workspace root storage (root DBFS), you need two endpoints, one for blob + // and one for dfs. + GroupId *string + // The name of the Azure private endpoint resource. + EndpointName *string + // account ID. You can find your account ID from the Accounts + // Console. + AccountId *string + // The full target AWS endpoint service name that connects to the destination + // resources of the private endpoint. + EndpointService *string + // Only used by private endpoints towards AWS S3 service. + // + // The globally unique S3 bucket names that will be accessed via the VPC + // endpoint. The bucket names must be in the same region as the NCC/endpoint + // service. When updating this field, we perform full update on this field. + // Please ensure a full list of desired resource_names is provided. + ResourceNames []string + // The AWS VPC endpoint ID. You can use this ID to identify the VPC endpoint + // created by . + VpcEndpointId *string + // Update this field to activate/deactivate this private endpoint to allow + // egress access from serverless compute resources. Only honored for first-party + // services on each cloud (e.g. AWS S3). + Enabled *bool + Endpoint isCreatePrivateEndpointRule_Endpoint +} + +type isCreatePrivateEndpointRule_Endpoint interface { + isCreatePrivateEndpointRule_Endpoint() +} + +// CreatePrivateEndpointRule_Endpoint_GcpEndpoint selects GcpEndpoint for CreatePrivateEndpointRule.Endpoint. +type CreatePrivateEndpointRule_Endpoint_GcpEndpoint struct { + GcpEndpoint GcpEndpoint +} + +func (*CreatePrivateEndpointRule_Endpoint_GcpEndpoint) isCreatePrivateEndpointRule_Endpoint() {} + +type CreateVpcEndpointRequest struct { + AccountId *string + // The human-readable name of the storage configuration. + VpcEndpointName *string + // The region in which this VPC endpoint object exists. + Region *string + // The ID of the VPC endpoint object in AWS. + AwsVpcEndpointId *string + VpcEndpointInfo isCreateVpcEndpointRequest_VpcEndpointInfo +} + +type isCreateVpcEndpointRequest_VpcEndpointInfo interface { + isCreateVpcEndpointRequest_VpcEndpointInfo() +} + +// CreateVpcEndpointRequest_VpcEndpointInfo_GcpVpcEndpointInfo selects GcpVpcEndpointInfo for CreateVpcEndpointRequest.VpcEndpointInfo. +// The cloud info of this vpc endpoint. +type CreateVpcEndpointRequest_VpcEndpointInfo_GcpVpcEndpointInfo struct { + GcpVpcEndpointInfo GcpVpcEndpointInfo +} + +func (*CreateVpcEndpointRequest_VpcEndpointInfo_GcpVpcEndpointInfo) isCreateVpcEndpointRequest_VpcEndpointInfo() { +} + +type CustomerFacingNetworkConnectivityConfigEgressConfig struct { + // The network connectivity rules that are applied by default without resource + // specific configurations. You can find the stable network information of your + // serverless compute resources here. + DefaultRules *NetworkConnectivityConfigEgressConfig_DefaultRule + // The network connectivity rules that configured for each destinations. These + // rules override default rules. + TargetRules *CustomerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRule +} + +// Target rule controls the egress rules that are dedicated to specific +// resources.. +type CustomerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRule struct { + AzurePrivateEndpointRules []NetworkConnectivityConfigAzurePrivateEndpointRule + // AWS private endpoint rule controls the AWS private endpoint based egress + // rules. + AwsPrivateEndpointRules []NetworkConnectivityConfigAwsPrivateEndpointRule +} + +type DeleteAccountIpAccessListRequest struct { + AccountId *string + // The ID for the corresponding IP access list + ListId *string +} + +// The IP access list was successfully deleted.. +type DeleteAccountIpAccessListResponse struct { +} + +type DeleteEndpointRequest struct { + Name *string +} + +type DeleteIpAccessListRequest struct { + // The ID for the corresponding IP access list + ListId *string +} + +// The IP access list was successfully deleted.. +type DeleteIpAccessListResponse struct { +} + +// Initiates deleting a private endpoint rule. If the connection state is +// PENDING or EXPIRED, the private endpoint is immediately deleted. Otherwise, +// the private endpoint is deactivated and will be deleted after one day of +// deactivation. When a private endpoint is deactivated, the deactivated field +// is set to true and the private endpoint is not available to your serverless +// compute resources.. +type DeleteNccPrivateEndpointRuleRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // Your Network Connectvity Configuration ID. + NetworkConnectivityConfigId *string + // Your private endpoint rule ID. + PrivateEndpointRuleId *string +} + +type DeleteNetworkConnectivityConfigRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // Your Network Connectivity Configuration ID. + NetworkConnectivityConfigId *string +} + +type DeleteNetworkPolicyRequest struct { + // The unique identifier of the network policy to delete. + NetworkPolicyId *string + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string +} + +type DeleteNetworkRequest struct { + // Databricks Account API network configuration ID. + NetworkId *string + AccountId *string +} + +type DeletePrivateAccessSettingsRequest struct { + PrivateAccessSettingsId *string + AccountId *string +} + +type DeleteVpcEndpointRequest struct { + VpcEndpointId *string + AccountId *string +} + +// The network policies applying for egress traffic.. +type EgressNetworkPolicy struct { + // The access policy enforced for egress traffic to the internet. + NetworkAccess *EgressNetworkPolicy_NetworkAccessPolicy +} + +type EgressNetworkPolicy_NetworkAccessPolicy struct { + // The restriction mode that controls how serverless workloads can access the + // internet. + RestrictionMode EgressNetworkPolicy_NetworkAccessPolicy_RestrictionMode + // List of internet destinations that serverless workloads are allowed to access + // when in RESTRICTED_ACCESS mode. + AllowedInternetDestinations []EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination + // List of storage destinations that serverless workloads are allowed to access + // when in RESTRICTED_ACCESS mode. + AllowedStorageDestinations []EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination + // Optional. When policy_enforcement is not provided, we default to + // ENFORCE_MODE_ALL_SERVICES + PolicyEnforcement *EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement + // List of internet destinations that serverless workloads are blocked from + // accessing. These destinations are enforced when restriction mode is + // RESTRICTED_ACCESS or DRY_RUN. Currently supports DNS_NAME type only; IP_RANGE + // support is planned. + BlockedInternetDestinations []EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination + // List of workspace destinations that serverless workloads are + // allowed to access when in RESTRICTED_ACCESS mode. + AllowedDatabricksDestinations []EgressNetworkPolicy_NetworkAccessPolicy_DatabricksDestination +} + +type EgressNetworkPolicy_NetworkAccessPolicy_DatabricksDestination struct { + // The workspace IDs to allow egress traffic to. + WorkspaceIds []int64 +} + +// Users can specify accessible internet destinations when outbound access is +// restricted. We only support DNS_NAME (FQDN format) destinations for the time +// being. Going forward we may extend support to host names and IP addresses.. +type EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination struct { + // The internet destination to which access will be allowed. Format dependent on + // the destination type. + Destination *string + // The type of internet destination. Currently only DNS_NAME is supported. + InternetDestinationType EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination_InternetDestinationType +} + +type EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement struct { + // The mode of policy enforcement. ENFORCED blocks traffic that violates policy, + // while DRY_RUN only logs violations without blocking. When not specified, + // defaults to ENFORCED. + EnforcementMode EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_EnforcementMode + // When empty, it means dry run for all products. When non-empty, it means dry + // run for specific products and for the other products, they will run in + // enforced mode. + DryRunModeProductFilter []EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_DryRunModeProductFilter +} + +// Users can specify accessible storage destinations.. +type EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination struct { + BucketName *string + Region *string + // The type of storage destination. + StorageDestinationType EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType + // The Azure storage account name. + AzureStorageAccount *string + // The Azure storage service type (blob, dfs, etc.). + AzureStorageService *string +} + +// Endpoint represents a cloud networking resource in a user's cloud account and +// binds it to the account.. +type Endpoint struct { + // The resource name of the endpoint, which uniquely identifies the endpoint. + Name *string + // The unique identifier for this endpoint under the account. This field is a + // UUID generated by . + EndpointId *string + // The Databricks Account in which the endpoint object exists. + AccountId *string + // The human-readable display name of this endpoint. The input should conform to + // RFC-1034, which restricts to letters, numbers, and hyphens, with the first + // character a letter, the last a letter or a number, and a 63 character + // maximum. + DisplayName *string + // The use case that determines the type of network connectivity this endpoint + // provides. This field is automatically determined based on the endpoint + // configuration and cloud-specific settings. + UseCase EndpointUseCase_EndpointUseCase + // The cloud provider region where this endpoint is located. + Region *string + // The state of the endpoint. The endpoint can only be used if the state is + // `APPROVED`. + State EndpointState + // The cloud info of this endpoint. (-- Azure is GA; AWS and GCP added for + // PLAT-165656 (Private Preview). --) + EndpointInfo isEndpoint_EndpointInfo + // The timestamp when the endpoint was created. The timestamp is in RFC 3339 + // format in UTC timezone. + CreateTime *types.Time +} + +type isEndpoint_EndpointInfo interface { + isEndpoint_EndpointInfo() +} + +// Endpoint_EndpointInfo_AzurePrivateEndpointInfo selects AzurePrivateEndpointInfo for Endpoint.EndpointInfo. +// Info for an Azure private endpoint. +type Endpoint_EndpointInfo_AzurePrivateEndpointInfo struct { + AzurePrivateEndpointInfo AzurePrivateEndpointInfo +} + +func (*Endpoint_EndpointInfo_AzurePrivateEndpointInfo) isEndpoint_EndpointInfo() {} + +// Endpoint_EndpointInfo_AwsVpcEndpointInfo selects AwsVpcEndpointInfo for Endpoint.EndpointInfo. +// Info for an AWS VPC endpoint. +type Endpoint_EndpointInfo_AwsVpcEndpointInfo struct { + AwsVpcEndpointInfo AwsVpcEndpointInfo +} + +func (*Endpoint_EndpointInfo_AwsVpcEndpointInfo) isEndpoint_EndpointInfo() {} + +// Endpoint_EndpointInfo_GcpPscEndpointInfo selects GcpPscEndpointInfo for Endpoint.EndpointInfo. +// Info for a GCP Private Service Connect endpoint. +type Endpoint_EndpointInfo_GcpPscEndpointInfo struct { + GcpPscEndpointInfo GcpPscEndpointInfo +} + +func (*Endpoint_EndpointInfo_GcpPscEndpointInfo) isEndpoint_EndpointInfo() {} + +type EndpointUseCase struct { +} + +type GcpEndpoint struct { + // Output only. The URI of the created PSC endpoint. + PscEndpointUri *string `fieldmask:"psc_endpoint_uri"` + // Selects which target services this private endpoint reaches. + TargetServices isGcpEndpoint_TargetServices + _ [0]gcpEndpointTargetServicesFieldMaskMetadata `fieldmask_oneof:"TargetServices"` +} + +type isGcpEndpoint_TargetServices interface { + isGcpEndpoint_TargetServices() +} + +// GcpEndpoint_TargetServices_ServiceAttachment selects ServiceAttachment for GcpEndpoint.TargetServices. +// The full url of the target service attachment. Example: +// projects/my-gcp-project/regions/us-east4/serviceAttachments/my-service-attachment +type GcpEndpoint_TargetServices_ServiceAttachment struct { + ServiceAttachment string `fieldmask:"service_attachment"` +} + +func (*GcpEndpoint_TargetServices_ServiceAttachment) isGcpEndpoint_TargetServices() {} + +// GcpEndpoint_TargetServices_GoogleApiEndpoints selects GoogleApiEndpoints for GcpEndpoint.TargetServices. +// Selected Google API hostnames, e.g. "storage.googleapis.com", +// "bigquery.googleapis.com". +type GcpEndpoint_TargetServices_GoogleApiEndpoints struct { + GoogleApiEndpoints GoogleApiEndpoints `fieldmask:"google_api_endpoints"` +} + +func (*GcpEndpoint_TargetServices_GoogleApiEndpoints) isGcpEndpoint_TargetServices() {} + +// GcpEndpoint_TargetServices_AllVpcScServices selects AllVpcScServices for GcpEndpoint.TargetServices. +// All Google APIs that support VPC Service Controls (a subset of all Google +// APIs). +type GcpEndpoint_TargetServices_AllVpcScServices struct { + AllVpcScServices bool `fieldmask:"all_vpc_sc_services"` +} + +func (*GcpEndpoint_TargetServices_AllVpcScServices) isGcpEndpoint_TargetServices() {} + +type gcpEndpointTargetServicesFieldMaskMetadata struct { + *GcpEndpoint_TargetServices_ServiceAttachment + *GcpEndpoint_TargetServices_GoogleApiEndpoints + *GcpEndpoint_TargetServices_AllVpcScServices +} + +type GcpNetworkInfo struct { + // The GCP project ID for network resources. This project is where the VPC and + // subnet resides. + NetworkProjectId *string + // The customer-provided VPC ID. + VpcId *string + // The customer-provided Subnet ID that will be available to Clusters in + // Workspaces using this Network. + SubnetId *string + SubnetRegion *string + // Name of the secondary range within the subnet that will be used by GKE as Pod + // IP range. This is BYO VPC specific. DB VPC uses + // network.getGcpManagedNetworkConfig.getGkeClusterPodIpRange + PodIpRangeName *string + // Name of the secondary range within the subnet that will be used by GKE as + // Service IP range. + ServiceIpRangeName *string +} + +type GcpPscEndpointInfo struct { + // The ID of the underlying Private Service Connect connection in the GCP + // consumer project, assigned by GCP when the PSC connection is created. + PscConnectionId *string + // The GCP consumer project ID in which this PSC endpoint is created. Provided + // by the customer when registering an existing PSC endpoint. + ProjectId *string + // The name of this PSC connection in the GCP consumer project. Provided by the + // customer when registering an existing PSC endpoint. + PscEndpoint *string + // The GCP region of the PSC connection endpoint. Provided by the customer when + // registering an existing PSC endpoint. GCP supports only same-region PSC, so + // this must match the workspace region. + EndpointRegion *string + // The ID of the service attachment this PSC endpoint connects to. + ServiceAttachmentId *string +} + +type GcpVpcEndpointInfo struct { + PscConnectionId *string + ProjectId *string + PscEndpointName *string + EndpointRegion *string + ServiceAttachmentId *string +} + +type GetAccountIpAccessListRequest struct { + AccountId *string + // The ID for the corresponding IP access list + ListId *string +} + +type GetAccountIpAccessListResponse struct { + IpAccessList *AccountIpAccessList +} + +type GetEndpointRequest struct { + Name *string +} + +type GetIpAccessListRequest struct { + // The ID for the corresponding IP access list + ListId *string +} + +// An IP access list was successfully returned.. +type GetIpAccessListResponse struct { + IpAccessList *IpAccessList +} + +type GetNccPrivateEndpointRuleRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // Your Network Connectvity Configuration ID. + NetworkConnectivityConfigId *string + // Your private endpoint rule ID. + PrivateEndpointRuleId *string +} + +// ***************************** Public facing RPC requests and responses +// *****************************//. +type GetNetworkConnectivityConfigRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // Your Network Connectivity Configuration ID. + NetworkConnectivityConfigId *string +} + +type GetNetworkPolicyRequest struct { + // The unique identifier of the network policy to retrieve. + NetworkPolicyId *string + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string +} + +type GetNetworkRequest struct { + // Databricks Account API network configuration ID. + NetworkId *string + AccountId *string +} + +type GetPrivateAccessSettingsRequest struct { + PrivateAccessSettingsId *string + AccountId *string +} + +type GetVpcEndpointRequest struct { + // Databricks VPC endpoint ID. + VpcEndpointId *string + AccountId *string +} + +type GetWorkspaceNetworkOptionRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // The workspace ID. + WorkspaceId *int64 +} + +// Wrapper for a list of Google API hostnames. Wrapped in a message because +// proto3 oneof does not support repeated fields directly.. +type GoogleApiEndpoints struct { + // Google API hostnames, e.g. "storage.googleapis.com", + // "bigquery.googleapis.com". Use "googleapis.com" to cover all Google APIs. + Endpoints []string `fieldmask:"endpoints"` +} + +// The network policies applying for ingress traffic.. +type IngressNetworkPolicy struct { + // The network policy restrictions for public access to the workspace. + // Configures how public internet traffic is allowed or denied access. + PublicAccess *IngressNetworkPolicy_PublicAccess + // The network policy restrictions for private access. Configures how requests + // arriving over private connectivity are governed. + PrivateAccess *IngressNetworkPolicy_PrivateAccess + CrossWorkspaceAccess *IngressNetworkPolicy_CrossWorkspaceAccess +} + +// Matches account-level Databricks API endpoints for an ingress network policy +// rule.. +type IngressNetworkPolicy_AccountApiDestination struct { + // The API scopes to match. Use "all-apis" to match any account-level API. + Scopes []string + // Qualifies the breadth of API access for the listed scopes. See + // ApiScopeQualifier. + ScopeQualifier IngressNetworkPolicy_ApiScopeQualifier +} + +type IngressNetworkPolicy_AccountDatabricksOneDestination struct { + // Must be set to true. + AllDestinations *bool +} + +// The account console UI destination.. +type IngressNetworkPolicy_AccountUiDestination struct { + // Must be set to true. + AllDestinations *bool +} + +type IngressNetworkPolicy_AppsRuntimeDestination struct { + // Must be set to true. + AllDestinations *bool +} + +type IngressNetworkPolicy_Authentication struct { + IdentityType IngressNetworkPolicy_Authentication_IdentityType + // Valid only when IdentityType is IDENTITY_TYPE_SELECTED_IDENTITIES. + Identities []IngressNetworkPolicy_AuthenticationIdentity +} + +type IngressNetworkPolicy_AuthenticationIdentity struct { + PrincipalType IngressNetworkPolicy_AuthenticationIdentity_PrincipalType + PrincipalId *int64 +} + +type IngressNetworkPolicy_CrossWorkspaceAccess struct { + RestrictionMode IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode + DenyRules []IngressNetworkPolicy_CrossWorkspaceIngressRule + AllowRules []IngressNetworkPolicy_CrossWorkspaceIngressRule +} + +type IngressNetworkPolicy_CrossWorkspaceIngressRule struct { + Origin *IngressNetworkPolicy_CrossWorkspaceRequestOrigin + Destination *IngressNetworkPolicy_RequestDestination + Authentication *IngressNetworkPolicy_Authentication + // The label for this ingress rule. + Label *string +} + +type IngressNetworkPolicy_CrossWorkspaceRequestOrigin struct { + Source isIngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source +} + +type isIngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source interface { + isIngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source() +} + +// IngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source_AllSourceWorkspaces selects AllSourceWorkspaces for IngressNetworkPolicy_CrossWorkspaceRequestOrigin.Source. +// Matches all source workspaces. +type IngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source_AllSourceWorkspaces struct { + AllSourceWorkspaces bool +} + +func (*IngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source_AllSourceWorkspaces) isIngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source() { +} + +// IngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source_SelectedWorkspaces selects SelectedWorkspaces for IngressNetworkPolicy_CrossWorkspaceRequestOrigin.Source. +// Specific source workspace IDs to match. +type IngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source_SelectedWorkspaces struct { + SelectedWorkspaces IngressNetworkPolicy_WorkspaceIdList +} + +func (*IngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source_SelectedWorkspaces) isIngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source() { +} + +// A set of registered endpoints, identified by their endpoint IDs.. +type IngressNetworkPolicy_Endpoints struct { + // The IDs of the registered endpoints. Must contain at least one endpoint ID. + EndpointIds []string +} + +type IngressNetworkPolicy_IpRanges struct { + // We only support IPv4 and IPv4 CIDR notation for now. + IpRanges []string +} + +type IngressNetworkPolicy_LakebaseRuntimeDestination struct { + // Must be set to true. + AllDestinations *bool +} + +// Configures how requests arriving over private connectivity, such as +// registered endpoints, are allowed or denied access.. +type IngressNetworkPolicy_PrivateAccess struct { + // The restriction mode for private access. + RestrictionMode IngressNetworkPolicy_PrivateAccess_RestrictionMode + // Deny rules are evaluated first. A request matching any deny rule is denied, + // regardless of allow rules. Only applies when restriction_mode is + // RESTRICTED_ACCESS. + DenyRules []IngressNetworkPolicy_PrivateIngressRule + // Allow rules are evaluated after deny rules. A request matching any allow rule + // is allowed; a request matching no rule is denied by default. Only applies + // when restriction_mode is RESTRICTED_ACCESS. + AllowRules []IngressNetworkPolicy_PrivateIngressRule +} + +// An ingress rule is enforced when a request satisfies all specified attributes +// — including request origin, destination, and authentication.. +type IngressNetworkPolicy_PrivateIngressRule struct { + // The origin the request must match — the private connectivity the request + // arrives through, for example a specific set of registered endpoints or any + // endpoint registered to the account. See PrivateRequestOrigin. + Origin *IngressNetworkPolicy_PrivateRequestOrigin + // The destination the request must match — the resource being accessed, for + // example the workspace UI, workspace APIs, or account-level APIs. See + // RequestDestination. + Destination *IngressNetworkPolicy_RequestDestination + // The authenticated identity the request must match. When unset, the rule + // matches all users and service principals. On the account-level network + // policy, scoping to specific identities is not currently supported, so this + // field must be unset (the rule matches all users and service principals). + Authentication *IngressNetworkPolicy_Authentication + // The label for this ingress rule. + Label *string +} + +// The origin of a private access request, identified by the endpoint through +// which the request arrives.. +type IngressNetworkPolicy_PrivateRequestOrigin struct { + Source isIngressNetworkPolicy_PrivateRequestOrigin_Source +} + +type isIngressNetworkPolicy_PrivateRequestOrigin_Source interface { + isIngressNetworkPolicy_PrivateRequestOrigin_Source() +} + +// IngressNetworkPolicy_PrivateRequestOrigin_Source_Endpoints selects Endpoints for IngressNetworkPolicy_PrivateRequestOrigin.Source. +// Matches requests arriving through any of the specified registered endpoints. +type IngressNetworkPolicy_PrivateRequestOrigin_Source_Endpoints struct { + Endpoints IngressNetworkPolicy_Endpoints +} + +func (*IngressNetworkPolicy_PrivateRequestOrigin_Source_Endpoints) isIngressNetworkPolicy_PrivateRequestOrigin_Source() { +} + +// IngressNetworkPolicy_PrivateRequestOrigin_Source_AllRegisteredEndpoints selects AllRegisteredEndpoints for IngressNetworkPolicy_PrivateRequestOrigin.Source. +// Matches requests arriving through any endpoint registered to the account. +// Must be set to true when specified. +type IngressNetworkPolicy_PrivateRequestOrigin_Source_AllRegisteredEndpoints struct { + AllRegisteredEndpoints bool +} + +func (*IngressNetworkPolicy_PrivateRequestOrigin_Source_AllRegisteredEndpoints) isIngressNetworkPolicy_PrivateRequestOrigin_Source() { +} + +// IngressNetworkPolicy_PrivateRequestOrigin_Source_AzureWorkspacePrivateLink selects AzureWorkspacePrivateLink for IngressNetworkPolicy_PrivateRequestOrigin.Source. +// Matches requests arriving through the workspace's Azure Private Link (ui-api) +// endpoints. Can only be used in deny rules of workspace-level network +// policies. Must be set to true when specified. +type IngressNetworkPolicy_PrivateRequestOrigin_Source_AzureWorkspacePrivateLink struct { + AzureWorkspacePrivateLink bool +} + +func (*IngressNetworkPolicy_PrivateRequestOrigin_Source_AzureWorkspacePrivateLink) isIngressNetworkPolicy_PrivateRequestOrigin_Source() { +} + +// IngressNetworkPolicy_PrivateRequestOrigin_Source_AllPrivateAccess selects AllPrivateAccess for IngressNetworkPolicy_PrivateRequestOrigin.Source. +// Matches requests arriving over any private connectivity, including registered +// endpoints and the workspace's Azure Private Link (ui-api) endpoints. Can only +// be used in deny rules of workspace-level network policies. Must be set to +// true when specified. +type IngressNetworkPolicy_PrivateRequestOrigin_Source_AllPrivateAccess struct { + AllPrivateAccess bool +} + +func (*IngressNetworkPolicy_PrivateRequestOrigin_Source_AllPrivateAccess) isIngressNetworkPolicy_PrivateRequestOrigin_Source() { +} + +type IngressNetworkPolicy_PublicAccess struct { + RestrictionMode IngressNetworkPolicy_PublicAccess_RestrictionMode + DenyRules []IngressNetworkPolicy_PublicIngressRule + AllowRules []IngressNetworkPolicy_PublicIngressRule +} + +// An ingress rule is enforced when a request satisfies all specified attributes +// — including request origin, destination, and authentication.. +type IngressNetworkPolicy_PublicIngressRule struct { + Origin *IngressNetworkPolicy_PublicRequestOrigin + Destination *IngressNetworkPolicy_RequestDestination + Authentication *IngressNetworkPolicy_Authentication + // The label for this ingress rule. + Label *string +} + +type IngressNetworkPolicy_PublicRequestOrigin struct { + Source isIngressNetworkPolicy_PublicRequestOrigin_Source +} + +type isIngressNetworkPolicy_PublicRequestOrigin_Source interface { + isIngressNetworkPolicy_PublicRequestOrigin_Source() +} + +// IngressNetworkPolicy_PublicRequestOrigin_Source_AllIpRanges selects AllIpRanges for IngressNetworkPolicy_PublicRequestOrigin.Source. +// Matches all IPv4 and IPv6 ranges (both public and private). +type IngressNetworkPolicy_PublicRequestOrigin_Source_AllIpRanges struct { + AllIpRanges bool +} + +func (*IngressNetworkPolicy_PublicRequestOrigin_Source_AllIpRanges) isIngressNetworkPolicy_PublicRequestOrigin_Source() { +} + +// IngressNetworkPolicy_PublicRequestOrigin_Source_IncludedIpRanges selects IncludedIpRanges for IngressNetworkPolicy_PublicRequestOrigin.Source. +// Will not allow IP ranges with private IPs. +type IngressNetworkPolicy_PublicRequestOrigin_Source_IncludedIpRanges struct { + IncludedIpRanges IngressNetworkPolicy_IpRanges +} + +func (*IngressNetworkPolicy_PublicRequestOrigin_Source_IncludedIpRanges) isIngressNetworkPolicy_PublicRequestOrigin_Source() { +} + +// IngressNetworkPolicy_PublicRequestOrigin_Source_ExcludedIpRanges selects ExcludedIpRanges for IngressNetworkPolicy_PublicRequestOrigin.Source. +// Excluded means: all public IP ranges except this one. +type IngressNetworkPolicy_PublicRequestOrigin_Source_ExcludedIpRanges struct { + ExcludedIpRanges IngressNetworkPolicy_IpRanges +} + +func (*IngressNetworkPolicy_PublicRequestOrigin_Source_ExcludedIpRanges) isIngressNetworkPolicy_PublicRequestOrigin_Source() { +} + +type IngressNetworkPolicy_RequestDestination struct { + // When true, match all destinations, no other destination fields can be set. + // When not set or false, at least one specific destination must be provided. + AllDestinations *bool + WorkspaceUi *IngressNetworkPolicy_WorkspaceUiDestination + WorkspaceApi *IngressNetworkPolicy_WorkspaceApiDestination + AppsRuntime *IngressNetworkPolicy_AppsRuntimeDestination + LakebaseRuntime *IngressNetworkPolicy_LakebaseRuntimeDestination + // Matches requests to the account console UI. Can only be used in the + // account-level network policy. + AccountUi *IngressNetworkPolicy_AccountUiDestination + // Matches requests to account-level APIs. Can only be used in the account-level + // network policy. + AccountApi *IngressNetworkPolicy_AccountApiDestination + // Account DatabricksOne destination is not supported. + AccountDatabricksOne *IngressNetworkPolicy_AccountDatabricksOneDestination +} + +// Matches workspace-level Databricks API endpoints for an ingress network +// policy rule.. +type IngressNetworkPolicy_WorkspaceApiDestination struct { + Scopes []string + // Qualifies the breadth of API access for the listed scopes. See + // ApiScopeQualifier. + ScopeQualifier IngressNetworkPolicy_ApiScopeQualifier +} + +type IngressNetworkPolicy_WorkspaceIdList struct { + WorkspaceIds []int64 +} + +type IngressNetworkPolicy_WorkspaceUiDestination struct { + // Must be set to true. + AllDestinations *bool +} + +// Definition of an IP Access list. +type IpAccessList struct { + // Universally unique identifier (UUID) of the IP access list. + ListId *string + // Label for the IP access list. This **cannot** be empty. + Label *string + IpAddresses []string + // Total number of IP or CIDR values. + AddressCount *int + ListType IpAccessListType + // Creation timestamp in milliseconds. + CreatedAt *int64 + // User ID of the user who created this list. + CreatedBy *int64 + // Update timestamp in milliseconds. + UpdatedAt *int64 + // User ID of the user who updated this list. + UpdatedBy *int64 + // Specifies whether this IP access list is enabled. + Enabled *bool +} + +type ListAccountIpAccessListsRequest struct { + AccountId *string +} + +// IP access lists were successfully returned.. +type ListAccountIpAccessListsResponse struct { + IpAccessLists []AccountIpAccessList +} + +type ListEndpointsRequest struct { + // The parent resource name of the account to list endpoints for. Format: + // `accounts/{account_id}`. + Parent *string + PageToken *string + PageSize *int +} + +type ListEndpointsResponse struct { + Items []Endpoint + NextPageToken *string +} + +type ListIpAccessLists struct { +} + +// IP access lists were successfully returned.. +type ListIpAccessListsResponse struct { + IpAccessLists []IpAccessList +} + +// Gets an array of private endpoint rules.. +type ListNccPrivateEndpointRulesRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // Your Network Connectvity Configuration ID. + NetworkConnectivityConfigId *string + // Pagination token to go to next page based on previous query. + PageToken *string +} + +// The private endpoint rule list was successfully retrieved.. +type ListNccPrivateEndpointRulesResponse struct { + Items []NccPrivateEndpointRule + // A token that can be used to get the next page of results. If null, there are + // no more results to show. + NextPageToken *string +} + +type ListNetworkConnectivityConfigsRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // Pagination token to go to next page based on previous query. + PageToken *string +} + +// The network connectivity configuration list was successfully retrieved.. +type ListNetworkConnectivityConfigsResponse struct { + Items []NetworkConnectivityConfig + // A token that can be used to get the next page of results. If null, there are + // no more results to show. + NextPageToken *string +} + +type ListNetworkPoliciesRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // Pagination token to go to next page based on previous query. + PageToken *string +} + +type ListNetworkPoliciesResponse struct { + // List of network policies. + Items []AccountNetworkPolicy + // A token that can be used to get the next page of results. If null, there are + // no more results to show. + NextPageToken *string +} + +type ListNetworkRequest struct { + AccountId *string +} + +type ListNetworkResponse struct { + Networks []Network +} + +type ListPrivateAccessSettingsRequest struct { + AccountId *string +} + +type ListPrivateAccessSettingsResponse struct { + PrivateAccessSettings []PrivateAccessSettings +} + +type ListVpcEndpointRequest struct { + AccountId *string +} + +type ListVpcEndpointResponse struct { + VpcEndpoints []VpcEndpoint +} + +// Properties of the new private endpoint rule. Note that you must approve the +// endpoint in Azure portal after initialization.. +type NccPrivateEndpointRule struct { + // The ID of a private endpoint rule. + RuleId *string + // The ID of a network connectivity configuration, which is the parent resource + // of this private endpoint rule object. + NetworkConnectivityConfigId *string + // The current status of this private endpoint. The private endpoint rules are + // effective only if the connection state is ESTABLISHED. Remember that you must + // approve new endpoints on your resources in the Cloud console before they take + // effect. The possible values are: - PENDING: The endpoint has been created and + // pending approval. - ESTABLISHED: The endpoint has been approved and is ready + // to use in your serverless compute resources. - REJECTED: Connection was + // rejected by the private link resource owner. - DISCONNECTED: Connection was + // removed by the private link resource owner, the private endpoint becomes + // informative and should be deleted for clean-up. - EXPIRED: If the endpoint + // was created but not approved in 14 days, it will be EXPIRED. - CREATING: The + // endpoint creation is in progress. Once successfully created, the state will + // transition to PENDING. - CREATE_FAILED: The endpoint creation failed. You can + // check the error_message field for more details. + ConnectionState NccPrivateEndpointRule_PrivateLinkConnectionState + // Only used by private endpoints to customer-managed private endpoint services. + // + // Domain names of target private link service. When updating this field, the + // full list of target domain_names must be specified. + DomainNames []string + // Time in epoch milliseconds when this object was created. + CreationTime *int64 + // Time in epoch milliseconds when this object was updated. + UpdatedTime *int64 + // Whether this private endpoint is deactivated. + Deactivated *bool + // Time in epoch milliseconds when this object was deactivated. + DeactivatedAt *int64 + ErrorMessage *string + // The Azure resource ID of the target resource. + ResourceId *string + // Not used by customer-managed private endpoint services. + // + // The sub-resource type (group ID) of the target resource. Note that to connect + // to workspace root storage (root DBFS), you need two endpoints, one for blob + // and one for dfs. + GroupId *string + // The name of the Azure private endpoint resource. + EndpointName *string + // account ID. You can find your account ID from the Accounts + // Console. + AccountId *string + // The full target AWS endpoint service name that connects to the destination + // resources of the private endpoint. + EndpointService *string + // Only used by private endpoints towards AWS S3 service. + // + // The globally unique S3 bucket names that will be accessed via the VPC + // endpoint. The bucket names must be in the same region as the NCC/endpoint + // service. When updating this field, we perform full update on this field. + // Please ensure a full list of desired resource_names is provided. + ResourceNames []string + // The AWS VPC endpoint ID. You can use this ID to identify the VPC endpoint + // created by . + VpcEndpointId *string + // Update this field to activate/deactivate this private endpoint to allow + // egress access from serverless compute resources. Only honored for first-party + // services on each cloud (e.g. AWS S3). + Enabled *bool + Endpoint isNccPrivateEndpointRule_Endpoint +} + +type isNccPrivateEndpointRule_Endpoint interface { + isNccPrivateEndpointRule_Endpoint() +} + +// NccPrivateEndpointRule_Endpoint_GcpEndpoint selects GcpEndpoint for NccPrivateEndpointRule.Endpoint. +type NccPrivateEndpointRule_Endpoint_GcpEndpoint struct { + GcpEndpoint GcpEndpoint +} + +func (*NccPrivateEndpointRule_Endpoint_GcpEndpoint) isNccPrivateEndpointRule_Endpoint() {} + +type Network struct { + // The network configuration ID. + NetworkId *string + // The account ID associated with this network configuration. + AccountId *string + // Workspace ID associated with this network configuration. + WorkspaceId *int64 + // The ID of the VPC associated with this network configuration. VPC IDs can be + // used in multiple networks. + VpcId *string + // IDs of at least two subnets associated with this network. Subnet IDs + // **cannot** be used in multiple network configurations. + SubnetIds []string + // IDs of one to five security groups associated with this network. Security + // group IDs **cannot** be used in multiple network configurations. + SecurityGroupIds []string + VpcStatus VpcStatus + // Array of error messages about the network configuration. + ErrorMessages []NetworkHealth + // The human-readable name of the network configuration. + NetworkName *string + // Time in epoch milliseconds when the network was created. + CreationTime *int64 + // Array of warning messages about the network configuration. + WarningMessages []NetworkWarning + VpcEndpoints *NetworkVpcEndpoints + NetworkInfo isNetwork_NetworkInfo +} + +type isNetwork_NetworkInfo interface { + isNetwork_NetworkInfo() +} + +// Network_NetworkInfo_GcpNetworkInfo selects GcpNetworkInfo for Network.NetworkInfo. +type Network_NetworkInfo_GcpNetworkInfo struct { + GcpNetworkInfo GcpNetworkInfo +} + +func (*Network_NetworkInfo_GcpNetworkInfo) isNetwork_NetworkInfo() {} + +// Properties of the new network connectivity configuration.. +type NetworkConnectivityConfig struct { + // network connectivity configuration ID. + NetworkConnectivityConfigId *string + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // The name of the network connectivity configuration. The name can contain + // alphanumeric characters, hyphens, and underscores. The length must be between + // 3 and 30 characters. The name must match the regular expression + // ^[0-9a-zA-Z-_]{3,30}$ + Name *string + // The region for the network connectivity configuration. Only workspaces in the + // same region can be attached to the network connectivity configuration. + Region *string + // The network connectivity rules that apply to network traffic from your + // serverless compute resources. + EgressConfig *CustomerFacingNetworkConnectivityConfigEgressConfig + // Time in epoch milliseconds when this object was updated. + UpdatedTime *int64 + // Time in epoch milliseconds when this object was created. + CreationTime *int64 +} + +// Properties of the new private endpoint rule. Note that for private endpoints +// towards a VPC endpoint service behind a customer-managed NLB, you must +// approve the endpoint in AWS console after initialization.. +type NetworkConnectivityConfigAwsPrivateEndpointRule struct { + // The ID of a private endpoint rule. + RuleId *string + // The ID of a network connectivity configuration, which is the parent resource + // of this private endpoint rule object. + NetworkConnectivityConfigId *string + // account ID. You can find your account ID from the Accounts + // Console. + AccountId *string + // The full target AWS endpoint service name that connects to the destination + // resources of the private endpoint. + EndpointService *string + // Only used by private endpoints towards a VPC endpoint service for + // customer-managed VPC endpoint service. + // + // The target AWS resource FQDNs accessible via the VPC endpoint service. When + // updating this field, we perform full update on this field. Please ensure a + // full list of desired domain_names is provided. + DomainNames []string + // Only used by private endpoints towards AWS S3 service. + // + // The globally unique S3 bucket names that will be accessed via the VPC + // endpoint. The bucket names must be in the same region as the NCC/endpoint + // service. When updating this field, we perform full update on this field. + // Please ensure a full list of desired resource_names is provided. + ResourceNames []string + // The AWS VPC endpoint ID. You can use this ID to identify VPC endpoint created + // by . + VpcEndpointId *string + // The current status of this private endpoint. The private endpoint rules are + // effective only if the connection state is ESTABLISHED. Remember that you must + // approve new endpoints on your resources in the AWS console before they take + // effect. The possible values are: - PENDING: The endpoint has been created and + // pending approval. - ESTABLISHED: The endpoint has been approved and is ready + // to use in your serverless compute resources. - REJECTED: Connection was + // rejected by the private link resource owner. - DISCONNECTED: Connection was + // removed by the private link resource owner, the private endpoint becomes + // informative and should be deleted for clean-up. - EXPIRED: If the endpoint is + // created but not approved in 14 days, it is EXPIRED. + ConnectionState NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState + // Time in epoch milliseconds when this object was created. + CreationTime *int64 + // Time in epoch milliseconds when this object was updated. + UpdatedTime *int64 + // Whether this private endpoint is deactivated. + Deactivated *bool + // Time in epoch milliseconds when this object was deactivated. + DeactivatedAt *int64 + // Only used by private endpoints towards an AWS S3 service. + // + // Update this field to activate/deactivate this private endpoint to allow + // egress access from serverless compute resources. + Enabled *bool + ErrorMessage *string +} + +// Properties of the new private endpoint rule. Note that you must approve the +// endpoint in Azure portal after initialization.. +type NetworkConnectivityConfigAzurePrivateEndpointRule struct { + // The ID of a private endpoint rule. + RuleId *string + // The ID of a network connectivity configuration, which is the parent resource + // of this private endpoint rule object. + NetworkConnectivityConfigId *string + // The Azure resource ID of the target resource. + ResourceId *string + // Only used by private endpoints to Azure first-party services. + // + // The sub-resource type (group ID) of the target resource. Note that to connect + // to workspace root storage (root DBFS), you need two endpoints, one for blob + // and one for dfs. + GroupId *string + // The name of the Azure private endpoint resource. + EndpointName *string + // The current status of this private endpoint. The private endpoint rules are + // effective only if the connection state is ESTABLISHED. Remember that you must + // approve new endpoints on your resources in the Azure portal before they take + // effect. The possible values are: - INIT: (deprecated) The endpoint has been + // created and pending approval. - PENDING: The endpoint has been created and + // pending approval. - ESTABLISHED: The endpoint has been approved and is ready + // to use in your serverless compute resources. - REJECTED: Connection was + // rejected by the private link resource owner. - DISCONNECTED: Connection was + // removed by the private link resource owner, the private endpoint becomes + // informative and should be deleted for clean-up. - EXPIRED: If the endpoint + // was created but not approved in 14 days, it will be EXPIRED. + ConnectionState NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState + // Time in epoch milliseconds when this object was created. + CreationTime *int64 + // Time in epoch milliseconds when this object was updated. + UpdatedTime *int64 + // Whether this private endpoint is deactivated. + Deactivated *bool + // Time in epoch milliseconds when this object was deactivated. + DeactivatedAt *int64 + // Not used by customer-managed private endpoint services. + // + // Domain names of target private link service. When updating this field, the + // full list of target domain_names must be specified. + DomainNames []string + ErrorMessage *string +} + +// Egress network configurations. Provides network configurations for Databricks +// -> Customer traffic.. +type NetworkConnectivityConfigEgressConfig struct { +} + +// Default rules don't have specific targets.. +type NetworkConnectivityConfigEgressConfig_DefaultRule struct { + AzureServiceEndpointRule *NetworkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRule + AwsStableIpRule *NetworkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRule +} + +// The stable AWS IP CIDR blocks. You can use these to configure the firewall of +// your resources to allow traffic from your workspace.. +type NetworkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRule struct { + // The list of stable IP CIDR blocks from which network traffic + // originates when accessing your resources. + CidrBlocks []string +} + +// The stable Azure service endpoints. You can configure the firewall of your +// Azure resources to allow traffic from your serverless compute +// resources.. +type NetworkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRule struct { + // The Azure region in which this service endpoint rule applies.. + TargetRegion *string + // The Azure services to which this service endpoint rule applies to. + TargetServices []EgressResourceType + // The list of subnets from which network traffic originates when + // accessing your Azure resources. + Subnets []string +} + +type NetworkHealth struct { + ErrorType *string + // Details of the error. + ErrorMessage *string +} + +type NetworkVpcEndpoints struct { + // The VPC endpoint ID used by this network to access the Databricks REST API. + RestApi []string + // The VPC endpoint ID used by this network to access the secure + // cluster connectivity relay. + DataplaneRelay []string +} + +type NetworkWarning struct { + WarningType *string + // Details of the warning. + WarningMessage *string +} + +// *. +type PrivateAccessSettings struct { + // private access settings ID. + PrivateAccessSettingsId *string + // The account ID that hosts the private access settings. + AccountId *string + // The human-readable name of the private access settings object. + PrivateAccessSettingsName *string + // The AWS region for workspaces attached to this private access settings + // object. + Region *string + // Determines if the workspace can be accessed over public internet. For fully + // private workspaces, you can optionally specify false, but only if you + // implement both the front-end and the back-end PrivateLink connections. + // Otherwise, specify true, which means that public access is enabled. + PublicAccessEnabled *bool + // The private access level controls which VPC endpoints can connect to the UI + // or API of any workspace that attaches this private access settings object. + // `ACCOUNT` level access (the default) allows only VPC endpoints that are + // registered in your account connect to your workspace. `ENDPOINT` + // level access allows only specified VPC endpoints connect to your workspace. + // For details, see allowed_vpc_endpoint_ids. + PrivateAccessLevel PrivateAccessLevel + // An array of Databricks VPC endpoint IDs. This is the ID that is + // returned when registering the VPC endpoint configuration in your + // account. This is not the ID of the VPC endpoint in AWS. Only used when + // private_access_level is set to ENDPOINT. This is an allow list of VPC + // endpoints that in your account that can connect to your workspace over AWS + // PrivateLink. If hybrid access to your workspace is enabled by setting + // public_access_enabled to true, this control only works for PrivateLink + // connections. To control how your workspace is accessed via public internet, + // see IP access lists. + AllowedVpcEndpointIds []string +} + +// Details required to replace an IP access list.. +type ReplaceAccountIpAccessListRequest struct { + AccountId *string + // The ID for the corresponding IP access list + ListId *string + // Label for the IP access list. This **cannot** be empty. + Label *string + ListType AccountIpAccessListType_IpAccessListType + IpAddresses []string + // Specifies whether this IP access list is enabled. + Enabled *bool +} + +// The IP access list was successfully replaced.. +type ReplaceAccountIpAccessListResponse struct { + IpAccessList *AccountIpAccessList +} + +// Details required to replace an IP access list.. +type ReplaceIpAccessListRequest struct { + // The ID for the corresponding IP access list + ListId *string + // Label for the IP access list. This **cannot** be empty. + Label *string + ListType IpAccessListType + IpAddresses []string + // Specifies whether this IP access list is enabled. + Enabled *bool +} + +// The IP access list was successfully replaced.. +type ReplaceIpAccessListResponse struct { + IpAccessList *IpAccessList +} + +// Details required to update an IP access list.. +type UpdateAccountIpAccessListRequest struct { + AccountId *string + // The ID for the corresponding IP access list + ListId *string + // Label for the IP access list. This **cannot** be empty. + Label *string + ListType AccountIpAccessListType_IpAccessListType + IpAddresses []string + // Specifies whether this IP access list is enabled. + Enabled *bool +} + +// The IP access list was successfully updated.. +type UpdateAccountIpAccessListResponse struct { + IpAccessList *AccountIpAccessList +} + +// Details required to update an IP access list.. +type UpdateIpAccessListRequest struct { + // The ID for the corresponding IP access list + ListId *string + // Label for the IP access list. This **cannot** be empty. + Label *string + ListType IpAccessListType + IpAddresses []string + // Specifies whether this IP access list is enabled. + Enabled *bool +} + +// The IP access list was successfully updated.. +type UpdateIpAccessListResponse struct { + IpAccessList *IpAccessList +} + +// Your Network Connectivity Configuration ID.. +type UpdateNccPrivateEndpointRuleRequest struct { + // The ID of a network connectivity configuration, which is the parent resource + // of this private endpoint rule object. + NetworkConnectivityConfigId *string + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // Your private endpoint rule ID. + PrivateEndpointRuleId *string + PrivateEndpointRule *UpdatePrivateEndpointRule + UpdateMask *types.FieldMask[UpdatePrivateEndpointRule] +} + +type UpdateNetworkPolicyRequest struct { + // The unique identifier for the network policy. + NetworkPolicyId *string + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // Updated network policy configuration details. + NetworkPolicy *AccountNetworkPolicy +} + +type UpdatePrivateAccessSettingsRequest struct { + // Properties of the new private access settings object. + CustomerFacingPrivateAccessSettings *PrivateAccessSettings +} + +// Properties of the new private endpoint rule. Note that you must approve the +// endpoint in Azure portal after initialization.. +type UpdatePrivateEndpointRule struct { + // The ID of a private endpoint rule. + RuleId *string `fieldmask:"rule_id"` + // The ID of a network connectivity configuration, which is the parent resource + // of this private endpoint rule object. + NetworkConnectivityConfigId *string `fieldmask:"network_connectivity_config_id"` + // The current status of this private endpoint. The private endpoint rules are + // effective only if the connection state is ESTABLISHED. Remember that you must + // approve new endpoints on your resources in the Cloud console before they take + // effect. The possible values are: - PENDING: The endpoint has been created and + // pending approval. - ESTABLISHED: The endpoint has been approved and is ready + // to use in your serverless compute resources. - REJECTED: Connection was + // rejected by the private link resource owner. - DISCONNECTED: Connection was + // removed by the private link resource owner, the private endpoint becomes + // informative and should be deleted for clean-up. - EXPIRED: If the endpoint + // was created but not approved in 14 days, it will be EXPIRED. - CREATING: The + // endpoint creation is in progress. Once successfully created, the state will + // transition to PENDING. - CREATE_FAILED: The endpoint creation failed. You can + // check the error_message field for more details. + ConnectionState NccPrivateEndpointRule_PrivateLinkConnectionState `fieldmask:"connection_state"` + // Only used by private endpoints to customer-managed private endpoint services. + // + // Domain names of target private link service. When updating this field, the + // full list of target domain_names must be specified. + DomainNames []string `fieldmask:"domain_names"` + // Time in epoch milliseconds when this object was created. + CreationTime *int64 `fieldmask:"creation_time"` + // Time in epoch milliseconds when this object was updated. + UpdatedTime *int64 `fieldmask:"updated_time"` + // Whether this private endpoint is deactivated. + Deactivated *bool `fieldmask:"deactivated"` + // Time in epoch milliseconds when this object was deactivated. + DeactivatedAt *int64 `fieldmask:"deactivated_at"` + ErrorMessage *string `fieldmask:"error_message"` + // The Azure resource ID of the target resource. + ResourceId *string `fieldmask:"resource_id"` + // Not used by customer-managed private endpoint services. + // + // The sub-resource type (group ID) of the target resource. Note that to connect + // to workspace root storage (root DBFS), you need two endpoints, one for blob + // and one for dfs. + GroupId *string `fieldmask:"group_id"` + // The name of the Azure private endpoint resource. + EndpointName *string `fieldmask:"endpoint_name"` + // account ID. You can find your account ID from the Accounts + // Console. + AccountId *string `fieldmask:"account_id"` + // The full target AWS endpoint service name that connects to the destination + // resources of the private endpoint. + EndpointService *string `fieldmask:"endpoint_service"` + // Only used by private endpoints towards AWS S3 service. + // + // The globally unique S3 bucket names that will be accessed via the VPC + // endpoint. The bucket names must be in the same region as the NCC/endpoint + // service. When updating this field, we perform full update on this field. + // Please ensure a full list of desired resource_names is provided. + ResourceNames []string `fieldmask:"resource_names"` + // The AWS VPC endpoint ID. You can use this ID to identify the VPC endpoint + // created by . + VpcEndpointId *string `fieldmask:"vpc_endpoint_id"` + // Update this field to activate/deactivate this private endpoint to allow + // egress access from serverless compute resources. Only honored for first-party + // services on each cloud (e.g. AWS S3). + Enabled *bool `fieldmask:"enabled"` + Endpoint isUpdatePrivateEndpointRule_Endpoint + _ [0]updatePrivateEndpointRuleEndpointFieldMaskMetadata `fieldmask_oneof:"Endpoint"` +} + +type isUpdatePrivateEndpointRule_Endpoint interface { + isUpdatePrivateEndpointRule_Endpoint() +} + +// UpdatePrivateEndpointRule_Endpoint_GcpEndpoint selects GcpEndpoint for UpdatePrivateEndpointRule.Endpoint. +type UpdatePrivateEndpointRule_Endpoint_GcpEndpoint struct { + GcpEndpoint GcpEndpoint `fieldmask:"gcp_endpoint"` +} + +func (*UpdatePrivateEndpointRule_Endpoint_GcpEndpoint) isUpdatePrivateEndpointRule_Endpoint() {} + +type updatePrivateEndpointRuleEndpointFieldMaskMetadata struct { + *UpdatePrivateEndpointRule_Endpoint_GcpEndpoint +} + +type UpdateWorkspaceNetworkOptionRequest struct { + // Your account ID. You can find your account ID in your + // accounts console. + AccountId *string + // The workspace ID. + WorkspaceId *int64 + // The network option details for the workspace. + WorkspaceNetworkOption *WorkspaceNetworkOption +} + +// *. +type VpcEndpoint struct { + // Databricks VPC endpoint ID. This is the -specific name of the VPC + // endpoint. Do not confuse this with the `aws_vpc_endpoint_id`, which is the ID + // within AWS of the VPC endpoint. + VpcEndpointId *string + // The account ID that hosts the VPC endpoint configuration. + AccountId *string + // The human-readable name of the storage configuration. + VpcEndpointName *string + // The ID of the VPC endpoint object in AWS. + AwsVpcEndpointId *string + // The ID of the [endpoint service] that this VPC endpoint is + // connected to. For a list of endpoint service IDs for each supported AWS + // region, see the [Databricks PrivateLink documentation]. + // + // [Databricks PrivateLink documentation]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html + // [endpoint service]: https://docs.aws.amazon.com/vpc/latest/privatelink/endpoint-service.html + AwsEndpointServiceId *string + // This enumeration represents the type of Databricks VPC endpoint service that + // was used when creating this VPC endpoint. If the VPC endpoint connects to the + // control plane for either the front-end connection or the + // back-end REST API connection, the value is GENERAL_ACCESS. If the VPC + // endpoint connects to the workspace for the back-end secure + // cluster connectivity relay, the value is DATAPLANE_RELAY_ACCESS. + UseCase VpcEndpointUseCase + // The AWS region in which this VPC endpoint object exists. + Region *string + // The AWS Account in which the VPC endpoint object exists. + AwsAccountId *string + // The current state (such as `available` or `rejected`) of the VPC endpoint. + // Derived from AWS. For the full set of values, see [AWS DescribeVpcEndpoint + // documentation]. + // + // [AWS DescribeVpcEndpoint documentation]: https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-vpc-endpoints.html + State *string + VpcEndpointInfo isVpcEndpoint_VpcEndpointInfo +} + +type isVpcEndpoint_VpcEndpointInfo interface { + isVpcEndpoint_VpcEndpointInfo() +} + +// VpcEndpoint_VpcEndpointInfo_GcpVpcEndpointInfo selects GcpVpcEndpointInfo for VpcEndpoint.VpcEndpointInfo. +// The cloud info of this vpc endpoint. Info for a GCP vpc endpoint. +type VpcEndpoint_VpcEndpointInfo_GcpVpcEndpointInfo struct { + GcpVpcEndpointInfo GcpVpcEndpointInfo +} + +func (*VpcEndpoint_VpcEndpointInfo_GcpVpcEndpointInfo) isVpcEndpoint_VpcEndpointInfo() {} + +type WorkspaceNetworkOption struct { + // The network policy ID to apply to the workspace. This controls the network + // access rules for all serverless compute resources in the workspace. Each + // workspace can only be linked to one policy at a time. If no policy is + // explicitly assigned, the workspace will use 'default-policy'. + NetworkPolicyId *string + // The workspace ID. + WorkspaceId *int64 +} diff --git a/networking/v1/wire.go b/networking/v1/wire.go new file mode 100755 index 0000000..ca0aefc --- /dev/null +++ b/networking/v1/wire.go @@ -0,0 +1,3165 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package networking + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type accountIpAccessListWire struct { + ListId *string `json:"list_id,omitempty"` + Label *string `json:"label,omitempty"` + IpAddresses []string `json:"ip_addresses,omitempty"` + AddressCount *int `json:"address_count,omitempty"` + ListType AccountIpAccessListType_IpAccessListType `json:"list_type,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *int64 `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *int64 `json:"updated_by,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func accountIpAccessListFromWire(w *accountIpAccessListWire) (*AccountIpAccessList, error) { + if w == nil { + return nil, nil + } + return &AccountIpAccessList{ + ListId: w.ListId, + Label: w.Label, + IpAddresses: w.IpAddresses, + AddressCount: w.AddressCount, + ListType: w.ListType, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + Enabled: w.Enabled, + }, nil +} + +type accountNetworkPolicyWire struct { + NetworkPolicyId *string `json:"network_policy_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + Egress *egressNetworkPolicyWire `json:"egress,omitempty"` + Ingress *ingressNetworkPolicyWire `json:"ingress,omitempty"` + IngressDryRun *ingressNetworkPolicyWire `json:"ingress_dry_run,omitempty"` +} + +func accountNetworkPolicyToWire(v *AccountNetworkPolicy) (*accountNetworkPolicyWire, error) { + if v == nil { + return nil, nil + } + egressWireValue, err := egressNetworkPolicyToWire(v.Egress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountNetworkPolicy.Egress", err) + } + ingressWireValue, err := ingressNetworkPolicyToWire(v.Ingress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountNetworkPolicy.Ingress", err) + } + ingressDryRunWireValue, err := ingressNetworkPolicyToWire(v.IngressDryRun) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountNetworkPolicy.IngressDryRun", err) + } + return &accountNetworkPolicyWire{ + NetworkPolicyId: v.NetworkPolicyId, + AccountId: v.AccountId, + Egress: egressWireValue, + Ingress: ingressWireValue, + IngressDryRun: ingressDryRunWireValue, + }, nil +} + +func accountNetworkPolicyFromWire(w *accountNetworkPolicyWire) (*AccountNetworkPolicy, error) { + if w == nil { + return nil, nil + } + egressPublicValue, err := egressNetworkPolicyFromWire(w.Egress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountNetworkPolicy.Egress", err) + } + ingressPublicValue, err := ingressNetworkPolicyFromWire(w.Ingress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountNetworkPolicy.Ingress", err) + } + ingressDryRunPublicValue, err := ingressNetworkPolicyFromWire(w.IngressDryRun) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountNetworkPolicy.IngressDryRun", err) + } + return &AccountNetworkPolicy{ + NetworkPolicyId: w.NetworkPolicyId, + AccountId: w.AccountId, + Egress: egressPublicValue, + Ingress: ingressPublicValue, + IngressDryRun: ingressDryRunPublicValue, + }, nil +} + +type awsVpcEndpointInfoWire struct { + AwsVpcEndpointId *string `json:"aws_vpc_endpoint_id,omitempty"` + AwsEndpointServiceId *string `json:"aws_endpoint_service_id,omitempty"` + AwsAccountId *string `json:"aws_account_id,omitempty"` +} + +func awsVpcEndpointInfoToWire(v *AwsVpcEndpointInfo) (*awsVpcEndpointInfoWire, error) { + if v == nil { + return nil, nil + } + return &awsVpcEndpointInfoWire{ + AwsVpcEndpointId: v.AwsVpcEndpointId, + AwsEndpointServiceId: v.AwsEndpointServiceId, + AwsAccountId: v.AwsAccountId, + }, nil +} + +func awsVpcEndpointInfoFromWire(w *awsVpcEndpointInfoWire) (*AwsVpcEndpointInfo, error) { + if w == nil { + return nil, nil + } + return &AwsVpcEndpointInfo{ + AwsVpcEndpointId: w.AwsVpcEndpointId, + AwsEndpointServiceId: w.AwsEndpointServiceId, + AwsAccountId: w.AwsAccountId, + }, nil +} + +type azurePrivateEndpointInfoWire struct { + PrivateEndpointName *string `json:"private_endpoint_name,omitempty"` + PrivateEndpointResourceGuid *string `json:"private_endpoint_resource_guid,omitempty"` + PrivateEndpointResourceId *string `json:"private_endpoint_resource_id,omitempty"` + PrivateLinkServiceId *string `json:"private_link_service_id,omitempty"` +} + +func azurePrivateEndpointInfoToWire(v *AzurePrivateEndpointInfo) (*azurePrivateEndpointInfoWire, error) { + if v == nil { + return nil, nil + } + return &azurePrivateEndpointInfoWire{ + PrivateEndpointName: v.PrivateEndpointName, + PrivateEndpointResourceGuid: v.PrivateEndpointResourceGuid, + PrivateEndpointResourceId: v.PrivateEndpointResourceId, + PrivateLinkServiceId: v.PrivateLinkServiceId, + }, nil +} + +func azurePrivateEndpointInfoFromWire(w *azurePrivateEndpointInfoWire) (*AzurePrivateEndpointInfo, error) { + if w == nil { + return nil, nil + } + return &AzurePrivateEndpointInfo{ + PrivateEndpointName: w.PrivateEndpointName, + PrivateEndpointResourceGuid: w.PrivateEndpointResourceGuid, + PrivateEndpointResourceId: w.PrivateEndpointResourceId, + PrivateLinkServiceId: w.PrivateLinkServiceId, + }, nil +} + +type createAccountIpAccessListRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + Label *string `json:"label,omitempty"` + ListType AccountIpAccessListType_IpAccessListType `json:"list_type,omitempty"` + IpAddresses []string `json:"ip_addresses,omitempty"` +} + +func createAccountIpAccessListRequestToWire(v *CreateAccountIpAccessListRequest) (*createAccountIpAccessListRequestWire, error) { + if v == nil { + return nil, nil + } + return &createAccountIpAccessListRequestWire{ + AccountId: v.AccountId, + Label: v.Label, + ListType: v.ListType, + IpAddresses: v.IpAddresses, + }, nil +} + +type createAccountIpAccessListResponseWire struct { + IpAccessList *accountIpAccessListWire `json:"ip_access_list,omitempty"` +} + +func createAccountIpAccessListResponseFromWire(w *createAccountIpAccessListResponseWire) (*CreateAccountIpAccessListResponse, error) { + if w == nil { + return nil, nil + } + ipAccessListPublicValue, err := accountIpAccessListFromWire(w.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountIpAccessListResponse.IpAccessList", err) + } + return &CreateAccountIpAccessListResponse{ + IpAccessList: ipAccessListPublicValue, + }, nil +} + +type createEndpointRequestWire struct { + Parent *string `json:"parent,omitempty"` + Endpoint *endpointWire `json:"endpoint,omitempty"` +} + +func createEndpointRequestToWire(v *CreateEndpointRequest) (*createEndpointRequestWire, error) { + if v == nil { + return nil, nil + } + endpointWireValue, err := endpointToWire(v.Endpoint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateEndpointRequest.Endpoint", err) + } + return &createEndpointRequestWire{ + Parent: v.Parent, + Endpoint: endpointWireValue, + }, nil +} + +type createIpAccessListRequestWire struct { + Label *string `json:"label,omitempty"` + ListType IpAccessListType `json:"list_type,omitempty"` + IpAddresses []string `json:"ip_addresses,omitempty"` +} + +func createIpAccessListRequestToWire(v *CreateIpAccessListRequest) (*createIpAccessListRequestWire, error) { + if v == nil { + return nil, nil + } + return &createIpAccessListRequestWire{ + Label: v.Label, + ListType: v.ListType, + IpAddresses: v.IpAddresses, + }, nil +} + +type createIpAccessListResponseWire struct { + IpAccessList *ipAccessListWire `json:"ip_access_list,omitempty"` +} + +func createIpAccessListResponseFromWire(w *createIpAccessListResponseWire) (*CreateIpAccessListResponse, error) { + if w == nil { + return nil, nil + } + ipAccessListPublicValue, err := ipAccessListFromWire(w.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateIpAccessListResponse.IpAccessList", err) + } + return &CreateIpAccessListResponse{ + IpAccessList: ipAccessListPublicValue, + }, nil +} + +type createNccPrivateEndpointRuleRequestWire struct { + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + PrivateEndpointRule *createPrivateEndpointRuleWire `json:"private_endpoint_rule,omitempty"` +} + +func createNccPrivateEndpointRuleRequestToWire(v *CreateNccPrivateEndpointRuleRequest) (*createNccPrivateEndpointRuleRequestWire, error) { + if v == nil { + return nil, nil + } + privateEndpointRuleWireValue, err := createPrivateEndpointRuleToWire(v.PrivateEndpointRule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateNccPrivateEndpointRuleRequest.PrivateEndpointRule", err) + } + return &createNccPrivateEndpointRuleRequestWire{ + NetworkConnectivityConfigId: v.NetworkConnectivityConfigId, + AccountId: v.AccountId, + PrivateEndpointRule: privateEndpointRuleWireValue, + }, nil +} + +type createNetworkConnectivityConfigRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + NetworkConnectivityConfig *createNetworkConnectivityConfigurationWire `json:"network_connectivity_config,omitempty"` +} + +func createNetworkConnectivityConfigRequestToWire(v *CreateNetworkConnectivityConfigRequest) (*createNetworkConnectivityConfigRequestWire, error) { + if v == nil { + return nil, nil + } + networkConnectivityConfigWireValue, err := createNetworkConnectivityConfigurationToWire(v.NetworkConnectivityConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateNetworkConnectivityConfigRequest.NetworkConnectivityConfig", err) + } + return &createNetworkConnectivityConfigRequestWire{ + AccountId: v.AccountId, + NetworkConnectivityConfig: networkConnectivityConfigWireValue, + }, nil +} + +type createNetworkConnectivityConfigurationWire struct { + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + Name *string `json:"name,omitempty"` + Region *string `json:"region,omitempty"` + EgressConfig *customerFacingNetworkConnectivityConfigEgressConfigWire `json:"egress_config,omitempty"` + UpdatedTime *int64 `json:"updated_time,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` +} + +func createNetworkConnectivityConfigurationToWire(v *CreateNetworkConnectivityConfiguration) (*createNetworkConnectivityConfigurationWire, error) { + if v == nil { + return nil, nil + } + egressConfigWireValue, err := customerFacingNetworkConnectivityConfigEgressConfigToWire(v.EgressConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateNetworkConnectivityConfiguration.EgressConfig", err) + } + return &createNetworkConnectivityConfigurationWire{ + NetworkConnectivityConfigId: v.NetworkConnectivityConfigId, + AccountId: v.AccountId, + Name: v.Name, + Region: v.Region, + EgressConfig: egressConfigWireValue, + UpdatedTime: v.UpdatedTime, + CreationTime: v.CreationTime, + }, nil +} + +type createNetworkPolicyRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + NetworkPolicy *accountNetworkPolicyWire `json:"network_policy,omitempty"` +} + +func createNetworkPolicyRequestToWire(v *CreateNetworkPolicyRequest) (*createNetworkPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + networkPolicyWireValue, err := accountNetworkPolicyToWire(v.NetworkPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateNetworkPolicyRequest.NetworkPolicy", err) + } + return &createNetworkPolicyRequestWire{ + AccountId: v.AccountId, + NetworkPolicy: networkPolicyWireValue, + }, nil +} + +type createNetworkRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + NetworkName *string `json:"network_name,omitempty"` + VpcId *string `json:"vpc_id,omitempty"` + SubnetIds []string `json:"subnet_ids,omitempty"` + SecurityGroupIds []string `json:"security_group_ids,omitempty"` + VpcEndpoints *networkVpcEndpointsWire `json:"vpc_endpoints,omitempty"` + GcpNetworkInfo *gcpNetworkInfoWire `json:"gcp_network_info,omitempty"` +} + +func createNetworkRequestToWire(v *CreateNetworkRequest) (*createNetworkRequestWire, error) { + if v == nil { + return nil, nil + } + vpcEndpointsWireValue, err := networkVpcEndpointsToWire(v.VpcEndpoints) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateNetworkRequest.VpcEndpoints", err) + } + gcpNetworkInfoWireValue, err := gcpNetworkInfoToWire(v.GcpNetworkInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateNetworkRequest.GcpNetworkInfo", err) + } + return &createNetworkRequestWire{ + AccountId: v.AccountId, + NetworkName: v.NetworkName, + VpcId: v.VpcId, + SubnetIds: v.SubnetIds, + SecurityGroupIds: v.SecurityGroupIds, + VpcEndpoints: vpcEndpointsWireValue, + GcpNetworkInfo: gcpNetworkInfoWireValue, + }, nil +} + +type createPrivateAccessSettingsRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + PrivateAccessSettingsName *string `json:"private_access_settings_name,omitempty"` + Region *string `json:"region,omitempty"` + PublicAccessEnabled *bool `json:"public_access_enabled,omitempty"` + PrivateAccessLevel PrivateAccessLevel `json:"private_access_level,omitempty"` + AllowedVpcEndpointIds []string `json:"allowed_vpc_endpoint_ids,omitempty"` +} + +func createPrivateAccessSettingsRequestToWire(v *CreatePrivateAccessSettingsRequest) (*createPrivateAccessSettingsRequestWire, error) { + if v == nil { + return nil, nil + } + return &createPrivateAccessSettingsRequestWire{ + AccountId: v.AccountId, + PrivateAccessSettingsName: v.PrivateAccessSettingsName, + Region: v.Region, + PublicAccessEnabled: v.PublicAccessEnabled, + PrivateAccessLevel: v.PrivateAccessLevel, + AllowedVpcEndpointIds: v.AllowedVpcEndpointIds, + }, nil +} + +type createPrivateEndpointRuleWire struct { + RuleId *string `json:"rule_id,omitempty"` + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + ConnectionState NccPrivateEndpointRule_PrivateLinkConnectionState `json:"connection_state,omitempty"` + DomainNames []string `json:"domain_names,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + UpdatedTime *int64 `json:"updated_time,omitempty"` + Deactivated *bool `json:"deactivated,omitempty"` + DeactivatedAt *int64 `json:"deactivated_at,omitempty"` + ErrorMessage *string `json:"error_message,omitempty"` + ResourceId *string `json:"resource_id,omitempty"` + GroupId *string `json:"group_id,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + AccountId *string `json:"account_id,omitempty"` + EndpointService *string `json:"endpoint_service,omitempty"` + ResourceNames []string `json:"resource_names,omitempty"` + VpcEndpointId *string `json:"vpc_endpoint_id,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + GcpEndpoint *gcpEndpointWire `json:"gcp_endpoint,omitempty"` +} + +func createPrivateEndpointRuleToWire(v *CreatePrivateEndpointRule) (*createPrivateEndpointRuleWire, error) { + if v == nil { + return nil, nil + } + var endpointGcpEndpointWire *gcpEndpointWire + switch value := v.Endpoint.(type) { + case nil: + case *CreatePrivateEndpointRule_Endpoint_GcpEndpoint: + if value != nil { + endpointGcpEndpointConverted, err := gcpEndpointToWire(&value.GcpEndpoint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePrivateEndpointRule.Endpoint.GcpEndpoint", err) + } + endpointGcpEndpointWire = endpointGcpEndpointConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreatePrivateEndpointRule.Endpoint", value) + } + return &createPrivateEndpointRuleWire{ + RuleId: v.RuleId, + NetworkConnectivityConfigId: v.NetworkConnectivityConfigId, + ConnectionState: v.ConnectionState, + DomainNames: v.DomainNames, + CreationTime: v.CreationTime, + UpdatedTime: v.UpdatedTime, + Deactivated: v.Deactivated, + DeactivatedAt: v.DeactivatedAt, + ErrorMessage: v.ErrorMessage, + ResourceId: v.ResourceId, + GroupId: v.GroupId, + EndpointName: v.EndpointName, + AccountId: v.AccountId, + EndpointService: v.EndpointService, + ResourceNames: v.ResourceNames, + VpcEndpointId: v.VpcEndpointId, + Enabled: v.Enabled, + GcpEndpoint: endpointGcpEndpointWire, + }, nil +} + +type createVpcEndpointRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + VpcEndpointName *string `json:"vpc_endpoint_name,omitempty"` + Region *string `json:"region,omitempty"` + AwsVpcEndpointId *string `json:"aws_vpc_endpoint_id,omitempty"` + GcpVpcEndpointInfo *gcpVpcEndpointInfoWire `json:"gcp_vpc_endpoint_info,omitempty"` +} + +func createVpcEndpointRequestToWire(v *CreateVpcEndpointRequest) (*createVpcEndpointRequestWire, error) { + if v == nil { + return nil, nil + } + var vpcEndpointInfoGcpVpcEndpointInfoWire *gcpVpcEndpointInfoWire + switch value := v.VpcEndpointInfo.(type) { + case nil: + case *CreateVpcEndpointRequest_VpcEndpointInfo_GcpVpcEndpointInfo: + if value != nil { + vpcEndpointInfoGcpVpcEndpointInfoConverted, err := gcpVpcEndpointInfoToWire(&value.GcpVpcEndpointInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateVpcEndpointRequest.VpcEndpointInfo.GcpVpcEndpointInfo", err) + } + vpcEndpointInfoGcpVpcEndpointInfoWire = vpcEndpointInfoGcpVpcEndpointInfoConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreateVpcEndpointRequest.VpcEndpointInfo", value) + } + return &createVpcEndpointRequestWire{ + AccountId: v.AccountId, + VpcEndpointName: v.VpcEndpointName, + Region: v.Region, + AwsVpcEndpointId: v.AwsVpcEndpointId, + GcpVpcEndpointInfo: vpcEndpointInfoGcpVpcEndpointInfoWire, + }, nil +} + +type customerFacingNetworkConnectivityConfigEgressConfigWire struct { + DefaultRules *networkConnectivityConfigEgressConfig_DefaultRuleWire `json:"default_rules,omitempty"` + TargetRules *customerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRuleWire `json:"target_rules,omitempty"` +} + +func customerFacingNetworkConnectivityConfigEgressConfigToWire(v *CustomerFacingNetworkConnectivityConfigEgressConfig) (*customerFacingNetworkConnectivityConfigEgressConfigWire, error) { + if v == nil { + return nil, nil + } + defaultRulesWireValue, err := networkConnectivityConfigEgressConfig_DefaultRuleToWire(v.DefaultRules) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerFacingNetworkConnectivityConfigEgressConfig.DefaultRules", err) + } + targetRulesWireValue, err := customerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRuleToWire(v.TargetRules) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerFacingNetworkConnectivityConfigEgressConfig.TargetRules", err) + } + return &customerFacingNetworkConnectivityConfigEgressConfigWire{ + DefaultRules: defaultRulesWireValue, + TargetRules: targetRulesWireValue, + }, nil +} + +func customerFacingNetworkConnectivityConfigEgressConfigFromWire(w *customerFacingNetworkConnectivityConfigEgressConfigWire) (*CustomerFacingNetworkConnectivityConfigEgressConfig, error) { + if w == nil { + return nil, nil + } + defaultRulesPublicValue, err := networkConnectivityConfigEgressConfig_DefaultRuleFromWire(w.DefaultRules) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerFacingNetworkConnectivityConfigEgressConfig.DefaultRules", err) + } + targetRulesPublicValue, err := customerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRuleFromWire(w.TargetRules) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerFacingNetworkConnectivityConfigEgressConfig.TargetRules", err) + } + return &CustomerFacingNetworkConnectivityConfigEgressConfig{ + DefaultRules: defaultRulesPublicValue, + TargetRules: targetRulesPublicValue, + }, nil +} + +type customerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRuleWire struct { + AzurePrivateEndpointRules []networkConnectivityConfigAzurePrivateEndpointRuleWire `json:"azure_private_endpoint_rules,omitempty"` + AwsPrivateEndpointRules []networkConnectivityConfigAwsPrivateEndpointRuleWire `json:"aws_private_endpoint_rules,omitempty"` +} + +func customerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRuleToWire(v *CustomerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRule) (*customerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRuleWire, error) { + if v == nil { + return nil, nil + } + azurePrivateEndpointRulesWireValue, err := convertSlice(v.AzurePrivateEndpointRules, networkConnectivityConfigAzurePrivateEndpointRuleToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRule.AzurePrivateEndpointRules", err) + } + awsPrivateEndpointRulesWireValue, err := convertSlice(v.AwsPrivateEndpointRules, networkConnectivityConfigAwsPrivateEndpointRuleToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRule.AwsPrivateEndpointRules", err) + } + return &customerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRuleWire{ + AzurePrivateEndpointRules: azurePrivateEndpointRulesWireValue, + AwsPrivateEndpointRules: awsPrivateEndpointRulesWireValue, + }, nil +} + +func customerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRuleFromWire(w *customerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRuleWire) (*CustomerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRule, error) { + if w == nil { + return nil, nil + } + azurePrivateEndpointRulesPublicValue, err := convertSlice(w.AzurePrivateEndpointRules, networkConnectivityConfigAzurePrivateEndpointRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRule.AzurePrivateEndpointRules", err) + } + awsPrivateEndpointRulesPublicValue, err := convertSlice(w.AwsPrivateEndpointRules, networkConnectivityConfigAwsPrivateEndpointRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRule.AwsPrivateEndpointRules", err) + } + return &CustomerFacingNetworkConnectivityConfigEgressConfig_CustomerFacingTargetRule{ + AzurePrivateEndpointRules: azurePrivateEndpointRulesPublicValue, + AwsPrivateEndpointRules: awsPrivateEndpointRulesPublicValue, + }, nil +} + +type egressNetworkPolicyWire struct { + NetworkAccess *egressNetworkPolicy_NetworkAccessPolicyWire `json:"network_access,omitempty"` +} + +func egressNetworkPolicyToWire(v *EgressNetworkPolicy) (*egressNetworkPolicyWire, error) { + if v == nil { + return nil, nil + } + networkAccessWireValue, err := egressNetworkPolicy_NetworkAccessPolicyToWire(v.NetworkAccess) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy.NetworkAccess", err) + } + return &egressNetworkPolicyWire{ + NetworkAccess: networkAccessWireValue, + }, nil +} + +func egressNetworkPolicyFromWire(w *egressNetworkPolicyWire) (*EgressNetworkPolicy, error) { + if w == nil { + return nil, nil + } + networkAccessPublicValue, err := egressNetworkPolicy_NetworkAccessPolicyFromWire(w.NetworkAccess) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy.NetworkAccess", err) + } + return &EgressNetworkPolicy{ + NetworkAccess: networkAccessPublicValue, + }, nil +} + +type egressNetworkPolicy_NetworkAccessPolicyWire struct { + RestrictionMode EgressNetworkPolicy_NetworkAccessPolicy_RestrictionMode `json:"restriction_mode,omitempty"` + AllowedInternetDestinations []egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationWire `json:"allowed_internet_destinations,omitempty"` + AllowedStorageDestinations []egressNetworkPolicy_NetworkAccessPolicy_StorageDestinationWire `json:"allowed_storage_destinations,omitempty"` + PolicyEnforcement *egressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcementWire `json:"policy_enforcement,omitempty"` + BlockedInternetDestinations []egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationWire `json:"blocked_internet_destinations,omitempty"` + AllowedDatabricksDestinations []egressNetworkPolicy_NetworkAccessPolicy_DatabricksDestinationWire `json:"allowed_databricks_destinations,omitempty"` +} + +func egressNetworkPolicy_NetworkAccessPolicyToWire(v *EgressNetworkPolicy_NetworkAccessPolicy) (*egressNetworkPolicy_NetworkAccessPolicyWire, error) { + if v == nil { + return nil, nil + } + allowedInternetDestinationsWireValue, err := convertSlice(v.AllowedInternetDestinations, egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_NetworkAccessPolicy.AllowedInternetDestinations", err) + } + allowedStorageDestinationsWireValue, err := convertSlice(v.AllowedStorageDestinations, egressNetworkPolicy_NetworkAccessPolicy_StorageDestinationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_NetworkAccessPolicy.AllowedStorageDestinations", err) + } + policyEnforcementWireValue, err := egressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcementToWire(v.PolicyEnforcement) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_NetworkAccessPolicy.PolicyEnforcement", err) + } + blockedInternetDestinationsWireValue, err := convertSlice(v.BlockedInternetDestinations, egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_NetworkAccessPolicy.BlockedInternetDestinations", err) + } + allowedDatabricksDestinationsWireValue, err := convertSlice(v.AllowedDatabricksDestinations, egressNetworkPolicy_NetworkAccessPolicy_DatabricksDestinationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_NetworkAccessPolicy.AllowedDatabricksDestinations", err) + } + return &egressNetworkPolicy_NetworkAccessPolicyWire{ + RestrictionMode: v.RestrictionMode, + AllowedInternetDestinations: allowedInternetDestinationsWireValue, + AllowedStorageDestinations: allowedStorageDestinationsWireValue, + PolicyEnforcement: policyEnforcementWireValue, + BlockedInternetDestinations: blockedInternetDestinationsWireValue, + AllowedDatabricksDestinations: allowedDatabricksDestinationsWireValue, + }, nil +} + +func egressNetworkPolicy_NetworkAccessPolicyFromWire(w *egressNetworkPolicy_NetworkAccessPolicyWire) (*EgressNetworkPolicy_NetworkAccessPolicy, error) { + if w == nil { + return nil, nil + } + allowedInternetDestinationsPublicValue, err := convertSlice(w.AllowedInternetDestinations, egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_NetworkAccessPolicy.AllowedInternetDestinations", err) + } + allowedStorageDestinationsPublicValue, err := convertSlice(w.AllowedStorageDestinations, egressNetworkPolicy_NetworkAccessPolicy_StorageDestinationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_NetworkAccessPolicy.AllowedStorageDestinations", err) + } + policyEnforcementPublicValue, err := egressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcementFromWire(w.PolicyEnforcement) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_NetworkAccessPolicy.PolicyEnforcement", err) + } + blockedInternetDestinationsPublicValue, err := convertSlice(w.BlockedInternetDestinations, egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_NetworkAccessPolicy.BlockedInternetDestinations", err) + } + allowedDatabricksDestinationsPublicValue, err := convertSlice(w.AllowedDatabricksDestinations, egressNetworkPolicy_NetworkAccessPolicy_DatabricksDestinationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EgressNetworkPolicy_NetworkAccessPolicy.AllowedDatabricksDestinations", err) + } + return &EgressNetworkPolicy_NetworkAccessPolicy{ + RestrictionMode: w.RestrictionMode, + AllowedInternetDestinations: allowedInternetDestinationsPublicValue, + AllowedStorageDestinations: allowedStorageDestinationsPublicValue, + PolicyEnforcement: policyEnforcementPublicValue, + BlockedInternetDestinations: blockedInternetDestinationsPublicValue, + AllowedDatabricksDestinations: allowedDatabricksDestinationsPublicValue, + }, nil +} + +type egressNetworkPolicy_NetworkAccessPolicy_DatabricksDestinationWire struct { + WorkspaceIds []int64 `json:"workspace_ids,omitempty"` +} + +func egressNetworkPolicy_NetworkAccessPolicy_DatabricksDestinationToWire(v *EgressNetworkPolicy_NetworkAccessPolicy_DatabricksDestination) (*egressNetworkPolicy_NetworkAccessPolicy_DatabricksDestinationWire, error) { + if v == nil { + return nil, nil + } + return &egressNetworkPolicy_NetworkAccessPolicy_DatabricksDestinationWire{ + WorkspaceIds: v.WorkspaceIds, + }, nil +} + +func egressNetworkPolicy_NetworkAccessPolicy_DatabricksDestinationFromWire(w *egressNetworkPolicy_NetworkAccessPolicy_DatabricksDestinationWire) (*EgressNetworkPolicy_NetworkAccessPolicy_DatabricksDestination, error) { + if w == nil { + return nil, nil + } + return &EgressNetworkPolicy_NetworkAccessPolicy_DatabricksDestination{ + WorkspaceIds: w.WorkspaceIds, + }, nil +} + +type egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationWire struct { + Destination *string `json:"destination,omitempty"` + InternetDestinationType EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination_InternetDestinationType `json:"internet_destination_type,omitempty"` +} + +func egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationToWire(v *EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination) (*egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationWire, error) { + if v == nil { + return nil, nil + } + return &egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationWire{ + Destination: v.Destination, + InternetDestinationType: v.InternetDestinationType, + }, nil +} + +func egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationFromWire(w *egressNetworkPolicy_NetworkAccessPolicy_InternetDestinationWire) (*EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination, error) { + if w == nil { + return nil, nil + } + return &EgressNetworkPolicy_NetworkAccessPolicy_InternetDestination{ + Destination: w.Destination, + InternetDestinationType: w.InternetDestinationType, + }, nil +} + +type egressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcementWire struct { + EnforcementMode EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_EnforcementMode `json:"enforcement_mode,omitempty"` + DryRunModeProductFilter []EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement_DryRunModeProductFilter `json:"dry_run_mode_product_filter,omitempty"` +} + +func egressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcementToWire(v *EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement) (*egressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcementWire, error) { + if v == nil { + return nil, nil + } + return &egressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcementWire{ + EnforcementMode: v.EnforcementMode, + DryRunModeProductFilter: v.DryRunModeProductFilter, + }, nil +} + +func egressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcementFromWire(w *egressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcementWire) (*EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement, error) { + if w == nil { + return nil, nil + } + return &EgressNetworkPolicy_NetworkAccessPolicy_PolicyEnforcement{ + EnforcementMode: w.EnforcementMode, + DryRunModeProductFilter: w.DryRunModeProductFilter, + }, nil +} + +type egressNetworkPolicy_NetworkAccessPolicy_StorageDestinationWire struct { + BucketName *string `json:"bucket_name,omitempty"` + Region *string `json:"region,omitempty"` + StorageDestinationType EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination_StorageDestinationType `json:"storage_destination_type,omitempty"` + AzureStorageAccount *string `json:"azure_storage_account,omitempty"` + AzureStorageService *string `json:"azure_storage_service,omitempty"` +} + +func egressNetworkPolicy_NetworkAccessPolicy_StorageDestinationToWire(v *EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination) (*egressNetworkPolicy_NetworkAccessPolicy_StorageDestinationWire, error) { + if v == nil { + return nil, nil + } + return &egressNetworkPolicy_NetworkAccessPolicy_StorageDestinationWire{ + BucketName: v.BucketName, + Region: v.Region, + StorageDestinationType: v.StorageDestinationType, + AzureStorageAccount: v.AzureStorageAccount, + AzureStorageService: v.AzureStorageService, + }, nil +} + +func egressNetworkPolicy_NetworkAccessPolicy_StorageDestinationFromWire(w *egressNetworkPolicy_NetworkAccessPolicy_StorageDestinationWire) (*EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination, error) { + if w == nil { + return nil, nil + } + return &EgressNetworkPolicy_NetworkAccessPolicy_StorageDestination{ + BucketName: w.BucketName, + Region: w.Region, + StorageDestinationType: w.StorageDestinationType, + AzureStorageAccount: w.AzureStorageAccount, + AzureStorageService: w.AzureStorageService, + }, nil +} + +type endpointWire struct { + Name *string `json:"name,omitempty"` + EndpointId *string `json:"endpoint_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + UseCase EndpointUseCase_EndpointUseCase `json:"use_case,omitempty"` + Region *string `json:"region,omitempty"` + State EndpointState `json:"state,omitempty"` + AzurePrivateEndpointInfo *azurePrivateEndpointInfoWire `json:"azure_private_endpoint_info,omitempty"` + AwsVpcEndpointInfo *awsVpcEndpointInfoWire `json:"aws_vpc_endpoint_info,omitempty"` + GcpPscEndpointInfo *gcpPscEndpointInfoWire `json:"gcp_psc_endpoint_info,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` +} + +func endpointToWire(v *Endpoint) (*endpointWire, error) { + if v == nil { + return nil, nil + } + var endpointInfoAzurePrivateEndpointInfoWire *azurePrivateEndpointInfoWire + var endpointInfoAwsVpcEndpointInfoWire *awsVpcEndpointInfoWire + var endpointInfoGcpPscEndpointInfoWire *gcpPscEndpointInfoWire + switch value := v.EndpointInfo.(type) { + case nil: + case *Endpoint_EndpointInfo_AzurePrivateEndpointInfo: + if value != nil { + endpointInfoAzurePrivateEndpointInfoConverted, err := azurePrivateEndpointInfoToWire(&value.AzurePrivateEndpointInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.EndpointInfo.AzurePrivateEndpointInfo", err) + } + endpointInfoAzurePrivateEndpointInfoWire = endpointInfoAzurePrivateEndpointInfoConverted + } + case *Endpoint_EndpointInfo_AwsVpcEndpointInfo: + if value != nil { + endpointInfoAwsVpcEndpointInfoConverted, err := awsVpcEndpointInfoToWire(&value.AwsVpcEndpointInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.EndpointInfo.AwsVpcEndpointInfo", err) + } + endpointInfoAwsVpcEndpointInfoWire = endpointInfoAwsVpcEndpointInfoConverted + } + case *Endpoint_EndpointInfo_GcpPscEndpointInfo: + if value != nil { + endpointInfoGcpPscEndpointInfoConverted, err := gcpPscEndpointInfoToWire(&value.GcpPscEndpointInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.EndpointInfo.GcpPscEndpointInfo", err) + } + endpointInfoGcpPscEndpointInfoWire = endpointInfoGcpPscEndpointInfoConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Endpoint.EndpointInfo", value) + } + return &endpointWire{ + Name: v.Name, + EndpointId: v.EndpointId, + AccountId: v.AccountId, + DisplayName: v.DisplayName, + UseCase: v.UseCase, + Region: v.Region, + State: v.State, + AzurePrivateEndpointInfo: endpointInfoAzurePrivateEndpointInfoWire, + AwsVpcEndpointInfo: endpointInfoAwsVpcEndpointInfoWire, + GcpPscEndpointInfo: endpointInfoGcpPscEndpointInfoWire, + CreateTime: v.CreateTime, + }, nil +} + +func endpointFromWire(w *endpointWire) (*Endpoint, error) { + if w == nil { + return nil, nil + } + endpointInfoMembers := 0 + if w.AzurePrivateEndpointInfo != nil { + endpointInfoMembers++ + } + if w.AwsVpcEndpointInfo != nil { + endpointInfoMembers++ + } + if w.GcpPscEndpointInfo != nil { + endpointInfoMembers++ + } + if endpointInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Endpoint.EndpointInfo") + } + var endpointInfoSelection isEndpoint_EndpointInfo + switch { + case w.AzurePrivateEndpointInfo != nil: + endpointInfoAzurePrivateEndpointInfoConverted, err := azurePrivateEndpointInfoFromWire(w.AzurePrivateEndpointInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.EndpointInfo.AzurePrivateEndpointInfo", err) + } + endpointInfoSelection = &Endpoint_EndpointInfo_AzurePrivateEndpointInfo{AzurePrivateEndpointInfo: *endpointInfoAzurePrivateEndpointInfoConverted} + case w.AwsVpcEndpointInfo != nil: + endpointInfoAwsVpcEndpointInfoConverted, err := awsVpcEndpointInfoFromWire(w.AwsVpcEndpointInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.EndpointInfo.AwsVpcEndpointInfo", err) + } + endpointInfoSelection = &Endpoint_EndpointInfo_AwsVpcEndpointInfo{AwsVpcEndpointInfo: *endpointInfoAwsVpcEndpointInfoConverted} + case w.GcpPscEndpointInfo != nil: + endpointInfoGcpPscEndpointInfoConverted, err := gcpPscEndpointInfoFromWire(w.GcpPscEndpointInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.EndpointInfo.GcpPscEndpointInfo", err) + } + endpointInfoSelection = &Endpoint_EndpointInfo_GcpPscEndpointInfo{GcpPscEndpointInfo: *endpointInfoGcpPscEndpointInfoConverted} + } + return &Endpoint{ + Name: w.Name, + EndpointId: w.EndpointId, + AccountId: w.AccountId, + DisplayName: w.DisplayName, + UseCase: w.UseCase, + Region: w.Region, + State: w.State, + CreateTime: w.CreateTime, + EndpointInfo: endpointInfoSelection, + }, nil +} + +type gcpEndpointWire struct { + PscEndpointUri *string `json:"psc_endpoint_uri,omitempty"` + ServiceAttachment *string `json:"service_attachment,omitempty"` + GoogleApiEndpoints *googleApiEndpointsWire `json:"google_api_endpoints,omitempty"` + AllVpcScServices *bool `json:"all_vpc_sc_services,omitempty"` +} + +func gcpEndpointToWire(v *GcpEndpoint) (*gcpEndpointWire, error) { + if v == nil { + return nil, nil + } + var targetServicesServiceAttachmentWire *string + var targetServicesGoogleApiEndpointsWire *googleApiEndpointsWire + var targetServicesAllVpcScServicesWire *bool + switch value := v.TargetServices.(type) { + case nil: + case *GcpEndpoint_TargetServices_ServiceAttachment: + if value != nil { + targetServicesServiceAttachmentWire = new(value.ServiceAttachment) + } + case *GcpEndpoint_TargetServices_GoogleApiEndpoints: + if value != nil { + targetServicesGoogleApiEndpointsConverted, err := googleApiEndpointsToWire(&value.GoogleApiEndpoints) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GcpEndpoint.TargetServices.GoogleApiEndpoints", err) + } + targetServicesGoogleApiEndpointsWire = targetServicesGoogleApiEndpointsConverted + } + case *GcpEndpoint_TargetServices_AllVpcScServices: + if value != nil { + targetServicesAllVpcScServicesWire = new(value.AllVpcScServices) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "GcpEndpoint.TargetServices", value) + } + return &gcpEndpointWire{ + PscEndpointUri: v.PscEndpointUri, + ServiceAttachment: targetServicesServiceAttachmentWire, + GoogleApiEndpoints: targetServicesGoogleApiEndpointsWire, + AllVpcScServices: targetServicesAllVpcScServicesWire, + }, nil +} + +func gcpEndpointFromWire(w *gcpEndpointWire) (*GcpEndpoint, error) { + if w == nil { + return nil, nil + } + targetServicesMembers := 0 + if w.ServiceAttachment != nil { + targetServicesMembers++ + } + if w.GoogleApiEndpoints != nil { + targetServicesMembers++ + } + if w.AllVpcScServices != nil { + targetServicesMembers++ + } + if targetServicesMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "GcpEndpoint.TargetServices") + } + var targetServicesSelection isGcpEndpoint_TargetServices + switch { + case w.ServiceAttachment != nil: + targetServicesSelection = &GcpEndpoint_TargetServices_ServiceAttachment{ServiceAttachment: *w.ServiceAttachment} + case w.GoogleApiEndpoints != nil: + targetServicesGoogleApiEndpointsConverted, err := googleApiEndpointsFromWire(w.GoogleApiEndpoints) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GcpEndpoint.TargetServices.GoogleApiEndpoints", err) + } + targetServicesSelection = &GcpEndpoint_TargetServices_GoogleApiEndpoints{GoogleApiEndpoints: *targetServicesGoogleApiEndpointsConverted} + case w.AllVpcScServices != nil: + targetServicesSelection = &GcpEndpoint_TargetServices_AllVpcScServices{AllVpcScServices: *w.AllVpcScServices} + } + return &GcpEndpoint{ + PscEndpointUri: w.PscEndpointUri, + TargetServices: targetServicesSelection, + }, nil +} + +type gcpNetworkInfoWire struct { + NetworkProjectId *string `json:"network_project_id,omitempty"` + VpcId *string `json:"vpc_id,omitempty"` + SubnetId *string `json:"subnet_id,omitempty"` + SubnetRegion *string `json:"subnet_region,omitempty"` + PodIpRangeName *string `json:"pod_ip_range_name,omitempty"` + ServiceIpRangeName *string `json:"service_ip_range_name,omitempty"` +} + +func gcpNetworkInfoToWire(v *GcpNetworkInfo) (*gcpNetworkInfoWire, error) { + if v == nil { + return nil, nil + } + return &gcpNetworkInfoWire{ + NetworkProjectId: v.NetworkProjectId, + VpcId: v.VpcId, + SubnetId: v.SubnetId, + SubnetRegion: v.SubnetRegion, + PodIpRangeName: v.PodIpRangeName, + ServiceIpRangeName: v.ServiceIpRangeName, + }, nil +} + +func gcpNetworkInfoFromWire(w *gcpNetworkInfoWire) (*GcpNetworkInfo, error) { + if w == nil { + return nil, nil + } + return &GcpNetworkInfo{ + NetworkProjectId: w.NetworkProjectId, + VpcId: w.VpcId, + SubnetId: w.SubnetId, + SubnetRegion: w.SubnetRegion, + PodIpRangeName: w.PodIpRangeName, + ServiceIpRangeName: w.ServiceIpRangeName, + }, nil +} + +type gcpPscEndpointInfoWire struct { + PscConnectionId *string `json:"psc_connection_id,omitempty"` + ProjectId *string `json:"project_id,omitempty"` + PscEndpoint *string `json:"psc_endpoint,omitempty"` + EndpointRegion *string `json:"endpoint_region,omitempty"` + ServiceAttachmentId *string `json:"service_attachment_id,omitempty"` +} + +func gcpPscEndpointInfoToWire(v *GcpPscEndpointInfo) (*gcpPscEndpointInfoWire, error) { + if v == nil { + return nil, nil + } + return &gcpPscEndpointInfoWire{ + PscConnectionId: v.PscConnectionId, + ProjectId: v.ProjectId, + PscEndpoint: v.PscEndpoint, + EndpointRegion: v.EndpointRegion, + ServiceAttachmentId: v.ServiceAttachmentId, + }, nil +} + +func gcpPscEndpointInfoFromWire(w *gcpPscEndpointInfoWire) (*GcpPscEndpointInfo, error) { + if w == nil { + return nil, nil + } + return &GcpPscEndpointInfo{ + PscConnectionId: w.PscConnectionId, + ProjectId: w.ProjectId, + PscEndpoint: w.PscEndpoint, + EndpointRegion: w.EndpointRegion, + ServiceAttachmentId: w.ServiceAttachmentId, + }, nil +} + +type gcpVpcEndpointInfoWire struct { + PscConnectionId *string `json:"psc_connection_id,omitempty"` + ProjectId *string `json:"project_id,omitempty"` + PscEndpointName *string `json:"psc_endpoint_name,omitempty"` + EndpointRegion *string `json:"endpoint_region,omitempty"` + ServiceAttachmentId *string `json:"service_attachment_id,omitempty"` +} + +func gcpVpcEndpointInfoToWire(v *GcpVpcEndpointInfo) (*gcpVpcEndpointInfoWire, error) { + if v == nil { + return nil, nil + } + return &gcpVpcEndpointInfoWire{ + PscConnectionId: v.PscConnectionId, + ProjectId: v.ProjectId, + PscEndpointName: v.PscEndpointName, + EndpointRegion: v.EndpointRegion, + ServiceAttachmentId: v.ServiceAttachmentId, + }, nil +} + +func gcpVpcEndpointInfoFromWire(w *gcpVpcEndpointInfoWire) (*GcpVpcEndpointInfo, error) { + if w == nil { + return nil, nil + } + return &GcpVpcEndpointInfo{ + PscConnectionId: w.PscConnectionId, + ProjectId: w.ProjectId, + PscEndpointName: w.PscEndpointName, + EndpointRegion: w.EndpointRegion, + ServiceAttachmentId: w.ServiceAttachmentId, + }, nil +} + +type getAccountIpAccessListResponseWire struct { + IpAccessList *accountIpAccessListWire `json:"ip_access_list,omitempty"` +} + +func getAccountIpAccessListResponseFromWire(w *getAccountIpAccessListResponseWire) (*GetAccountIpAccessListResponse, error) { + if w == nil { + return nil, nil + } + ipAccessListPublicValue, err := accountIpAccessListFromWire(w.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetAccountIpAccessListResponse.IpAccessList", err) + } + return &GetAccountIpAccessListResponse{ + IpAccessList: ipAccessListPublicValue, + }, nil +} + +type getIpAccessListResponseWire struct { + IpAccessList *ipAccessListWire `json:"ip_access_list,omitempty"` +} + +func getIpAccessListResponseFromWire(w *getIpAccessListResponseWire) (*GetIpAccessListResponse, error) { + if w == nil { + return nil, nil + } + ipAccessListPublicValue, err := ipAccessListFromWire(w.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetIpAccessListResponse.IpAccessList", err) + } + return &GetIpAccessListResponse{ + IpAccessList: ipAccessListPublicValue, + }, nil +} + +type googleApiEndpointsWire struct { + Endpoints []string `json:"endpoints,omitempty"` +} + +func googleApiEndpointsToWire(v *GoogleApiEndpoints) (*googleApiEndpointsWire, error) { + if v == nil { + return nil, nil + } + return &googleApiEndpointsWire{ + Endpoints: v.Endpoints, + }, nil +} + +func googleApiEndpointsFromWire(w *googleApiEndpointsWire) (*GoogleApiEndpoints, error) { + if w == nil { + return nil, nil + } + return &GoogleApiEndpoints{ + Endpoints: w.Endpoints, + }, nil +} + +type ingressNetworkPolicyWire struct { + PublicAccess *ingressNetworkPolicy_PublicAccessWire `json:"public_access,omitempty"` + PrivateAccess *ingressNetworkPolicy_PrivateAccessWire `json:"private_access,omitempty"` + CrossWorkspaceAccess *ingressNetworkPolicy_CrossWorkspaceAccessWire `json:"cross_workspace_access,omitempty"` +} + +func ingressNetworkPolicyToWire(v *IngressNetworkPolicy) (*ingressNetworkPolicyWire, error) { + if v == nil { + return nil, nil + } + publicAccessWireValue, err := ingressNetworkPolicy_PublicAccessToWire(v.PublicAccess) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy.PublicAccess", err) + } + privateAccessWireValue, err := ingressNetworkPolicy_PrivateAccessToWire(v.PrivateAccess) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy.PrivateAccess", err) + } + crossWorkspaceAccessWireValue, err := ingressNetworkPolicy_CrossWorkspaceAccessToWire(v.CrossWorkspaceAccess) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy.CrossWorkspaceAccess", err) + } + return &ingressNetworkPolicyWire{ + PublicAccess: publicAccessWireValue, + PrivateAccess: privateAccessWireValue, + CrossWorkspaceAccess: crossWorkspaceAccessWireValue, + }, nil +} + +func ingressNetworkPolicyFromWire(w *ingressNetworkPolicyWire) (*IngressNetworkPolicy, error) { + if w == nil { + return nil, nil + } + publicAccessPublicValue, err := ingressNetworkPolicy_PublicAccessFromWire(w.PublicAccess) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy.PublicAccess", err) + } + privateAccessPublicValue, err := ingressNetworkPolicy_PrivateAccessFromWire(w.PrivateAccess) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy.PrivateAccess", err) + } + crossWorkspaceAccessPublicValue, err := ingressNetworkPolicy_CrossWorkspaceAccessFromWire(w.CrossWorkspaceAccess) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy.CrossWorkspaceAccess", err) + } + return &IngressNetworkPolicy{ + PublicAccess: publicAccessPublicValue, + PrivateAccess: privateAccessPublicValue, + CrossWorkspaceAccess: crossWorkspaceAccessPublicValue, + }, nil +} + +type ingressNetworkPolicy_AccountApiDestinationWire struct { + Scopes []string `json:"scopes,omitempty"` + ScopeQualifier IngressNetworkPolicy_ApiScopeQualifier `json:"scope_qualifier,omitempty"` +} + +func ingressNetworkPolicy_AccountApiDestinationToWire(v *IngressNetworkPolicy_AccountApiDestination) (*ingressNetworkPolicy_AccountApiDestinationWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_AccountApiDestinationWire{ + Scopes: v.Scopes, + ScopeQualifier: v.ScopeQualifier, + }, nil +} + +func ingressNetworkPolicy_AccountApiDestinationFromWire(w *ingressNetworkPolicy_AccountApiDestinationWire) (*IngressNetworkPolicy_AccountApiDestination, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_AccountApiDestination{ + Scopes: w.Scopes, + ScopeQualifier: w.ScopeQualifier, + }, nil +} + +type ingressNetworkPolicy_AccountDatabricksOneDestinationWire struct { + AllDestinations *bool `json:"all_destinations,omitempty"` +} + +func ingressNetworkPolicy_AccountDatabricksOneDestinationToWire(v *IngressNetworkPolicy_AccountDatabricksOneDestination) (*ingressNetworkPolicy_AccountDatabricksOneDestinationWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_AccountDatabricksOneDestinationWire{ + AllDestinations: v.AllDestinations, + }, nil +} + +func ingressNetworkPolicy_AccountDatabricksOneDestinationFromWire(w *ingressNetworkPolicy_AccountDatabricksOneDestinationWire) (*IngressNetworkPolicy_AccountDatabricksOneDestination, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_AccountDatabricksOneDestination{ + AllDestinations: w.AllDestinations, + }, nil +} + +type ingressNetworkPolicy_AccountUiDestinationWire struct { + AllDestinations *bool `json:"all_destinations,omitempty"` +} + +func ingressNetworkPolicy_AccountUiDestinationToWire(v *IngressNetworkPolicy_AccountUiDestination) (*ingressNetworkPolicy_AccountUiDestinationWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_AccountUiDestinationWire{ + AllDestinations: v.AllDestinations, + }, nil +} + +func ingressNetworkPolicy_AccountUiDestinationFromWire(w *ingressNetworkPolicy_AccountUiDestinationWire) (*IngressNetworkPolicy_AccountUiDestination, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_AccountUiDestination{ + AllDestinations: w.AllDestinations, + }, nil +} + +type ingressNetworkPolicy_AppsRuntimeDestinationWire struct { + AllDestinations *bool `json:"all_destinations,omitempty"` +} + +func ingressNetworkPolicy_AppsRuntimeDestinationToWire(v *IngressNetworkPolicy_AppsRuntimeDestination) (*ingressNetworkPolicy_AppsRuntimeDestinationWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_AppsRuntimeDestinationWire{ + AllDestinations: v.AllDestinations, + }, nil +} + +func ingressNetworkPolicy_AppsRuntimeDestinationFromWire(w *ingressNetworkPolicy_AppsRuntimeDestinationWire) (*IngressNetworkPolicy_AppsRuntimeDestination, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_AppsRuntimeDestination{ + AllDestinations: w.AllDestinations, + }, nil +} + +type ingressNetworkPolicy_AuthenticationWire struct { + IdentityType IngressNetworkPolicy_Authentication_IdentityType `json:"identity_type,omitempty"` + Identities []ingressNetworkPolicy_AuthenticationIdentityWire `json:"identities,omitempty"` +} + +func ingressNetworkPolicy_AuthenticationToWire(v *IngressNetworkPolicy_Authentication) (*ingressNetworkPolicy_AuthenticationWire, error) { + if v == nil { + return nil, nil + } + identitiesWireValue, err := convertSlice(v.Identities, ingressNetworkPolicy_AuthenticationIdentityToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_Authentication.Identities", err) + } + return &ingressNetworkPolicy_AuthenticationWire{ + IdentityType: v.IdentityType, + Identities: identitiesWireValue, + }, nil +} + +func ingressNetworkPolicy_AuthenticationFromWire(w *ingressNetworkPolicy_AuthenticationWire) (*IngressNetworkPolicy_Authentication, error) { + if w == nil { + return nil, nil + } + identitiesPublicValue, err := convertSlice(w.Identities, ingressNetworkPolicy_AuthenticationIdentityFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_Authentication.Identities", err) + } + return &IngressNetworkPolicy_Authentication{ + IdentityType: w.IdentityType, + Identities: identitiesPublicValue, + }, nil +} + +type ingressNetworkPolicy_AuthenticationIdentityWire struct { + PrincipalType IngressNetworkPolicy_AuthenticationIdentity_PrincipalType `json:"principal_type,omitempty"` + PrincipalId *int64 `json:"principal_id,omitempty"` +} + +func ingressNetworkPolicy_AuthenticationIdentityToWire(v *IngressNetworkPolicy_AuthenticationIdentity) (*ingressNetworkPolicy_AuthenticationIdentityWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_AuthenticationIdentityWire{ + PrincipalType: v.PrincipalType, + PrincipalId: v.PrincipalId, + }, nil +} + +func ingressNetworkPolicy_AuthenticationIdentityFromWire(w *ingressNetworkPolicy_AuthenticationIdentityWire) (*IngressNetworkPolicy_AuthenticationIdentity, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_AuthenticationIdentity{ + PrincipalType: w.PrincipalType, + PrincipalId: w.PrincipalId, + }, nil +} + +type ingressNetworkPolicy_CrossWorkspaceAccessWire struct { + RestrictionMode IngressNetworkPolicy_CrossWorkspaceAccess_RestrictionMode `json:"restriction_mode,omitempty"` + DenyRules []ingressNetworkPolicy_CrossWorkspaceIngressRuleWire `json:"deny_rules,omitempty"` + AllowRules []ingressNetworkPolicy_CrossWorkspaceIngressRuleWire `json:"allow_rules,omitempty"` +} + +func ingressNetworkPolicy_CrossWorkspaceAccessToWire(v *IngressNetworkPolicy_CrossWorkspaceAccess) (*ingressNetworkPolicy_CrossWorkspaceAccessWire, error) { + if v == nil { + return nil, nil + } + denyRulesWireValue, err := convertSlice(v.DenyRules, ingressNetworkPolicy_CrossWorkspaceIngressRuleToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceAccess.DenyRules", err) + } + allowRulesWireValue, err := convertSlice(v.AllowRules, ingressNetworkPolicy_CrossWorkspaceIngressRuleToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceAccess.AllowRules", err) + } + return &ingressNetworkPolicy_CrossWorkspaceAccessWire{ + RestrictionMode: v.RestrictionMode, + DenyRules: denyRulesWireValue, + AllowRules: allowRulesWireValue, + }, nil +} + +func ingressNetworkPolicy_CrossWorkspaceAccessFromWire(w *ingressNetworkPolicy_CrossWorkspaceAccessWire) (*IngressNetworkPolicy_CrossWorkspaceAccess, error) { + if w == nil { + return nil, nil + } + denyRulesPublicValue, err := convertSlice(w.DenyRules, ingressNetworkPolicy_CrossWorkspaceIngressRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceAccess.DenyRules", err) + } + allowRulesPublicValue, err := convertSlice(w.AllowRules, ingressNetworkPolicy_CrossWorkspaceIngressRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceAccess.AllowRules", err) + } + return &IngressNetworkPolicy_CrossWorkspaceAccess{ + RestrictionMode: w.RestrictionMode, + DenyRules: denyRulesPublicValue, + AllowRules: allowRulesPublicValue, + }, nil +} + +type ingressNetworkPolicy_CrossWorkspaceIngressRuleWire struct { + Origin *ingressNetworkPolicy_CrossWorkspaceRequestOriginWire `json:"origin,omitempty"` + Destination *ingressNetworkPolicy_RequestDestinationWire `json:"destination,omitempty"` + Authentication *ingressNetworkPolicy_AuthenticationWire `json:"authentication,omitempty"` + Label *string `json:"label,omitempty"` +} + +func ingressNetworkPolicy_CrossWorkspaceIngressRuleToWire(v *IngressNetworkPolicy_CrossWorkspaceIngressRule) (*ingressNetworkPolicy_CrossWorkspaceIngressRuleWire, error) { + if v == nil { + return nil, nil + } + originWireValue, err := ingressNetworkPolicy_CrossWorkspaceRequestOriginToWire(v.Origin) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceIngressRule.Origin", err) + } + destinationWireValue, err := ingressNetworkPolicy_RequestDestinationToWire(v.Destination) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceIngressRule.Destination", err) + } + authenticationWireValue, err := ingressNetworkPolicy_AuthenticationToWire(v.Authentication) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceIngressRule.Authentication", err) + } + return &ingressNetworkPolicy_CrossWorkspaceIngressRuleWire{ + Origin: originWireValue, + Destination: destinationWireValue, + Authentication: authenticationWireValue, + Label: v.Label, + }, nil +} + +func ingressNetworkPolicy_CrossWorkspaceIngressRuleFromWire(w *ingressNetworkPolicy_CrossWorkspaceIngressRuleWire) (*IngressNetworkPolicy_CrossWorkspaceIngressRule, error) { + if w == nil { + return nil, nil + } + originPublicValue, err := ingressNetworkPolicy_CrossWorkspaceRequestOriginFromWire(w.Origin) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceIngressRule.Origin", err) + } + destinationPublicValue, err := ingressNetworkPolicy_RequestDestinationFromWire(w.Destination) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceIngressRule.Destination", err) + } + authenticationPublicValue, err := ingressNetworkPolicy_AuthenticationFromWire(w.Authentication) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceIngressRule.Authentication", err) + } + return &IngressNetworkPolicy_CrossWorkspaceIngressRule{ + Origin: originPublicValue, + Destination: destinationPublicValue, + Authentication: authenticationPublicValue, + Label: w.Label, + }, nil +} + +type ingressNetworkPolicy_CrossWorkspaceRequestOriginWire struct { + AllSourceWorkspaces *bool `json:"all_source_workspaces,omitempty"` + SelectedWorkspaces *ingressNetworkPolicy_WorkspaceIdListWire `json:"selected_workspaces,omitempty"` +} + +func ingressNetworkPolicy_CrossWorkspaceRequestOriginToWire(v *IngressNetworkPolicy_CrossWorkspaceRequestOrigin) (*ingressNetworkPolicy_CrossWorkspaceRequestOriginWire, error) { + if v == nil { + return nil, nil + } + var sourceAllSourceWorkspacesWire *bool + var sourceSelectedWorkspacesWire *ingressNetworkPolicy_WorkspaceIdListWire + switch value := v.Source.(type) { + case nil: + case *IngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source_AllSourceWorkspaces: + if value != nil { + sourceAllSourceWorkspacesWire = new(value.AllSourceWorkspaces) + } + case *IngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source_SelectedWorkspaces: + if value != nil { + sourceSelectedWorkspacesConverted, err := ingressNetworkPolicy_WorkspaceIdListToWire(&value.SelectedWorkspaces) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceRequestOrigin.Source.SelectedWorkspaces", err) + } + sourceSelectedWorkspacesWire = sourceSelectedWorkspacesConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "IngressNetworkPolicy_CrossWorkspaceRequestOrigin.Source", value) + } + return &ingressNetworkPolicy_CrossWorkspaceRequestOriginWire{ + AllSourceWorkspaces: sourceAllSourceWorkspacesWire, + SelectedWorkspaces: sourceSelectedWorkspacesWire, + }, nil +} + +func ingressNetworkPolicy_CrossWorkspaceRequestOriginFromWire(w *ingressNetworkPolicy_CrossWorkspaceRequestOriginWire) (*IngressNetworkPolicy_CrossWorkspaceRequestOrigin, error) { + if w == nil { + return nil, nil + } + sourceMembers := 0 + if w.AllSourceWorkspaces != nil { + sourceMembers++ + } + if w.SelectedWorkspaces != nil { + sourceMembers++ + } + if sourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "IngressNetworkPolicy_CrossWorkspaceRequestOrigin.Source") + } + var sourceSelection isIngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source + switch { + case w.AllSourceWorkspaces != nil: + sourceSelection = &IngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source_AllSourceWorkspaces{AllSourceWorkspaces: *w.AllSourceWorkspaces} + case w.SelectedWorkspaces != nil: + sourceSelectedWorkspacesConverted, err := ingressNetworkPolicy_WorkspaceIdListFromWire(w.SelectedWorkspaces) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_CrossWorkspaceRequestOrigin.Source.SelectedWorkspaces", err) + } + sourceSelection = &IngressNetworkPolicy_CrossWorkspaceRequestOrigin_Source_SelectedWorkspaces{SelectedWorkspaces: *sourceSelectedWorkspacesConverted} + } + return &IngressNetworkPolicy_CrossWorkspaceRequestOrigin{ + Source: sourceSelection, + }, nil +} + +type ingressNetworkPolicy_EndpointsWire struct { + EndpointIds []string `json:"endpoint_ids,omitempty"` +} + +func ingressNetworkPolicy_EndpointsToWire(v *IngressNetworkPolicy_Endpoints) (*ingressNetworkPolicy_EndpointsWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_EndpointsWire{ + EndpointIds: v.EndpointIds, + }, nil +} + +func ingressNetworkPolicy_EndpointsFromWire(w *ingressNetworkPolicy_EndpointsWire) (*IngressNetworkPolicy_Endpoints, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_Endpoints{ + EndpointIds: w.EndpointIds, + }, nil +} + +type ingressNetworkPolicy_IpRangesWire struct { + IpRanges []string `json:"ip_ranges,omitempty"` +} + +func ingressNetworkPolicy_IpRangesToWire(v *IngressNetworkPolicy_IpRanges) (*ingressNetworkPolicy_IpRangesWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_IpRangesWire{ + IpRanges: v.IpRanges, + }, nil +} + +func ingressNetworkPolicy_IpRangesFromWire(w *ingressNetworkPolicy_IpRangesWire) (*IngressNetworkPolicy_IpRanges, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_IpRanges{ + IpRanges: w.IpRanges, + }, nil +} + +type ingressNetworkPolicy_LakebaseRuntimeDestinationWire struct { + AllDestinations *bool `json:"all_destinations,omitempty"` +} + +func ingressNetworkPolicy_LakebaseRuntimeDestinationToWire(v *IngressNetworkPolicy_LakebaseRuntimeDestination) (*ingressNetworkPolicy_LakebaseRuntimeDestinationWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_LakebaseRuntimeDestinationWire{ + AllDestinations: v.AllDestinations, + }, nil +} + +func ingressNetworkPolicy_LakebaseRuntimeDestinationFromWire(w *ingressNetworkPolicy_LakebaseRuntimeDestinationWire) (*IngressNetworkPolicy_LakebaseRuntimeDestination, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_LakebaseRuntimeDestination{ + AllDestinations: w.AllDestinations, + }, nil +} + +type ingressNetworkPolicy_PrivateAccessWire struct { + RestrictionMode IngressNetworkPolicy_PrivateAccess_RestrictionMode `json:"restriction_mode,omitempty"` + DenyRules []ingressNetworkPolicy_PrivateIngressRuleWire `json:"deny_rules,omitempty"` + AllowRules []ingressNetworkPolicy_PrivateIngressRuleWire `json:"allow_rules,omitempty"` +} + +func ingressNetworkPolicy_PrivateAccessToWire(v *IngressNetworkPolicy_PrivateAccess) (*ingressNetworkPolicy_PrivateAccessWire, error) { + if v == nil { + return nil, nil + } + denyRulesWireValue, err := convertSlice(v.DenyRules, ingressNetworkPolicy_PrivateIngressRuleToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateAccess.DenyRules", err) + } + allowRulesWireValue, err := convertSlice(v.AllowRules, ingressNetworkPolicy_PrivateIngressRuleToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateAccess.AllowRules", err) + } + return &ingressNetworkPolicy_PrivateAccessWire{ + RestrictionMode: v.RestrictionMode, + DenyRules: denyRulesWireValue, + AllowRules: allowRulesWireValue, + }, nil +} + +func ingressNetworkPolicy_PrivateAccessFromWire(w *ingressNetworkPolicy_PrivateAccessWire) (*IngressNetworkPolicy_PrivateAccess, error) { + if w == nil { + return nil, nil + } + denyRulesPublicValue, err := convertSlice(w.DenyRules, ingressNetworkPolicy_PrivateIngressRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateAccess.DenyRules", err) + } + allowRulesPublicValue, err := convertSlice(w.AllowRules, ingressNetworkPolicy_PrivateIngressRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateAccess.AllowRules", err) + } + return &IngressNetworkPolicy_PrivateAccess{ + RestrictionMode: w.RestrictionMode, + DenyRules: denyRulesPublicValue, + AllowRules: allowRulesPublicValue, + }, nil +} + +type ingressNetworkPolicy_PrivateIngressRuleWire struct { + Origin *ingressNetworkPolicy_PrivateRequestOriginWire `json:"origin,omitempty"` + Destination *ingressNetworkPolicy_RequestDestinationWire `json:"destination,omitempty"` + Authentication *ingressNetworkPolicy_AuthenticationWire `json:"authentication,omitempty"` + Label *string `json:"label,omitempty"` +} + +func ingressNetworkPolicy_PrivateIngressRuleToWire(v *IngressNetworkPolicy_PrivateIngressRule) (*ingressNetworkPolicy_PrivateIngressRuleWire, error) { + if v == nil { + return nil, nil + } + originWireValue, err := ingressNetworkPolicy_PrivateRequestOriginToWire(v.Origin) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateIngressRule.Origin", err) + } + destinationWireValue, err := ingressNetworkPolicy_RequestDestinationToWire(v.Destination) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateIngressRule.Destination", err) + } + authenticationWireValue, err := ingressNetworkPolicy_AuthenticationToWire(v.Authentication) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateIngressRule.Authentication", err) + } + return &ingressNetworkPolicy_PrivateIngressRuleWire{ + Origin: originWireValue, + Destination: destinationWireValue, + Authentication: authenticationWireValue, + Label: v.Label, + }, nil +} + +func ingressNetworkPolicy_PrivateIngressRuleFromWire(w *ingressNetworkPolicy_PrivateIngressRuleWire) (*IngressNetworkPolicy_PrivateIngressRule, error) { + if w == nil { + return nil, nil + } + originPublicValue, err := ingressNetworkPolicy_PrivateRequestOriginFromWire(w.Origin) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateIngressRule.Origin", err) + } + destinationPublicValue, err := ingressNetworkPolicy_RequestDestinationFromWire(w.Destination) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateIngressRule.Destination", err) + } + authenticationPublicValue, err := ingressNetworkPolicy_AuthenticationFromWire(w.Authentication) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateIngressRule.Authentication", err) + } + return &IngressNetworkPolicy_PrivateIngressRule{ + Origin: originPublicValue, + Destination: destinationPublicValue, + Authentication: authenticationPublicValue, + Label: w.Label, + }, nil +} + +type ingressNetworkPolicy_PrivateRequestOriginWire struct { + Endpoints *ingressNetworkPolicy_EndpointsWire `json:"endpoints,omitempty"` + AllRegisteredEndpoints *bool `json:"all_registered_endpoints,omitempty"` + AzureWorkspacePrivateLink *bool `json:"azure_workspace_private_link,omitempty"` + AllPrivateAccess *bool `json:"all_private_access,omitempty"` +} + +func ingressNetworkPolicy_PrivateRequestOriginToWire(v *IngressNetworkPolicy_PrivateRequestOrigin) (*ingressNetworkPolicy_PrivateRequestOriginWire, error) { + if v == nil { + return nil, nil + } + var sourceEndpointsWire *ingressNetworkPolicy_EndpointsWire + var sourceAllRegisteredEndpointsWire *bool + var sourceAzureWorkspacePrivateLinkWire *bool + var sourceAllPrivateAccessWire *bool + switch value := v.Source.(type) { + case nil: + case *IngressNetworkPolicy_PrivateRequestOrigin_Source_Endpoints: + if value != nil { + sourceEndpointsConverted, err := ingressNetworkPolicy_EndpointsToWire(&value.Endpoints) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateRequestOrigin.Source.Endpoints", err) + } + sourceEndpointsWire = sourceEndpointsConverted + } + case *IngressNetworkPolicy_PrivateRequestOrigin_Source_AllRegisteredEndpoints: + if value != nil { + sourceAllRegisteredEndpointsWire = new(value.AllRegisteredEndpoints) + } + case *IngressNetworkPolicy_PrivateRequestOrigin_Source_AzureWorkspacePrivateLink: + if value != nil { + sourceAzureWorkspacePrivateLinkWire = new(value.AzureWorkspacePrivateLink) + } + case *IngressNetworkPolicy_PrivateRequestOrigin_Source_AllPrivateAccess: + if value != nil { + sourceAllPrivateAccessWire = new(value.AllPrivateAccess) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "IngressNetworkPolicy_PrivateRequestOrigin.Source", value) + } + return &ingressNetworkPolicy_PrivateRequestOriginWire{ + Endpoints: sourceEndpointsWire, + AllRegisteredEndpoints: sourceAllRegisteredEndpointsWire, + AzureWorkspacePrivateLink: sourceAzureWorkspacePrivateLinkWire, + AllPrivateAccess: sourceAllPrivateAccessWire, + }, nil +} + +func ingressNetworkPolicy_PrivateRequestOriginFromWire(w *ingressNetworkPolicy_PrivateRequestOriginWire) (*IngressNetworkPolicy_PrivateRequestOrigin, error) { + if w == nil { + return nil, nil + } + sourceMembers := 0 + if w.Endpoints != nil { + sourceMembers++ + } + if w.AllRegisteredEndpoints != nil { + sourceMembers++ + } + if w.AzureWorkspacePrivateLink != nil { + sourceMembers++ + } + if w.AllPrivateAccess != nil { + sourceMembers++ + } + if sourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "IngressNetworkPolicy_PrivateRequestOrigin.Source") + } + var sourceSelection isIngressNetworkPolicy_PrivateRequestOrigin_Source + switch { + case w.Endpoints != nil: + sourceEndpointsConverted, err := ingressNetworkPolicy_EndpointsFromWire(w.Endpoints) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PrivateRequestOrigin.Source.Endpoints", err) + } + sourceSelection = &IngressNetworkPolicy_PrivateRequestOrigin_Source_Endpoints{Endpoints: *sourceEndpointsConverted} + case w.AllRegisteredEndpoints != nil: + sourceSelection = &IngressNetworkPolicy_PrivateRequestOrigin_Source_AllRegisteredEndpoints{AllRegisteredEndpoints: *w.AllRegisteredEndpoints} + case w.AzureWorkspacePrivateLink != nil: + sourceSelection = &IngressNetworkPolicy_PrivateRequestOrigin_Source_AzureWorkspacePrivateLink{AzureWorkspacePrivateLink: *w.AzureWorkspacePrivateLink} + case w.AllPrivateAccess != nil: + sourceSelection = &IngressNetworkPolicy_PrivateRequestOrigin_Source_AllPrivateAccess{AllPrivateAccess: *w.AllPrivateAccess} + } + return &IngressNetworkPolicy_PrivateRequestOrigin{ + Source: sourceSelection, + }, nil +} + +type ingressNetworkPolicy_PublicAccessWire struct { + RestrictionMode IngressNetworkPolicy_PublicAccess_RestrictionMode `json:"restriction_mode,omitempty"` + DenyRules []ingressNetworkPolicy_PublicIngressRuleWire `json:"deny_rules,omitempty"` + AllowRules []ingressNetworkPolicy_PublicIngressRuleWire `json:"allow_rules,omitempty"` +} + +func ingressNetworkPolicy_PublicAccessToWire(v *IngressNetworkPolicy_PublicAccess) (*ingressNetworkPolicy_PublicAccessWire, error) { + if v == nil { + return nil, nil + } + denyRulesWireValue, err := convertSlice(v.DenyRules, ingressNetworkPolicy_PublicIngressRuleToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicAccess.DenyRules", err) + } + allowRulesWireValue, err := convertSlice(v.AllowRules, ingressNetworkPolicy_PublicIngressRuleToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicAccess.AllowRules", err) + } + return &ingressNetworkPolicy_PublicAccessWire{ + RestrictionMode: v.RestrictionMode, + DenyRules: denyRulesWireValue, + AllowRules: allowRulesWireValue, + }, nil +} + +func ingressNetworkPolicy_PublicAccessFromWire(w *ingressNetworkPolicy_PublicAccessWire) (*IngressNetworkPolicy_PublicAccess, error) { + if w == nil { + return nil, nil + } + denyRulesPublicValue, err := convertSlice(w.DenyRules, ingressNetworkPolicy_PublicIngressRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicAccess.DenyRules", err) + } + allowRulesPublicValue, err := convertSlice(w.AllowRules, ingressNetworkPolicy_PublicIngressRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicAccess.AllowRules", err) + } + return &IngressNetworkPolicy_PublicAccess{ + RestrictionMode: w.RestrictionMode, + DenyRules: denyRulesPublicValue, + AllowRules: allowRulesPublicValue, + }, nil +} + +type ingressNetworkPolicy_PublicIngressRuleWire struct { + Origin *ingressNetworkPolicy_PublicRequestOriginWire `json:"origin,omitempty"` + Destination *ingressNetworkPolicy_RequestDestinationWire `json:"destination,omitempty"` + Authentication *ingressNetworkPolicy_AuthenticationWire `json:"authentication,omitempty"` + Label *string `json:"label,omitempty"` +} + +func ingressNetworkPolicy_PublicIngressRuleToWire(v *IngressNetworkPolicy_PublicIngressRule) (*ingressNetworkPolicy_PublicIngressRuleWire, error) { + if v == nil { + return nil, nil + } + originWireValue, err := ingressNetworkPolicy_PublicRequestOriginToWire(v.Origin) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicIngressRule.Origin", err) + } + destinationWireValue, err := ingressNetworkPolicy_RequestDestinationToWire(v.Destination) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicIngressRule.Destination", err) + } + authenticationWireValue, err := ingressNetworkPolicy_AuthenticationToWire(v.Authentication) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicIngressRule.Authentication", err) + } + return &ingressNetworkPolicy_PublicIngressRuleWire{ + Origin: originWireValue, + Destination: destinationWireValue, + Authentication: authenticationWireValue, + Label: v.Label, + }, nil +} + +func ingressNetworkPolicy_PublicIngressRuleFromWire(w *ingressNetworkPolicy_PublicIngressRuleWire) (*IngressNetworkPolicy_PublicIngressRule, error) { + if w == nil { + return nil, nil + } + originPublicValue, err := ingressNetworkPolicy_PublicRequestOriginFromWire(w.Origin) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicIngressRule.Origin", err) + } + destinationPublicValue, err := ingressNetworkPolicy_RequestDestinationFromWire(w.Destination) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicIngressRule.Destination", err) + } + authenticationPublicValue, err := ingressNetworkPolicy_AuthenticationFromWire(w.Authentication) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicIngressRule.Authentication", err) + } + return &IngressNetworkPolicy_PublicIngressRule{ + Origin: originPublicValue, + Destination: destinationPublicValue, + Authentication: authenticationPublicValue, + Label: w.Label, + }, nil +} + +type ingressNetworkPolicy_PublicRequestOriginWire struct { + AllIpRanges *bool `json:"all_ip_ranges,omitempty"` + IncludedIpRanges *ingressNetworkPolicy_IpRangesWire `json:"included_ip_ranges,omitempty"` + ExcludedIpRanges *ingressNetworkPolicy_IpRangesWire `json:"excluded_ip_ranges,omitempty"` +} + +func ingressNetworkPolicy_PublicRequestOriginToWire(v *IngressNetworkPolicy_PublicRequestOrigin) (*ingressNetworkPolicy_PublicRequestOriginWire, error) { + if v == nil { + return nil, nil + } + var sourceAllIpRangesWire *bool + var sourceIncludedIpRangesWire *ingressNetworkPolicy_IpRangesWire + var sourceExcludedIpRangesWire *ingressNetworkPolicy_IpRangesWire + switch value := v.Source.(type) { + case nil: + case *IngressNetworkPolicy_PublicRequestOrigin_Source_AllIpRanges: + if value != nil { + sourceAllIpRangesWire = new(value.AllIpRanges) + } + case *IngressNetworkPolicy_PublicRequestOrigin_Source_IncludedIpRanges: + if value != nil { + sourceIncludedIpRangesConverted, err := ingressNetworkPolicy_IpRangesToWire(&value.IncludedIpRanges) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicRequestOrigin.Source.IncludedIpRanges", err) + } + sourceIncludedIpRangesWire = sourceIncludedIpRangesConverted + } + case *IngressNetworkPolicy_PublicRequestOrigin_Source_ExcludedIpRanges: + if value != nil { + sourceExcludedIpRangesConverted, err := ingressNetworkPolicy_IpRangesToWire(&value.ExcludedIpRanges) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicRequestOrigin.Source.ExcludedIpRanges", err) + } + sourceExcludedIpRangesWire = sourceExcludedIpRangesConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "IngressNetworkPolicy_PublicRequestOrigin.Source", value) + } + return &ingressNetworkPolicy_PublicRequestOriginWire{ + AllIpRanges: sourceAllIpRangesWire, + IncludedIpRanges: sourceIncludedIpRangesWire, + ExcludedIpRanges: sourceExcludedIpRangesWire, + }, nil +} + +func ingressNetworkPolicy_PublicRequestOriginFromWire(w *ingressNetworkPolicy_PublicRequestOriginWire) (*IngressNetworkPolicy_PublicRequestOrigin, error) { + if w == nil { + return nil, nil + } + sourceMembers := 0 + if w.AllIpRanges != nil { + sourceMembers++ + } + if w.IncludedIpRanges != nil { + sourceMembers++ + } + if w.ExcludedIpRanges != nil { + sourceMembers++ + } + if sourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "IngressNetworkPolicy_PublicRequestOrigin.Source") + } + var sourceSelection isIngressNetworkPolicy_PublicRequestOrigin_Source + switch { + case w.AllIpRanges != nil: + sourceSelection = &IngressNetworkPolicy_PublicRequestOrigin_Source_AllIpRanges{AllIpRanges: *w.AllIpRanges} + case w.IncludedIpRanges != nil: + sourceIncludedIpRangesConverted, err := ingressNetworkPolicy_IpRangesFromWire(w.IncludedIpRanges) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicRequestOrigin.Source.IncludedIpRanges", err) + } + sourceSelection = &IngressNetworkPolicy_PublicRequestOrigin_Source_IncludedIpRanges{IncludedIpRanges: *sourceIncludedIpRangesConverted} + case w.ExcludedIpRanges != nil: + sourceExcludedIpRangesConverted, err := ingressNetworkPolicy_IpRangesFromWire(w.ExcludedIpRanges) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_PublicRequestOrigin.Source.ExcludedIpRanges", err) + } + sourceSelection = &IngressNetworkPolicy_PublicRequestOrigin_Source_ExcludedIpRanges{ExcludedIpRanges: *sourceExcludedIpRangesConverted} + } + return &IngressNetworkPolicy_PublicRequestOrigin{ + Source: sourceSelection, + }, nil +} + +type ingressNetworkPolicy_RequestDestinationWire struct { + AllDestinations *bool `json:"all_destinations,omitempty"` + WorkspaceUi *ingressNetworkPolicy_WorkspaceUiDestinationWire `json:"workspace_ui,omitempty"` + WorkspaceApi *ingressNetworkPolicy_WorkspaceApiDestinationWire `json:"workspace_api,omitempty"` + AppsRuntime *ingressNetworkPolicy_AppsRuntimeDestinationWire `json:"apps_runtime,omitempty"` + LakebaseRuntime *ingressNetworkPolicy_LakebaseRuntimeDestinationWire `json:"lakebase_runtime,omitempty"` + AccountUi *ingressNetworkPolicy_AccountUiDestinationWire `json:"account_ui,omitempty"` + AccountApi *ingressNetworkPolicy_AccountApiDestinationWire `json:"account_api,omitempty"` + AccountDatabricksOne *ingressNetworkPolicy_AccountDatabricksOneDestinationWire `json:"account_databricks_one,omitempty"` +} + +func ingressNetworkPolicy_RequestDestinationToWire(v *IngressNetworkPolicy_RequestDestination) (*ingressNetworkPolicy_RequestDestinationWire, error) { + if v == nil { + return nil, nil + } + workspaceUiWireValue, err := ingressNetworkPolicy_WorkspaceUiDestinationToWire(v.WorkspaceUi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.WorkspaceUi", err) + } + workspaceApiWireValue, err := ingressNetworkPolicy_WorkspaceApiDestinationToWire(v.WorkspaceApi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.WorkspaceApi", err) + } + appsRuntimeWireValue, err := ingressNetworkPolicy_AppsRuntimeDestinationToWire(v.AppsRuntime) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.AppsRuntime", err) + } + lakebaseRuntimeWireValue, err := ingressNetworkPolicy_LakebaseRuntimeDestinationToWire(v.LakebaseRuntime) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.LakebaseRuntime", err) + } + accountUiWireValue, err := ingressNetworkPolicy_AccountUiDestinationToWire(v.AccountUi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.AccountUi", err) + } + accountApiWireValue, err := ingressNetworkPolicy_AccountApiDestinationToWire(v.AccountApi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.AccountApi", err) + } + accountDatabricksOneWireValue, err := ingressNetworkPolicy_AccountDatabricksOneDestinationToWire(v.AccountDatabricksOne) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.AccountDatabricksOne", err) + } + return &ingressNetworkPolicy_RequestDestinationWire{ + AllDestinations: v.AllDestinations, + WorkspaceUi: workspaceUiWireValue, + WorkspaceApi: workspaceApiWireValue, + AppsRuntime: appsRuntimeWireValue, + LakebaseRuntime: lakebaseRuntimeWireValue, + AccountUi: accountUiWireValue, + AccountApi: accountApiWireValue, + AccountDatabricksOne: accountDatabricksOneWireValue, + }, nil +} + +func ingressNetworkPolicy_RequestDestinationFromWire(w *ingressNetworkPolicy_RequestDestinationWire) (*IngressNetworkPolicy_RequestDestination, error) { + if w == nil { + return nil, nil + } + workspaceUiPublicValue, err := ingressNetworkPolicy_WorkspaceUiDestinationFromWire(w.WorkspaceUi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.WorkspaceUi", err) + } + workspaceApiPublicValue, err := ingressNetworkPolicy_WorkspaceApiDestinationFromWire(w.WorkspaceApi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.WorkspaceApi", err) + } + appsRuntimePublicValue, err := ingressNetworkPolicy_AppsRuntimeDestinationFromWire(w.AppsRuntime) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.AppsRuntime", err) + } + lakebaseRuntimePublicValue, err := ingressNetworkPolicy_LakebaseRuntimeDestinationFromWire(w.LakebaseRuntime) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.LakebaseRuntime", err) + } + accountUiPublicValue, err := ingressNetworkPolicy_AccountUiDestinationFromWire(w.AccountUi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.AccountUi", err) + } + accountApiPublicValue, err := ingressNetworkPolicy_AccountApiDestinationFromWire(w.AccountApi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.AccountApi", err) + } + accountDatabricksOnePublicValue, err := ingressNetworkPolicy_AccountDatabricksOneDestinationFromWire(w.AccountDatabricksOne) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngressNetworkPolicy_RequestDestination.AccountDatabricksOne", err) + } + return &IngressNetworkPolicy_RequestDestination{ + AllDestinations: w.AllDestinations, + WorkspaceUi: workspaceUiPublicValue, + WorkspaceApi: workspaceApiPublicValue, + AppsRuntime: appsRuntimePublicValue, + LakebaseRuntime: lakebaseRuntimePublicValue, + AccountUi: accountUiPublicValue, + AccountApi: accountApiPublicValue, + AccountDatabricksOne: accountDatabricksOnePublicValue, + }, nil +} + +type ingressNetworkPolicy_WorkspaceApiDestinationWire struct { + Scopes []string `json:"scopes,omitempty"` + ScopeQualifier IngressNetworkPolicy_ApiScopeQualifier `json:"scope_qualifier,omitempty"` +} + +func ingressNetworkPolicy_WorkspaceApiDestinationToWire(v *IngressNetworkPolicy_WorkspaceApiDestination) (*ingressNetworkPolicy_WorkspaceApiDestinationWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_WorkspaceApiDestinationWire{ + Scopes: v.Scopes, + ScopeQualifier: v.ScopeQualifier, + }, nil +} + +func ingressNetworkPolicy_WorkspaceApiDestinationFromWire(w *ingressNetworkPolicy_WorkspaceApiDestinationWire) (*IngressNetworkPolicy_WorkspaceApiDestination, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_WorkspaceApiDestination{ + Scopes: w.Scopes, + ScopeQualifier: w.ScopeQualifier, + }, nil +} + +type ingressNetworkPolicy_WorkspaceIdListWire struct { + WorkspaceIds []int64 `json:"workspace_ids,omitempty"` +} + +func ingressNetworkPolicy_WorkspaceIdListToWire(v *IngressNetworkPolicy_WorkspaceIdList) (*ingressNetworkPolicy_WorkspaceIdListWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_WorkspaceIdListWire{ + WorkspaceIds: v.WorkspaceIds, + }, nil +} + +func ingressNetworkPolicy_WorkspaceIdListFromWire(w *ingressNetworkPolicy_WorkspaceIdListWire) (*IngressNetworkPolicy_WorkspaceIdList, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_WorkspaceIdList{ + WorkspaceIds: w.WorkspaceIds, + }, nil +} + +type ingressNetworkPolicy_WorkspaceUiDestinationWire struct { + AllDestinations *bool `json:"all_destinations,omitempty"` +} + +func ingressNetworkPolicy_WorkspaceUiDestinationToWire(v *IngressNetworkPolicy_WorkspaceUiDestination) (*ingressNetworkPolicy_WorkspaceUiDestinationWire, error) { + if v == nil { + return nil, nil + } + return &ingressNetworkPolicy_WorkspaceUiDestinationWire{ + AllDestinations: v.AllDestinations, + }, nil +} + +func ingressNetworkPolicy_WorkspaceUiDestinationFromWire(w *ingressNetworkPolicy_WorkspaceUiDestinationWire) (*IngressNetworkPolicy_WorkspaceUiDestination, error) { + if w == nil { + return nil, nil + } + return &IngressNetworkPolicy_WorkspaceUiDestination{ + AllDestinations: w.AllDestinations, + }, nil +} + +type ipAccessListWire struct { + ListId *string `json:"list_id,omitempty"` + Label *string `json:"label,omitempty"` + IpAddresses []string `json:"ip_addresses,omitempty"` + AddressCount *int `json:"address_count,omitempty"` + ListType IpAccessListType `json:"list_type,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *int64 `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *int64 `json:"updated_by,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func ipAccessListFromWire(w *ipAccessListWire) (*IpAccessList, error) { + if w == nil { + return nil, nil + } + return &IpAccessList{ + ListId: w.ListId, + Label: w.Label, + IpAddresses: w.IpAddresses, + AddressCount: w.AddressCount, + ListType: w.ListType, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + Enabled: w.Enabled, + }, nil +} + +type listAccountIpAccessListsResponseWire struct { + IpAccessLists []accountIpAccessListWire `json:"ip_access_lists,omitempty"` +} + +func listAccountIpAccessListsResponseFromWire(w *listAccountIpAccessListsResponseWire) (*ListAccountIpAccessListsResponse, error) { + if w == nil { + return nil, nil + } + ipAccessListsPublicValue, err := convertSlice(w.IpAccessLists, accountIpAccessListFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAccountIpAccessListsResponse.IpAccessLists", err) + } + return &ListAccountIpAccessListsResponse{ + IpAccessLists: ipAccessListsPublicValue, + }, nil +} + +type listEndpointsRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listEndpointsRequestToWire(v *ListEndpointsRequest) (*listEndpointsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listEndpointsRequestWire{ + Parent: v.Parent, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listEndpointsResponseWire struct { + Items []endpointWire `json:"items,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listEndpointsResponseFromWire(w *listEndpointsResponseWire) (*ListEndpointsResponse, error) { + if w == nil { + return nil, nil + } + itemsPublicValue, err := convertSlice(w.Items, endpointFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListEndpointsResponse.Items", err) + } + return &ListEndpointsResponse{ + Items: itemsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listIpAccessListsResponseWire struct { + IpAccessLists []ipAccessListWire `json:"ip_access_lists,omitempty"` +} + +func listIpAccessListsResponseFromWire(w *listIpAccessListsResponseWire) (*ListIpAccessListsResponse, error) { + if w == nil { + return nil, nil + } + ipAccessListsPublicValue, err := convertSlice(w.IpAccessLists, ipAccessListFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListIpAccessListsResponse.IpAccessLists", err) + } + return &ListIpAccessListsResponse{ + IpAccessLists: ipAccessListsPublicValue, + }, nil +} + +type listNccPrivateEndpointRulesRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listNccPrivateEndpointRulesRequestToWire(v *ListNccPrivateEndpointRulesRequest) (*listNccPrivateEndpointRulesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listNccPrivateEndpointRulesRequestWire{ + AccountId: v.AccountId, + NetworkConnectivityConfigId: v.NetworkConnectivityConfigId, + PageToken: v.PageToken, + }, nil +} + +type listNccPrivateEndpointRulesResponseWire struct { + Items []nccPrivateEndpointRuleWire `json:"items,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listNccPrivateEndpointRulesResponseFromWire(w *listNccPrivateEndpointRulesResponseWire) (*ListNccPrivateEndpointRulesResponse, error) { + if w == nil { + return nil, nil + } + itemsPublicValue, err := convertSlice(w.Items, nccPrivateEndpointRuleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListNccPrivateEndpointRulesResponse.Items", err) + } + return &ListNccPrivateEndpointRulesResponse{ + Items: itemsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listNetworkConnectivityConfigsRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listNetworkConnectivityConfigsRequestToWire(v *ListNetworkConnectivityConfigsRequest) (*listNetworkConnectivityConfigsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listNetworkConnectivityConfigsRequestWire{ + AccountId: v.AccountId, + PageToken: v.PageToken, + }, nil +} + +type listNetworkConnectivityConfigsResponseWire struct { + Items []networkConnectivityConfigWire `json:"items,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listNetworkConnectivityConfigsResponseFromWire(w *listNetworkConnectivityConfigsResponseWire) (*ListNetworkConnectivityConfigsResponse, error) { + if w == nil { + return nil, nil + } + itemsPublicValue, err := convertSlice(w.Items, networkConnectivityConfigFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListNetworkConnectivityConfigsResponse.Items", err) + } + return &ListNetworkConnectivityConfigsResponse{ + Items: itemsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listNetworkPoliciesRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listNetworkPoliciesRequestToWire(v *ListNetworkPoliciesRequest) (*listNetworkPoliciesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listNetworkPoliciesRequestWire{ + AccountId: v.AccountId, + PageToken: v.PageToken, + }, nil +} + +type listNetworkPoliciesResponseWire struct { + Items []accountNetworkPolicyWire `json:"items,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listNetworkPoliciesResponseFromWire(w *listNetworkPoliciesResponseWire) (*ListNetworkPoliciesResponse, error) { + if w == nil { + return nil, nil + } + itemsPublicValue, err := convertSlice(w.Items, accountNetworkPolicyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListNetworkPoliciesResponse.Items", err) + } + return &ListNetworkPoliciesResponse{ + Items: itemsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type nccPrivateEndpointRuleWire struct { + RuleId *string `json:"rule_id,omitempty"` + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + ConnectionState NccPrivateEndpointRule_PrivateLinkConnectionState `json:"connection_state,omitempty"` + DomainNames []string `json:"domain_names,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + UpdatedTime *int64 `json:"updated_time,omitempty"` + Deactivated *bool `json:"deactivated,omitempty"` + DeactivatedAt *int64 `json:"deactivated_at,omitempty"` + ErrorMessage *string `json:"error_message,omitempty"` + ResourceId *string `json:"resource_id,omitempty"` + GroupId *string `json:"group_id,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + AccountId *string `json:"account_id,omitempty"` + EndpointService *string `json:"endpoint_service,omitempty"` + ResourceNames []string `json:"resource_names,omitempty"` + VpcEndpointId *string `json:"vpc_endpoint_id,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + GcpEndpoint *gcpEndpointWire `json:"gcp_endpoint,omitempty"` +} + +func nccPrivateEndpointRuleFromWire(w *nccPrivateEndpointRuleWire) (*NccPrivateEndpointRule, error) { + if w == nil { + return nil, nil + } + endpointMembers := 0 + if w.GcpEndpoint != nil { + endpointMembers++ + } + if endpointMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "NccPrivateEndpointRule.Endpoint") + } + var endpointSelection isNccPrivateEndpointRule_Endpoint + switch { + case w.GcpEndpoint != nil: + endpointGcpEndpointConverted, err := gcpEndpointFromWire(w.GcpEndpoint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NccPrivateEndpointRule.Endpoint.GcpEndpoint", err) + } + endpointSelection = &NccPrivateEndpointRule_Endpoint_GcpEndpoint{GcpEndpoint: *endpointGcpEndpointConverted} + } + return &NccPrivateEndpointRule{ + RuleId: w.RuleId, + NetworkConnectivityConfigId: w.NetworkConnectivityConfigId, + ConnectionState: w.ConnectionState, + DomainNames: w.DomainNames, + CreationTime: w.CreationTime, + UpdatedTime: w.UpdatedTime, + Deactivated: w.Deactivated, + DeactivatedAt: w.DeactivatedAt, + ErrorMessage: w.ErrorMessage, + ResourceId: w.ResourceId, + GroupId: w.GroupId, + EndpointName: w.EndpointName, + AccountId: w.AccountId, + EndpointService: w.EndpointService, + ResourceNames: w.ResourceNames, + VpcEndpointId: w.VpcEndpointId, + Enabled: w.Enabled, + Endpoint: endpointSelection, + }, nil +} + +type networkWire struct { + NetworkId *string `json:"network_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + WorkspaceId *int64 `json:"workspace_id,omitempty"` + VpcId *string `json:"vpc_id,omitempty"` + SubnetIds []string `json:"subnet_ids,omitempty"` + SecurityGroupIds []string `json:"security_group_ids,omitempty"` + VpcStatus VpcStatus `json:"vpc_status,omitempty"` + ErrorMessages []networkHealthWire `json:"error_messages,omitempty"` + NetworkName *string `json:"network_name,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + WarningMessages []networkWarningWire `json:"warning_messages,omitempty"` + VpcEndpoints *networkVpcEndpointsWire `json:"vpc_endpoints,omitempty"` + GcpNetworkInfo *gcpNetworkInfoWire `json:"gcp_network_info,omitempty"` +} + +func networkFromWire(w *networkWire) (*Network, error) { + if w == nil { + return nil, nil + } + networkInfoMembers := 0 + if w.GcpNetworkInfo != nil { + networkInfoMembers++ + } + if networkInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Network.NetworkInfo") + } + errorMessagesPublicValue, err := convertSlice(w.ErrorMessages, networkHealthFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Network.ErrorMessages", err) + } + warningMessagesPublicValue, err := convertSlice(w.WarningMessages, networkWarningFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Network.WarningMessages", err) + } + vpcEndpointsPublicValue, err := networkVpcEndpointsFromWire(w.VpcEndpoints) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Network.VpcEndpoints", err) + } + var networkInfoSelection isNetwork_NetworkInfo + switch { + case w.GcpNetworkInfo != nil: + networkInfoGcpNetworkInfoConverted, err := gcpNetworkInfoFromWire(w.GcpNetworkInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Network.NetworkInfo.GcpNetworkInfo", err) + } + networkInfoSelection = &Network_NetworkInfo_GcpNetworkInfo{GcpNetworkInfo: *networkInfoGcpNetworkInfoConverted} + } + return &Network{ + NetworkId: w.NetworkId, + AccountId: w.AccountId, + WorkspaceId: w.WorkspaceId, + VpcId: w.VpcId, + SubnetIds: w.SubnetIds, + SecurityGroupIds: w.SecurityGroupIds, + VpcStatus: w.VpcStatus, + ErrorMessages: errorMessagesPublicValue, + NetworkName: w.NetworkName, + CreationTime: w.CreationTime, + WarningMessages: warningMessagesPublicValue, + VpcEndpoints: vpcEndpointsPublicValue, + NetworkInfo: networkInfoSelection, + }, nil +} + +type networkConnectivityConfigWire struct { + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + Name *string `json:"name,omitempty"` + Region *string `json:"region,omitempty"` + EgressConfig *customerFacingNetworkConnectivityConfigEgressConfigWire `json:"egress_config,omitempty"` + UpdatedTime *int64 `json:"updated_time,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` +} + +func networkConnectivityConfigFromWire(w *networkConnectivityConfigWire) (*NetworkConnectivityConfig, error) { + if w == nil { + return nil, nil + } + egressConfigPublicValue, err := customerFacingNetworkConnectivityConfigEgressConfigFromWire(w.EgressConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NetworkConnectivityConfig.EgressConfig", err) + } + return &NetworkConnectivityConfig{ + NetworkConnectivityConfigId: w.NetworkConnectivityConfigId, + AccountId: w.AccountId, + Name: w.Name, + Region: w.Region, + EgressConfig: egressConfigPublicValue, + UpdatedTime: w.UpdatedTime, + CreationTime: w.CreationTime, + }, nil +} + +type networkConnectivityConfigAwsPrivateEndpointRuleWire struct { + RuleId *string `json:"rule_id,omitempty"` + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + EndpointService *string `json:"endpoint_service,omitempty"` + DomainNames []string `json:"domain_names,omitempty"` + ResourceNames []string `json:"resource_names,omitempty"` + VpcEndpointId *string `json:"vpc_endpoint_id,omitempty"` + ConnectionState NetworkConnectivityConfigAwsPrivateEndpointRule_PrivateLinkConnectionState `json:"connection_state,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + UpdatedTime *int64 `json:"updated_time,omitempty"` + Deactivated *bool `json:"deactivated,omitempty"` + DeactivatedAt *int64 `json:"deactivated_at,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + ErrorMessage *string `json:"error_message,omitempty"` +} + +func networkConnectivityConfigAwsPrivateEndpointRuleToWire(v *NetworkConnectivityConfigAwsPrivateEndpointRule) (*networkConnectivityConfigAwsPrivateEndpointRuleWire, error) { + if v == nil { + return nil, nil + } + return &networkConnectivityConfigAwsPrivateEndpointRuleWire{ + RuleId: v.RuleId, + NetworkConnectivityConfigId: v.NetworkConnectivityConfigId, + AccountId: v.AccountId, + EndpointService: v.EndpointService, + DomainNames: v.DomainNames, + ResourceNames: v.ResourceNames, + VpcEndpointId: v.VpcEndpointId, + ConnectionState: v.ConnectionState, + CreationTime: v.CreationTime, + UpdatedTime: v.UpdatedTime, + Deactivated: v.Deactivated, + DeactivatedAt: v.DeactivatedAt, + Enabled: v.Enabled, + ErrorMessage: v.ErrorMessage, + }, nil +} + +func networkConnectivityConfigAwsPrivateEndpointRuleFromWire(w *networkConnectivityConfigAwsPrivateEndpointRuleWire) (*NetworkConnectivityConfigAwsPrivateEndpointRule, error) { + if w == nil { + return nil, nil + } + return &NetworkConnectivityConfigAwsPrivateEndpointRule{ + RuleId: w.RuleId, + NetworkConnectivityConfigId: w.NetworkConnectivityConfigId, + AccountId: w.AccountId, + EndpointService: w.EndpointService, + DomainNames: w.DomainNames, + ResourceNames: w.ResourceNames, + VpcEndpointId: w.VpcEndpointId, + ConnectionState: w.ConnectionState, + CreationTime: w.CreationTime, + UpdatedTime: w.UpdatedTime, + Deactivated: w.Deactivated, + DeactivatedAt: w.DeactivatedAt, + Enabled: w.Enabled, + ErrorMessage: w.ErrorMessage, + }, nil +} + +type networkConnectivityConfigAzurePrivateEndpointRuleWire struct { + RuleId *string `json:"rule_id,omitempty"` + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + ResourceId *string `json:"resource_id,omitempty"` + GroupId *string `json:"group_id,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + ConnectionState NetworkConnectivityConfigAzurePrivateEndpointRule_PrivateLinkConnectionState `json:"connection_state,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + UpdatedTime *int64 `json:"updated_time,omitempty"` + Deactivated *bool `json:"deactivated,omitempty"` + DeactivatedAt *int64 `json:"deactivated_at,omitempty"` + DomainNames []string `json:"domain_names,omitempty"` + ErrorMessage *string `json:"error_message,omitempty"` +} + +func networkConnectivityConfigAzurePrivateEndpointRuleToWire(v *NetworkConnectivityConfigAzurePrivateEndpointRule) (*networkConnectivityConfigAzurePrivateEndpointRuleWire, error) { + if v == nil { + return nil, nil + } + return &networkConnectivityConfigAzurePrivateEndpointRuleWire{ + RuleId: v.RuleId, + NetworkConnectivityConfigId: v.NetworkConnectivityConfigId, + ResourceId: v.ResourceId, + GroupId: v.GroupId, + EndpointName: v.EndpointName, + ConnectionState: v.ConnectionState, + CreationTime: v.CreationTime, + UpdatedTime: v.UpdatedTime, + Deactivated: v.Deactivated, + DeactivatedAt: v.DeactivatedAt, + DomainNames: v.DomainNames, + ErrorMessage: v.ErrorMessage, + }, nil +} + +func networkConnectivityConfigAzurePrivateEndpointRuleFromWire(w *networkConnectivityConfigAzurePrivateEndpointRuleWire) (*NetworkConnectivityConfigAzurePrivateEndpointRule, error) { + if w == nil { + return nil, nil + } + return &NetworkConnectivityConfigAzurePrivateEndpointRule{ + RuleId: w.RuleId, + NetworkConnectivityConfigId: w.NetworkConnectivityConfigId, + ResourceId: w.ResourceId, + GroupId: w.GroupId, + EndpointName: w.EndpointName, + ConnectionState: w.ConnectionState, + CreationTime: w.CreationTime, + UpdatedTime: w.UpdatedTime, + Deactivated: w.Deactivated, + DeactivatedAt: w.DeactivatedAt, + DomainNames: w.DomainNames, + ErrorMessage: w.ErrorMessage, + }, nil +} + +type networkConnectivityConfigEgressConfig_DefaultRuleWire struct { + AzureServiceEndpointRule *networkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRuleWire `json:"azure_service_endpoint_rule,omitempty"` + AwsStableIpRule *networkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRuleWire `json:"aws_stable_ip_rule,omitempty"` +} + +func networkConnectivityConfigEgressConfig_DefaultRuleToWire(v *NetworkConnectivityConfigEgressConfig_DefaultRule) (*networkConnectivityConfigEgressConfig_DefaultRuleWire, error) { + if v == nil { + return nil, nil + } + azureServiceEndpointRuleWireValue, err := networkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRuleToWire(v.AzureServiceEndpointRule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NetworkConnectivityConfigEgressConfig_DefaultRule.AzureServiceEndpointRule", err) + } + awsStableIpRuleWireValue, err := networkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRuleToWire(v.AwsStableIpRule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NetworkConnectivityConfigEgressConfig_DefaultRule.AwsStableIpRule", err) + } + return &networkConnectivityConfigEgressConfig_DefaultRuleWire{ + AzureServiceEndpointRule: azureServiceEndpointRuleWireValue, + AwsStableIpRule: awsStableIpRuleWireValue, + }, nil +} + +func networkConnectivityConfigEgressConfig_DefaultRuleFromWire(w *networkConnectivityConfigEgressConfig_DefaultRuleWire) (*NetworkConnectivityConfigEgressConfig_DefaultRule, error) { + if w == nil { + return nil, nil + } + azureServiceEndpointRulePublicValue, err := networkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRuleFromWire(w.AzureServiceEndpointRule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NetworkConnectivityConfigEgressConfig_DefaultRule.AzureServiceEndpointRule", err) + } + awsStableIpRulePublicValue, err := networkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRuleFromWire(w.AwsStableIpRule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NetworkConnectivityConfigEgressConfig_DefaultRule.AwsStableIpRule", err) + } + return &NetworkConnectivityConfigEgressConfig_DefaultRule{ + AzureServiceEndpointRule: azureServiceEndpointRulePublicValue, + AwsStableIpRule: awsStableIpRulePublicValue, + }, nil +} + +type networkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRuleWire struct { + CidrBlocks []string `json:"cidr_blocks,omitempty"` +} + +func networkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRuleToWire(v *NetworkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRule) (*networkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRuleWire, error) { + if v == nil { + return nil, nil + } + return &networkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRuleWire{ + CidrBlocks: v.CidrBlocks, + }, nil +} + +func networkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRuleFromWire(w *networkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRuleWire) (*NetworkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRule, error) { + if w == nil { + return nil, nil + } + return &NetworkConnectivityConfigEgressConfig_DefaultRule_AwsStableIpRule{ + CidrBlocks: w.CidrBlocks, + }, nil +} + +type networkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRuleWire struct { + TargetRegion *string `json:"target_region,omitempty"` + TargetServices []EgressResourceType `json:"target_services,omitempty"` + Subnets []string `json:"subnets,omitempty"` +} + +func networkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRuleToWire(v *NetworkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRule) (*networkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRuleWire, error) { + if v == nil { + return nil, nil + } + return &networkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRuleWire{ + TargetRegion: v.TargetRegion, + TargetServices: v.TargetServices, + Subnets: v.Subnets, + }, nil +} + +func networkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRuleFromWire(w *networkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRuleWire) (*NetworkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRule, error) { + if w == nil { + return nil, nil + } + return &NetworkConnectivityConfigEgressConfig_DefaultRule_AzureServiceEndpointRule{ + TargetRegion: w.TargetRegion, + TargetServices: w.TargetServices, + Subnets: w.Subnets, + }, nil +} + +type networkHealthWire struct { + ErrorType *string `json:"error_type,omitempty"` + ErrorMessage *string `json:"error_message,omitempty"` +} + +func networkHealthFromWire(w *networkHealthWire) (*NetworkHealth, error) { + if w == nil { + return nil, nil + } + return &NetworkHealth{ + ErrorType: w.ErrorType, + ErrorMessage: w.ErrorMessage, + }, nil +} + +type networkVpcEndpointsWire struct { + RestApi []string `json:"rest_api,omitempty"` + DataplaneRelay []string `json:"dataplane_relay,omitempty"` +} + +func networkVpcEndpointsToWire(v *NetworkVpcEndpoints) (*networkVpcEndpointsWire, error) { + if v == nil { + return nil, nil + } + return &networkVpcEndpointsWire{ + RestApi: v.RestApi, + DataplaneRelay: v.DataplaneRelay, + }, nil +} + +func networkVpcEndpointsFromWire(w *networkVpcEndpointsWire) (*NetworkVpcEndpoints, error) { + if w == nil { + return nil, nil + } + return &NetworkVpcEndpoints{ + RestApi: w.RestApi, + DataplaneRelay: w.DataplaneRelay, + }, nil +} + +type networkWarningWire struct { + WarningType *string `json:"warning_type,omitempty"` + WarningMessage *string `json:"warning_message,omitempty"` +} + +func networkWarningFromWire(w *networkWarningWire) (*NetworkWarning, error) { + if w == nil { + return nil, nil + } + return &NetworkWarning{ + WarningType: w.WarningType, + WarningMessage: w.WarningMessage, + }, nil +} + +type privateAccessSettingsWire struct { + PrivateAccessSettingsId *string `json:"private_access_settings_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + PrivateAccessSettingsName *string `json:"private_access_settings_name,omitempty"` + Region *string `json:"region,omitempty"` + PublicAccessEnabled *bool `json:"public_access_enabled,omitempty"` + PrivateAccessLevel PrivateAccessLevel `json:"private_access_level,omitempty"` + AllowedVpcEndpointIds []string `json:"allowed_vpc_endpoint_ids,omitempty"` +} + +func privateAccessSettingsToWire(v *PrivateAccessSettings) (*privateAccessSettingsWire, error) { + if v == nil { + return nil, nil + } + return &privateAccessSettingsWire{ + PrivateAccessSettingsId: v.PrivateAccessSettingsId, + AccountId: v.AccountId, + PrivateAccessSettingsName: v.PrivateAccessSettingsName, + Region: v.Region, + PublicAccessEnabled: v.PublicAccessEnabled, + PrivateAccessLevel: v.PrivateAccessLevel, + AllowedVpcEndpointIds: v.AllowedVpcEndpointIds, + }, nil +} + +func privateAccessSettingsFromWire(w *privateAccessSettingsWire) (*PrivateAccessSettings, error) { + if w == nil { + return nil, nil + } + return &PrivateAccessSettings{ + PrivateAccessSettingsId: w.PrivateAccessSettingsId, + AccountId: w.AccountId, + PrivateAccessSettingsName: w.PrivateAccessSettingsName, + Region: w.Region, + PublicAccessEnabled: w.PublicAccessEnabled, + PrivateAccessLevel: w.PrivateAccessLevel, + AllowedVpcEndpointIds: w.AllowedVpcEndpointIds, + }, nil +} + +type replaceAccountIpAccessListRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ListId *string `json:"list_id,omitempty"` + Label *string `json:"label,omitempty"` + ListType AccountIpAccessListType_IpAccessListType `json:"list_type,omitempty"` + IpAddresses []string `json:"ip_addresses,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func replaceAccountIpAccessListRequestToWire(v *ReplaceAccountIpAccessListRequest) (*replaceAccountIpAccessListRequestWire, error) { + if v == nil { + return nil, nil + } + return &replaceAccountIpAccessListRequestWire{ + AccountId: v.AccountId, + ListId: v.ListId, + Label: v.Label, + ListType: v.ListType, + IpAddresses: v.IpAddresses, + Enabled: v.Enabled, + }, nil +} + +type replaceAccountIpAccessListResponseWire struct { + IpAccessList *accountIpAccessListWire `json:"ip_access_list,omitempty"` +} + +func replaceAccountIpAccessListResponseFromWire(w *replaceAccountIpAccessListResponseWire) (*ReplaceAccountIpAccessListResponse, error) { + if w == nil { + return nil, nil + } + ipAccessListPublicValue, err := accountIpAccessListFromWire(w.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ReplaceAccountIpAccessListResponse.IpAccessList", err) + } + return &ReplaceAccountIpAccessListResponse{ + IpAccessList: ipAccessListPublicValue, + }, nil +} + +type replaceIpAccessListRequestWire struct { + ListId *string `json:"list_id,omitempty"` + Label *string `json:"label,omitempty"` + ListType IpAccessListType `json:"list_type,omitempty"` + IpAddresses []string `json:"ip_addresses,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func replaceIpAccessListRequestToWire(v *ReplaceIpAccessListRequest) (*replaceIpAccessListRequestWire, error) { + if v == nil { + return nil, nil + } + return &replaceIpAccessListRequestWire{ + ListId: v.ListId, + Label: v.Label, + ListType: v.ListType, + IpAddresses: v.IpAddresses, + Enabled: v.Enabled, + }, nil +} + +type replaceIpAccessListResponseWire struct { + IpAccessList *ipAccessListWire `json:"ip_access_list,omitempty"` +} + +func replaceIpAccessListResponseFromWire(w *replaceIpAccessListResponseWire) (*ReplaceIpAccessListResponse, error) { + if w == nil { + return nil, nil + } + ipAccessListPublicValue, err := ipAccessListFromWire(w.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ReplaceIpAccessListResponse.IpAccessList", err) + } + return &ReplaceIpAccessListResponse{ + IpAccessList: ipAccessListPublicValue, + }, nil +} + +type updateAccountIpAccessListRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + ListId *string `json:"list_id,omitempty"` + Label *string `json:"label,omitempty"` + ListType AccountIpAccessListType_IpAccessListType `json:"list_type,omitempty"` + IpAddresses []string `json:"ip_addresses,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func updateAccountIpAccessListRequestToWire(v *UpdateAccountIpAccessListRequest) (*updateAccountIpAccessListRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateAccountIpAccessListRequestWire{ + AccountId: v.AccountId, + ListId: v.ListId, + Label: v.Label, + ListType: v.ListType, + IpAddresses: v.IpAddresses, + Enabled: v.Enabled, + }, nil +} + +type updateAccountIpAccessListResponseWire struct { + IpAccessList *accountIpAccessListWire `json:"ip_access_list,omitempty"` +} + +func updateAccountIpAccessListResponseFromWire(w *updateAccountIpAccessListResponseWire) (*UpdateAccountIpAccessListResponse, error) { + if w == nil { + return nil, nil + } + ipAccessListPublicValue, err := accountIpAccessListFromWire(w.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountIpAccessListResponse.IpAccessList", err) + } + return &UpdateAccountIpAccessListResponse{ + IpAccessList: ipAccessListPublicValue, + }, nil +} + +type updateIpAccessListRequestWire struct { + ListId *string `json:"list_id,omitempty"` + Label *string `json:"label,omitempty"` + ListType IpAccessListType `json:"list_type,omitempty"` + IpAddresses []string `json:"ip_addresses,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func updateIpAccessListRequestToWire(v *UpdateIpAccessListRequest) (*updateIpAccessListRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateIpAccessListRequestWire{ + ListId: v.ListId, + Label: v.Label, + ListType: v.ListType, + IpAddresses: v.IpAddresses, + Enabled: v.Enabled, + }, nil +} + +type updateIpAccessListResponseWire struct { + IpAccessList *ipAccessListWire `json:"ip_access_list,omitempty"` +} + +func updateIpAccessListResponseFromWire(w *updateIpAccessListResponseWire) (*UpdateIpAccessListResponse, error) { + if w == nil { + return nil, nil + } + ipAccessListPublicValue, err := ipAccessListFromWire(w.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateIpAccessListResponse.IpAccessList", err) + } + return &UpdateIpAccessListResponse{ + IpAccessList: ipAccessListPublicValue, + }, nil +} + +type updateNccPrivateEndpointRuleRequestWire struct { + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + PrivateEndpointRuleId *string `json:"private_endpoint_rule_id,omitempty"` + PrivateEndpointRule *updatePrivateEndpointRuleWire `json:"private_endpoint_rule,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateNccPrivateEndpointRuleRequestToWire(v *UpdateNccPrivateEndpointRuleRequest) (*updateNccPrivateEndpointRuleRequestWire, error) { + if v == nil { + return nil, nil + } + privateEndpointRuleWireValue, err := updatePrivateEndpointRuleToWire(v.PrivateEndpointRule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateNccPrivateEndpointRuleRequest.PrivateEndpointRule", err) + } + return &updateNccPrivateEndpointRuleRequestWire{ + NetworkConnectivityConfigId: v.NetworkConnectivityConfigId, + AccountId: v.AccountId, + PrivateEndpointRuleId: v.PrivateEndpointRuleId, + PrivateEndpointRule: privateEndpointRuleWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateNetworkPolicyRequestWire struct { + NetworkPolicyId *string `json:"network_policy_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + NetworkPolicy *accountNetworkPolicyWire `json:"network_policy,omitempty"` +} + +func updateNetworkPolicyRequestToWire(v *UpdateNetworkPolicyRequest) (*updateNetworkPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + networkPolicyWireValue, err := accountNetworkPolicyToWire(v.NetworkPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateNetworkPolicyRequest.NetworkPolicy", err) + } + return &updateNetworkPolicyRequestWire{ + NetworkPolicyId: v.NetworkPolicyId, + AccountId: v.AccountId, + NetworkPolicy: networkPolicyWireValue, + }, nil +} + +type updatePrivateAccessSettingsRequestWire struct { + CustomerFacingPrivateAccessSettings *privateAccessSettingsWire `json:"customer_facing_private_access_settings,omitempty"` +} + +func updatePrivateAccessSettingsRequestToWire(v *UpdatePrivateAccessSettingsRequest) (*updatePrivateAccessSettingsRequestWire, error) { + if v == nil { + return nil, nil + } + customerFacingPrivateAccessSettingsWireValue, err := privateAccessSettingsToWire(v.CustomerFacingPrivateAccessSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdatePrivateAccessSettingsRequest.CustomerFacingPrivateAccessSettings", err) + } + return &updatePrivateAccessSettingsRequestWire{ + CustomerFacingPrivateAccessSettings: customerFacingPrivateAccessSettingsWireValue, + }, nil +} + +type updatePrivateEndpointRuleWire struct { + RuleId *string `json:"rule_id,omitempty"` + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + ConnectionState NccPrivateEndpointRule_PrivateLinkConnectionState `json:"connection_state,omitempty"` + DomainNames []string `json:"domain_names,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + UpdatedTime *int64 `json:"updated_time,omitempty"` + Deactivated *bool `json:"deactivated,omitempty"` + DeactivatedAt *int64 `json:"deactivated_at,omitempty"` + ErrorMessage *string `json:"error_message,omitempty"` + ResourceId *string `json:"resource_id,omitempty"` + GroupId *string `json:"group_id,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + AccountId *string `json:"account_id,omitempty"` + EndpointService *string `json:"endpoint_service,omitempty"` + ResourceNames []string `json:"resource_names,omitempty"` + VpcEndpointId *string `json:"vpc_endpoint_id,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + GcpEndpoint *gcpEndpointWire `json:"gcp_endpoint,omitempty"` +} + +func updatePrivateEndpointRuleToWire(v *UpdatePrivateEndpointRule) (*updatePrivateEndpointRuleWire, error) { + if v == nil { + return nil, nil + } + var endpointGcpEndpointWire *gcpEndpointWire + switch value := v.Endpoint.(type) { + case nil: + case *UpdatePrivateEndpointRule_Endpoint_GcpEndpoint: + if value != nil { + endpointGcpEndpointConverted, err := gcpEndpointToWire(&value.GcpEndpoint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdatePrivateEndpointRule.Endpoint.GcpEndpoint", err) + } + endpointGcpEndpointWire = endpointGcpEndpointConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "UpdatePrivateEndpointRule.Endpoint", value) + } + return &updatePrivateEndpointRuleWire{ + RuleId: v.RuleId, + NetworkConnectivityConfigId: v.NetworkConnectivityConfigId, + ConnectionState: v.ConnectionState, + DomainNames: v.DomainNames, + CreationTime: v.CreationTime, + UpdatedTime: v.UpdatedTime, + Deactivated: v.Deactivated, + DeactivatedAt: v.DeactivatedAt, + ErrorMessage: v.ErrorMessage, + ResourceId: v.ResourceId, + GroupId: v.GroupId, + EndpointName: v.EndpointName, + AccountId: v.AccountId, + EndpointService: v.EndpointService, + ResourceNames: v.ResourceNames, + VpcEndpointId: v.VpcEndpointId, + Enabled: v.Enabled, + GcpEndpoint: endpointGcpEndpointWire, + }, nil +} + +type updateWorkspaceNetworkOptionRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + WorkspaceId *int64 `json:"workspace_id,omitempty"` + WorkspaceNetworkOption *workspaceNetworkOptionWire `json:"workspace_network_option,omitempty"` +} + +func updateWorkspaceNetworkOptionRequestToWire(v *UpdateWorkspaceNetworkOptionRequest) (*updateWorkspaceNetworkOptionRequestWire, error) { + if v == nil { + return nil, nil + } + workspaceNetworkOptionWireValue, err := workspaceNetworkOptionToWire(v.WorkspaceNetworkOption) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateWorkspaceNetworkOptionRequest.WorkspaceNetworkOption", err) + } + return &updateWorkspaceNetworkOptionRequestWire{ + AccountId: v.AccountId, + WorkspaceId: v.WorkspaceId, + WorkspaceNetworkOption: workspaceNetworkOptionWireValue, + }, nil +} + +type vpcEndpointWire struct { + VpcEndpointId *string `json:"vpc_endpoint_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + VpcEndpointName *string `json:"vpc_endpoint_name,omitempty"` + AwsVpcEndpointId *string `json:"aws_vpc_endpoint_id,omitempty"` + AwsEndpointServiceId *string `json:"aws_endpoint_service_id,omitempty"` + UseCase VpcEndpointUseCase `json:"use_case,omitempty"` + Region *string `json:"region,omitempty"` + AwsAccountId *string `json:"aws_account_id,omitempty"` + State *string `json:"state,omitempty"` + GcpVpcEndpointInfo *gcpVpcEndpointInfoWire `json:"gcp_vpc_endpoint_info,omitempty"` +} + +func vpcEndpointFromWire(w *vpcEndpointWire) (*VpcEndpoint, error) { + if w == nil { + return nil, nil + } + vpcEndpointInfoMembers := 0 + if w.GcpVpcEndpointInfo != nil { + vpcEndpointInfoMembers++ + } + if vpcEndpointInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "VpcEndpoint.VpcEndpointInfo") + } + var vpcEndpointInfoSelection isVpcEndpoint_VpcEndpointInfo + switch { + case w.GcpVpcEndpointInfo != nil: + vpcEndpointInfoGcpVpcEndpointInfoConverted, err := gcpVpcEndpointInfoFromWire(w.GcpVpcEndpointInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "VpcEndpoint.VpcEndpointInfo.GcpVpcEndpointInfo", err) + } + vpcEndpointInfoSelection = &VpcEndpoint_VpcEndpointInfo_GcpVpcEndpointInfo{GcpVpcEndpointInfo: *vpcEndpointInfoGcpVpcEndpointInfoConverted} + } + return &VpcEndpoint{ + VpcEndpointId: w.VpcEndpointId, + AccountId: w.AccountId, + VpcEndpointName: w.VpcEndpointName, + AwsVpcEndpointId: w.AwsVpcEndpointId, + AwsEndpointServiceId: w.AwsEndpointServiceId, + UseCase: w.UseCase, + Region: w.Region, + AwsAccountId: w.AwsAccountId, + State: w.State, + VpcEndpointInfo: vpcEndpointInfoSelection, + }, nil +} + +type workspaceNetworkOptionWire struct { + NetworkPolicyId *string `json:"network_policy_id,omitempty"` + WorkspaceId *int64 `json:"workspace_id,omitempty"` +} + +func workspaceNetworkOptionToWire(v *WorkspaceNetworkOption) (*workspaceNetworkOptionWire, error) { + if v == nil { + return nil, nil + } + return &workspaceNetworkOptionWire{ + NetworkPolicyId: v.NetworkPolicyId, + WorkspaceId: v.WorkspaceId, + }, nil +} + +func workspaceNetworkOptionFromWire(w *workspaceNetworkOptionWire) (*WorkspaceNetworkOption, error) { + if w == nil { + return nil, nil + } + return &WorkspaceNetworkOption{ + NetworkPolicyId: w.NetworkPolicyId, + WorkspaceId: w.WorkspaceId, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/notificationdestinations/.package.json b/notificationdestinations/.package.json new file mode 100644 index 0000000..9ba714d --- /dev/null +++ b/notificationdestinations/.package.json @@ -0,0 +1,3 @@ +{ + "package": "notificationdestinations" +} diff --git a/notificationdestinations/CHANGELOG.md b/notificationdestinations/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/notificationdestinations/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/notificationdestinations/README.md b/notificationdestinations/README.md new file mode 100644 index 0000000..53b3033 --- /dev/null +++ b/notificationdestinations/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/notificationdestinations + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/notificationdestinations@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/notificationdestinations/v1" + +client, err := notificationdestinations.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/notificationdestinations/go.mod b/notificationdestinations/go.mod new file mode 100644 index 0000000..9c9dc20 --- /dev/null +++ b/notificationdestinations/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/notificationdestinations + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/notificationdestinations/internal/version.go b/notificationdestinations/internal/version.go new file mode 100644 index 0000000..55891b0 --- /dev/null +++ b/notificationdestinations/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-notificationdestinations" + +const Version = "0.0.1-dev.1" diff --git a/notificationdestinations/v1/client.go b/notificationdestinations/v1/client.go new file mode 100755 index 0000000..b41d67e --- /dev/null +++ b/notificationdestinations/v1/client.go @@ -0,0 +1,436 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package notificationdestinations + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/notificationdestinations/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a notification destination. Requires workspace admin permissions. +func (c *internalClient) CreateNotificationDestination(ctx context.Context, req *CreateNotificationDestinationRequest, opts ...call.Option) (*NotificationDestination, error) { + wireReq, err := createNotificationDestinationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/notification-destinations" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *NotificationDestination + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp notificationDestinationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = notificationDestinationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a notification destination. Requires workspace admin permissions. +func (c *internalClient) DeleteNotificationDestination(ctx context.Context, req *DeleteNotificationDestinationRequest, opts ...call.Option) (*Empty, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/notification-destinations/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Empty + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &Empty{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a notification destination. +func (c *internalClient) GetNotificationDestination(ctx context.Context, req *GetNotificationDestinationRequest, opts ...call.Option) (*NotificationDestination, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/notification-destinations/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *NotificationDestination + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp notificationDestinationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = notificationDestinationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists notification destinations. +func (c *internalClient) ListNotificationDestinations(ctx context.Context, req *ListNotificationDestinationsRequest, opts ...call.Option) (*ListNotificationDestinationsResponse, error) { + wireReq, err := listNotificationDestinationsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/notification-destinations" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListNotificationDestinationsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listNotificationDestinationsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listNotificationDestinationsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListNotificationDestinationsIter returns an iterator that iterates +// over the results of ListNotificationDestinations. +// +// For example: +// +// for item, err := range c.ListNotificationDestinationsIter(ctx, &ListNotificationDestinationsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListNotificationDestinations call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListNotificationDestinations directly. +func (c *internalClient) ListNotificationDestinationsIter(ctx context.Context, req *ListNotificationDestinationsRequest, opts ...call.Option) iter.Seq2[*ListNotificationDestinationsResult, error] { + return func(yield func(*ListNotificationDestinationsResult, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListNotificationDestinationsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListNotificationDestinations(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Results { + if !yield(&resp.Results[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates a notification destination. Requires workspace admin permissions. At +// least one field is required in the request body. +func (c *internalClient) UpdateNotificationDestination(ctx context.Context, req *UpdateNotificationDestinationRequest, opts ...call.Option) (*NotificationDestination, error) { + wireReq, err := updateNotificationDestinationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/notification-destinations/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *NotificationDestination + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp notificationDestinationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = notificationDestinationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/notificationdestinations/v1/genhelper.go b/notificationdestinations/v1/genhelper.go new file mode 100755 index 0000000..691df90 --- /dev/null +++ b/notificationdestinations/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package notificationdestinations + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/notificationdestinations/v1/model.go b/notificationdestinations/v1/model.go new file mode 100755 index 0000000..94f5b4f --- /dev/null +++ b/notificationdestinations/v1/model.go @@ -0,0 +1,188 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package notificationdestinations + +type DestinationType string + +const ( + DestinationType_Unspecified DestinationType = "" + DestinationType_Slack DestinationType = "SLACK" + DestinationType_Email DestinationType = "EMAIL" + DestinationType_Webhook DestinationType = "WEBHOOK" + DestinationType_Pagerduty DestinationType = "PAGERDUTY" + DestinationType_MicrosoftTeams DestinationType = "MICROSOFT_TEAMS" +) + +type Config struct { + Config isConfig_Config +} + +type isConfig_Config interface { + isConfig_Config() +} + +// Config_Config_Slack selects Slack for Config.Config. +type Config_Config_Slack struct { + Slack SlackConfig +} + +func (*Config_Config_Slack) isConfig_Config() {} + +// Config_Config_Email selects Email for Config.Config. +type Config_Config_Email struct { + Email EmailConfig +} + +func (*Config_Config_Email) isConfig_Config() {} + +// Config_Config_GenericWebhook selects GenericWebhook for Config.Config. +type Config_Config_GenericWebhook struct { + GenericWebhook GenericWebhookConfig +} + +func (*Config_Config_GenericWebhook) isConfig_Config() {} + +// Config_Config_Pagerduty selects Pagerduty for Config.Config. +type Config_Config_Pagerduty struct { + Pagerduty PagerdutyConfig +} + +func (*Config_Config_Pagerduty) isConfig_Config() {} + +// Config_Config_MicrosoftTeams selects MicrosoftTeams for Config.Config. +type Config_Config_MicrosoftTeams struct { + MicrosoftTeams MicrosoftTeamsConfig +} + +func (*Config_Config_MicrosoftTeams) isConfig_Config() {} + +type CreateNotificationDestinationRequest struct { + // The display name for the notification destination. + DisplayName *string + // The configuration for the notification destination. Must wrap EXACTLY one of + // the nested configs. + Config *Config +} + +type DeleteNotificationDestinationRequest struct { + Id *string +} + +type EmailConfig struct { + // Email addresses to notify. + Addresses []string +} + +type Empty struct { +} + +type GenericWebhookConfig struct { + // [Input-Only] URL for webhook. + Url *string + // [Output-Only] Whether URL is set. + UrlSet *bool + // [Input-Only][Optional] Username for webhook. + Username *string + // [Output-Only] Whether username is set. + UsernameSet *bool + // [Input-Only][Optional] Password for webhook. + Password *string + // [Output-Only] Whether password is set. + PasswordSet *bool +} + +type GetNotificationDestinationRequest struct { + Id *string +} + +type ListNotificationDestinationsRequest struct { + PageToken *string + PageSize *int64 +} + +type ListNotificationDestinationsResponse struct { + Results []ListNotificationDestinationsResult + // Page token for next of results. + NextPageToken *string +} + +type ListNotificationDestinationsResult struct { + // UUID identifying notification destination. + Id *string + // The display name for the notification destination. + DisplayName *string + // [Output-only] The type of the notification destination. The type can not be + // changed once set. + DestinationType DestinationType + // The configuration for the notification destination. Will be exactly one of + // the nested configs. Only returns for users with workspace admin permissions. + Config *Config +} + +type MicrosoftTeamsConfig struct { + // [Input-Only] URL for Microsoft Teams webhook. + Url *string + // [Output-Only] Whether URL is set. + UrlSet *bool + // [Input-Only] App ID for Microsoft Teams App. + AppId *string + // [Output-Only] Whether App ID is set. + AppIdSet *bool + // [Input-Only] Secret for Microsoft Teams App authentication. + AuthSecret *string + // [Output-Only] Whether secret is set. + AuthSecretSet *bool + // [Input-Only] Channel URL for Microsoft Teams App. + ChannelUrl *string + // [Output-Only] Whether Channel URL is set. + ChannelUrlSet *bool + // [Input-Only] Tenant ID for Microsoft Teams App. + TenantId *string + // [Output-Only] Whether Tenant ID is set. + TenantIdSet *bool +} + +type NotificationDestination struct { + // UUID identifying notification destination. + Id *string + // The display name for the notification destination. + DisplayName *string + // [Output-only] The type of the notification destination. The type can not be + // changed once set. + DestinationType DestinationType + // The configuration for the notification destination. Will be exactly one of + // the nested configs. Only returns for users with workspace admin permissions. + Config *Config +} + +type PagerdutyConfig struct { + // [Input-Only] Integration key for PagerDuty. + IntegrationKey *string + // [Output-Only] Whether integration key is set. + IntegrationKeySet *bool +} + +type SlackConfig struct { + // [Input-Only] URL for Slack destination. + Url *string + // [Output-Only] Whether URL is set. + UrlSet *bool + // [Input-Only] OAuth token for Slack authentication. + OauthToken *string + // [Output-Only] Whether OAuth token is set. + OauthTokenSet *bool + // [Input-Only] Slack channel ID for notifications. + ChannelId *string + // [Output-Only] Whether channel ID is set. + ChannelIdSet *bool +} + +type UpdateNotificationDestinationRequest struct { + // UUID identifying notification destination. + Id *string + // The display name for the notification destination. + DisplayName *string + // The configuration for the notification destination. Must wrap EXACTLY one of + // the nested configs. + Config *Config +} diff --git a/notificationdestinations/v1/wire.go b/notificationdestinations/v1/wire.go new file mode 100755 index 0000000..700ac68 --- /dev/null +++ b/notificationdestinations/v1/wire.go @@ -0,0 +1,444 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package notificationdestinations + +import ( + "fmt" +) + +type configWire struct { + Slack *slackConfigWire `json:"slack,omitempty"` + Email *emailConfigWire `json:"email,omitempty"` + GenericWebhook *genericWebhookConfigWire `json:"generic_webhook,omitempty"` + Pagerduty *pagerdutyConfigWire `json:"pagerduty,omitempty"` + MicrosoftTeams *microsoftTeamsConfigWire `json:"microsoft_teams,omitempty"` +} + +func configToWire(v *Config) (*configWire, error) { + if v == nil { + return nil, nil + } + var configSlackWire *slackConfigWire + var configEmailWire *emailConfigWire + var configGenericWebhookWire *genericWebhookConfigWire + var configPagerdutyWire *pagerdutyConfigWire + var configMicrosoftTeamsWire *microsoftTeamsConfigWire + switch value := v.Config.(type) { + case nil: + case *Config_Config_Slack: + if value != nil { + configSlackConverted, err := slackConfigToWire(&value.Slack) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Config.Config.Slack", err) + } + configSlackWire = configSlackConverted + } + case *Config_Config_Email: + if value != nil { + configEmailConverted, err := emailConfigToWire(&value.Email) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Config.Config.Email", err) + } + configEmailWire = configEmailConverted + } + case *Config_Config_GenericWebhook: + if value != nil { + configGenericWebhookConverted, err := genericWebhookConfigToWire(&value.GenericWebhook) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Config.Config.GenericWebhook", err) + } + configGenericWebhookWire = configGenericWebhookConverted + } + case *Config_Config_Pagerduty: + if value != nil { + configPagerdutyConverted, err := pagerdutyConfigToWire(&value.Pagerduty) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Config.Config.Pagerduty", err) + } + configPagerdutyWire = configPagerdutyConverted + } + case *Config_Config_MicrosoftTeams: + if value != nil { + configMicrosoftTeamsConverted, err := microsoftTeamsConfigToWire(&value.MicrosoftTeams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Config.Config.MicrosoftTeams", err) + } + configMicrosoftTeamsWire = configMicrosoftTeamsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Config.Config", value) + } + return &configWire{ + Slack: configSlackWire, + Email: configEmailWire, + GenericWebhook: configGenericWebhookWire, + Pagerduty: configPagerdutyWire, + MicrosoftTeams: configMicrosoftTeamsWire, + }, nil +} + +func configFromWire(w *configWire) (*Config, error) { + if w == nil { + return nil, nil + } + configMembers := 0 + if w.Slack != nil { + configMembers++ + } + if w.Email != nil { + configMembers++ + } + if w.GenericWebhook != nil { + configMembers++ + } + if w.Pagerduty != nil { + configMembers++ + } + if w.MicrosoftTeams != nil { + configMembers++ + } + if configMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Config.Config") + } + var configSelection isConfig_Config + switch { + case w.Slack != nil: + configSlackConverted, err := slackConfigFromWire(w.Slack) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Config.Config.Slack", err) + } + configSelection = &Config_Config_Slack{Slack: *configSlackConverted} + case w.Email != nil: + configEmailConverted, err := emailConfigFromWire(w.Email) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Config.Config.Email", err) + } + configSelection = &Config_Config_Email{Email: *configEmailConverted} + case w.GenericWebhook != nil: + configGenericWebhookConverted, err := genericWebhookConfigFromWire(w.GenericWebhook) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Config.Config.GenericWebhook", err) + } + configSelection = &Config_Config_GenericWebhook{GenericWebhook: *configGenericWebhookConverted} + case w.Pagerduty != nil: + configPagerdutyConverted, err := pagerdutyConfigFromWire(w.Pagerduty) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Config.Config.Pagerduty", err) + } + configSelection = &Config_Config_Pagerduty{Pagerduty: *configPagerdutyConverted} + case w.MicrosoftTeams != nil: + configMicrosoftTeamsConverted, err := microsoftTeamsConfigFromWire(w.MicrosoftTeams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Config.Config.MicrosoftTeams", err) + } + configSelection = &Config_Config_MicrosoftTeams{MicrosoftTeams: *configMicrosoftTeamsConverted} + } + return &Config{ + Config: configSelection, + }, nil +} + +type createNotificationDestinationRequestWire struct { + DisplayName *string `json:"display_name,omitempty"` + Config *configWire `json:"config,omitempty"` +} + +func createNotificationDestinationRequestToWire(v *CreateNotificationDestinationRequest) (*createNotificationDestinationRequestWire, error) { + if v == nil { + return nil, nil + } + configWireValue, err := configToWire(v.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateNotificationDestinationRequest.Config", err) + } + return &createNotificationDestinationRequestWire{ + DisplayName: v.DisplayName, + Config: configWireValue, + }, nil +} + +type emailConfigWire struct { + Addresses []string `json:"addresses,omitempty"` +} + +func emailConfigToWire(v *EmailConfig) (*emailConfigWire, error) { + if v == nil { + return nil, nil + } + return &emailConfigWire{ + Addresses: v.Addresses, + }, nil +} + +func emailConfigFromWire(w *emailConfigWire) (*EmailConfig, error) { + if w == nil { + return nil, nil + } + return &EmailConfig{ + Addresses: w.Addresses, + }, nil +} + +type genericWebhookConfigWire struct { + Url *string `json:"url,omitempty"` + UrlSet *bool `json:"url_set,omitempty"` + Username *string `json:"username,omitempty"` + UsernameSet *bool `json:"username_set,omitempty"` + Password *string `json:"password,omitempty"` + PasswordSet *bool `json:"password_set,omitempty"` +} + +func genericWebhookConfigToWire(v *GenericWebhookConfig) (*genericWebhookConfigWire, error) { + if v == nil { + return nil, nil + } + return &genericWebhookConfigWire{ + Url: v.Url, + UrlSet: v.UrlSet, + Username: v.Username, + UsernameSet: v.UsernameSet, + Password: v.Password, + PasswordSet: v.PasswordSet, + }, nil +} + +func genericWebhookConfigFromWire(w *genericWebhookConfigWire) (*GenericWebhookConfig, error) { + if w == nil { + return nil, nil + } + return &GenericWebhookConfig{ + Url: w.Url, + UrlSet: w.UrlSet, + Username: w.Username, + UsernameSet: w.UsernameSet, + Password: w.Password, + PasswordSet: w.PasswordSet, + }, nil +} + +type listNotificationDestinationsRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int64 `json:"page_size,omitempty"` +} + +func listNotificationDestinationsRequestToWire(v *ListNotificationDestinationsRequest) (*listNotificationDestinationsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listNotificationDestinationsRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listNotificationDestinationsResponseWire struct { + Results []listNotificationDestinationsResultWire `json:"results,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listNotificationDestinationsResponseFromWire(w *listNotificationDestinationsResponseWire) (*ListNotificationDestinationsResponse, error) { + if w == nil { + return nil, nil + } + resultsPublicValue, err := convertSlice(w.Results, listNotificationDestinationsResultFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListNotificationDestinationsResponse.Results", err) + } + return &ListNotificationDestinationsResponse{ + Results: resultsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listNotificationDestinationsResultWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + DestinationType DestinationType `json:"destination_type,omitempty"` + Config *configWire `json:"config,omitempty"` +} + +func listNotificationDestinationsResultFromWire(w *listNotificationDestinationsResultWire) (*ListNotificationDestinationsResult, error) { + if w == nil { + return nil, nil + } + configPublicValue, err := configFromWire(w.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListNotificationDestinationsResult.Config", err) + } + return &ListNotificationDestinationsResult{ + Id: w.Id, + DisplayName: w.DisplayName, + DestinationType: w.DestinationType, + Config: configPublicValue, + }, nil +} + +type microsoftTeamsConfigWire struct { + Url *string `json:"url,omitempty"` + UrlSet *bool `json:"url_set,omitempty"` + AppId *string `json:"app_id,omitempty"` + AppIdSet *bool `json:"app_id_set,omitempty"` + AuthSecret *string `json:"auth_secret,omitempty"` + AuthSecretSet *bool `json:"auth_secret_set,omitempty"` + ChannelUrl *string `json:"channel_url,omitempty"` + ChannelUrlSet *bool `json:"channel_url_set,omitempty"` + TenantId *string `json:"tenant_id,omitempty"` + TenantIdSet *bool `json:"tenant_id_set,omitempty"` +} + +func microsoftTeamsConfigToWire(v *MicrosoftTeamsConfig) (*microsoftTeamsConfigWire, error) { + if v == nil { + return nil, nil + } + return µsoftTeamsConfigWire{ + Url: v.Url, + UrlSet: v.UrlSet, + AppId: v.AppId, + AppIdSet: v.AppIdSet, + AuthSecret: v.AuthSecret, + AuthSecretSet: v.AuthSecretSet, + ChannelUrl: v.ChannelUrl, + ChannelUrlSet: v.ChannelUrlSet, + TenantId: v.TenantId, + TenantIdSet: v.TenantIdSet, + }, nil +} + +func microsoftTeamsConfigFromWire(w *microsoftTeamsConfigWire) (*MicrosoftTeamsConfig, error) { + if w == nil { + return nil, nil + } + return &MicrosoftTeamsConfig{ + Url: w.Url, + UrlSet: w.UrlSet, + AppId: w.AppId, + AppIdSet: w.AppIdSet, + AuthSecret: w.AuthSecret, + AuthSecretSet: w.AuthSecretSet, + ChannelUrl: w.ChannelUrl, + ChannelUrlSet: w.ChannelUrlSet, + TenantId: w.TenantId, + TenantIdSet: w.TenantIdSet, + }, nil +} + +type notificationDestinationWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + DestinationType DestinationType `json:"destination_type,omitempty"` + Config *configWire `json:"config,omitempty"` +} + +func notificationDestinationFromWire(w *notificationDestinationWire) (*NotificationDestination, error) { + if w == nil { + return nil, nil + } + configPublicValue, err := configFromWire(w.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NotificationDestination.Config", err) + } + return &NotificationDestination{ + Id: w.Id, + DisplayName: w.DisplayName, + DestinationType: w.DestinationType, + Config: configPublicValue, + }, nil +} + +type pagerdutyConfigWire struct { + IntegrationKey *string `json:"integration_key,omitempty"` + IntegrationKeySet *bool `json:"integration_key_set,omitempty"` +} + +func pagerdutyConfigToWire(v *PagerdutyConfig) (*pagerdutyConfigWire, error) { + if v == nil { + return nil, nil + } + return &pagerdutyConfigWire{ + IntegrationKey: v.IntegrationKey, + IntegrationKeySet: v.IntegrationKeySet, + }, nil +} + +func pagerdutyConfigFromWire(w *pagerdutyConfigWire) (*PagerdutyConfig, error) { + if w == nil { + return nil, nil + } + return &PagerdutyConfig{ + IntegrationKey: w.IntegrationKey, + IntegrationKeySet: w.IntegrationKeySet, + }, nil +} + +type slackConfigWire struct { + Url *string `json:"url,omitempty"` + UrlSet *bool `json:"url_set,omitempty"` + OauthToken *string `json:"oauth_token,omitempty"` + OauthTokenSet *bool `json:"oauth_token_set,omitempty"` + ChannelId *string `json:"channel_id,omitempty"` + ChannelIdSet *bool `json:"channel_id_set,omitempty"` +} + +func slackConfigToWire(v *SlackConfig) (*slackConfigWire, error) { + if v == nil { + return nil, nil + } + return &slackConfigWire{ + Url: v.Url, + UrlSet: v.UrlSet, + OauthToken: v.OauthToken, + OauthTokenSet: v.OauthTokenSet, + ChannelId: v.ChannelId, + ChannelIdSet: v.ChannelIdSet, + }, nil +} + +func slackConfigFromWire(w *slackConfigWire) (*SlackConfig, error) { + if w == nil { + return nil, nil + } + return &SlackConfig{ + Url: w.Url, + UrlSet: w.UrlSet, + OauthToken: w.OauthToken, + OauthTokenSet: w.OauthTokenSet, + ChannelId: w.ChannelId, + ChannelIdSet: w.ChannelIdSet, + }, nil +} + +type updateNotificationDestinationRequestWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Config *configWire `json:"config,omitempty"` +} + +func updateNotificationDestinationRequestToWire(v *UpdateNotificationDestinationRequest) (*updateNotificationDestinationRequestWire, error) { + if v == nil { + return nil, nil + } + configWireValue, err := configToWire(v.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateNotificationDestinationRequest.Config", err) + } + return &updateNotificationDestinationRequestWire{ + Id: v.Id, + DisplayName: v.DisplayName, + Config: configWireValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/oauth/.package.json b/oauth/.package.json new file mode 100644 index 0000000..fcdcf82 --- /dev/null +++ b/oauth/.package.json @@ -0,0 +1,3 @@ +{ + "package": "oauth" +} diff --git a/oauth/CHANGELOG.md b/oauth/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/oauth/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/oauth/README.md b/oauth/README.md new file mode 100644 index 0000000..e9cca3b --- /dev/null +++ b/oauth/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/oauth + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/oauth@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/oauth/v1" + +client, err := oauth.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/oauth/go.mod b/oauth/go.mod new file mode 100644 index 0000000..3cf3d0e --- /dev/null +++ b/oauth/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/oauth + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/oauth/internal/version.go b/oauth/internal/version.go new file mode 100644 index 0000000..ffc3a37 --- /dev/null +++ b/oauth/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-oauth" + +const Version = "0.0.1-dev.1" diff --git a/oauth/v1/client.go b/oauth/v1/client.go new file mode 100755 index 0000000..e55ce80 --- /dev/null +++ b/oauth/v1/client.go @@ -0,0 +1,973 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package oauth + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/oauth/internal" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create Custom OAuth App Integration. +// +// You can retrieve the custom OAuth app integration via +// [CustomAppIntegration/get]. +// +// [CustomAppIntegration/get]: https://docs.databricks.com/api/account/customappintegration/get +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateCustomOAuthAppIntegration(ctx context.Context, req *CreateCustomOAuthAppIntegrationRequest, opts ...call.Option) (*CustomOAuthAppIntegrationSecret, error) { + wireReq, err := createCustomOAuthAppIntegrationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/custom-app-integrations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomOAuthAppIntegrationSecret + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customOAuthAppIntegrationSecretWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customOAuthAppIntegrationSecretFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create Published OAuth App Integration. +// +// You can retrieve the published OAuth app integration via +// [PublishedAppIntegration/get]. +// +// [PublishedAppIntegration/get]: https://docs.databricks.com/api/account/publishedappintegration/get +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreatePublishedOAuthAppIntegration(ctx context.Context, req *CreatePublishedOAuthAppIntegrationRequest, opts ...call.Option) (*CreatePublishedOAuthAppIntegrationResponse, error) { + wireReq, err := createPublishedOAuthAppIntegrationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/published-app-integrations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreatePublishedOAuthAppIntegrationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createPublishedOAuthAppIntegrationResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createPublishedOAuthAppIntegrationResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete an existing Custom OAuth App Integration. You can retrieve the custom +// OAuth app integration via [CustomAppIntegration/get]. +// +// [CustomAppIntegration/get]: https://docs.databricks.com/api/account/customappintegration/get +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteCustomOAuthAppIntegration(ctx context.Context, req *DeleteCustomOAuthAppIntegrationRequest, opts ...call.Option) (*DeleteCustomOAuthAppIntegrationResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/custom-app-integrations/") + pb.singleSegment(*req.IntegrationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteCustomOAuthAppIntegrationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteCustomOAuthAppIntegrationResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete an existing Published OAuth App Integration. You can retrieve the +// published OAuth app integration via [PublishedAppIntegration/get]. +// +// [PublishedAppIntegration/get]: https://docs.databricks.com/api/account/publishedappintegration/get +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeletePublishedOAuthAppIntegration(ctx context.Context, req *DeletePublishedOAuthAppIntegrationRequest, opts ...call.Option) (*DeletePublishedOAuthAppIntegrationResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/published-app-integrations/") + pb.singleSegment(*req.IntegrationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeletePublishedOAuthAppIntegrationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeletePublishedOAuthAppIntegrationResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the Custom OAuth App Integration for the given integration id. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetCustomOAuthAppIntegration(ctx context.Context, req *GetCustomOAuthAppIntegrationRequest, opts ...call.Option) (*CustomOAuthAppIntegration, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/custom-app-integrations/") + pb.singleSegment(*req.IntegrationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CustomOAuthAppIntegration + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp customOAuthAppIntegrationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = customOAuthAppIntegrationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the Published OAuth App Integration for the given integration id. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetPublishedOAuthAppIntegration(ctx context.Context, req *GetPublishedOAuthAppIntegrationRequest, opts ...call.Option) (*PublishedOAuthAppIntegration, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/published-app-integrations/") + pb.singleSegment(*req.IntegrationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PublishedOAuthAppIntegration + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp publishedOAuthAppIntegrationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = publishedOAuthAppIntegrationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get the list of custom OAuth app integrations for the specified +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListCustomOAuthAppIntegrations(ctx context.Context, req *ListCustomOAuthAppIntegrationsRequest, opts ...call.Option) (*ListCustomOAuthAppIntegrationsResponse, error) { + wireReq, err := listCustomOAuthAppIntegrationsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/custom-app-integrations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_creator_username", wireReq.IncludeCreatorUsername); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCustomOAuthAppIntegrationsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCustomOAuthAppIntegrationsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCustomOAuthAppIntegrationsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCustomOAuthAppIntegrationsIter returns an iterator that iterates +// over the results of ListCustomOAuthAppIntegrations. +// +// For example: +// +// for item, err := range c.ListCustomOAuthAppIntegrationsIter(ctx, &ListCustomOAuthAppIntegrationsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCustomOAuthAppIntegrations call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCustomOAuthAppIntegrations directly. +func (c *internalClient) ListCustomOAuthAppIntegrationsIter(ctx context.Context, req *ListCustomOAuthAppIntegrationsRequest, opts ...call.Option) iter.Seq2[*CustomOAuthAppIntegration, error] { + return func(yield func(*CustomOAuthAppIntegration, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCustomOAuthAppIntegrationsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCustomOAuthAppIntegrations(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Apps { + if !yield(&resp.Apps[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get the list of published OAuth app integrations for the specified +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListPublishedOAuthAppIntegrations(ctx context.Context, req *ListPublishedOAuthAppIntegrationsRequest, opts ...call.Option) (*ListPublishedOAuthAppIntegrationsResponse, error) { + wireReq, err := listPublishedOAuthAppIntegrationsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/published-app-integrations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPublishedOAuthAppIntegrationsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listPublishedOAuthAppIntegrationsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listPublishedOAuthAppIntegrationsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListPublishedOAuthAppIntegrationsIter returns an iterator that iterates +// over the results of ListPublishedOAuthAppIntegrations. +// +// For example: +// +// for item, err := range c.ListPublishedOAuthAppIntegrationsIter(ctx, &ListPublishedOAuthAppIntegrationsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListPublishedOAuthAppIntegrations call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListPublishedOAuthAppIntegrations directly. +func (c *internalClient) ListPublishedOAuthAppIntegrationsIter(ctx context.Context, req *ListPublishedOAuthAppIntegrationsRequest, opts ...call.Option) iter.Seq2[*PublishedOAuthAppIntegration, error] { + return func(yield func(*PublishedOAuthAppIntegration, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListPublishedOAuthAppIntegrationsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListPublishedOAuthAppIntegrations(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Apps { + if !yield(&resp.Apps[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get all the available published OAuth apps in . +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListPublishedOAuthApps(ctx context.Context, req *ListPublishedOAuthAppsRequest, opts ...call.Option) (*ListPublishedOAuthAppsResponse, error) { + wireReq, err := listPublishedOAuthAppsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/published-apps") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPublishedOAuthAppsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listPublishedOAuthAppsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listPublishedOAuthAppsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListPublishedOAuthAppsIter returns an iterator that iterates +// over the results of ListPublishedOAuthApps. +// +// For example: +// +// for item, err := range c.ListPublishedOAuthAppsIter(ctx, &ListPublishedOAuthAppsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListPublishedOAuthApps call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListPublishedOAuthApps directly. +func (c *internalClient) ListPublishedOAuthAppsIter(ctx context.Context, req *ListPublishedOAuthAppsRequest, opts ...call.Option) iter.Seq2[*PublishedOAuthApp, error] { + return func(yield func(*PublishedOAuthApp, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListPublishedOAuthAppsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListPublishedOAuthApps(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Apps { + if !yield(&resp.Apps[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates an existing custom OAuth App Integration. You can retrieve the custom +// OAuth app integration via [CustomAppIntegration/get]. +// +// [CustomAppIntegration/get]: https://docs.databricks.com/api/account/customappintegration/get +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateCustomOAuthAppIntegration(ctx context.Context, req *UpdateCustomOAuthAppIntegrationRequest, opts ...call.Option) (*UpdateCustomOAuthAppIntegrationResponse, error) { + wireReq, err := updateCustomOAuthAppIntegrationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/custom-app-integrations/") + pb.singleSegment(*req.IntegrationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateCustomOAuthAppIntegrationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateCustomOAuthAppIntegrationResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an existing published OAuth App Integration. You can retrieve the +// published OAuth app integration via [PublishedAppIntegration/get]. +// +// [PublishedAppIntegration/get]: https://docs.databricks.com/api/account/publishedappintegration/get +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdatePublishedOAuthAppIntegration(ctx context.Context, req *UpdatePublishedOAuthAppIntegrationRequest, opts ...call.Option) (*UpdatePublishedOAuthAppIntegrationResponse, error) { + wireReq, err := updatePublishedOAuthAppIntegrationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/oauth2/published-app-integrations/") + pb.singleSegment(*req.IntegrationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdatePublishedOAuthAppIntegrationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdatePublishedOAuthAppIntegrationResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/oauth/v1/genhelper.go b/oauth/v1/genhelper.go new file mode 100755 index 0000000..1f22dff --- /dev/null +++ b/oauth/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package oauth + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/oauth/v1/model.go b/oauth/v1/model.go new file mode 100755 index 0000000..74bc5ed --- /dev/null +++ b/oauth/v1/model.go @@ -0,0 +1,225 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package oauth + +type CreateCustomOAuthAppIntegrationRequest struct { + AccountId *string + // List of OAuth redirect urls + RedirectUrls []string + // Name of the custom OAuth app + Name *string + // This field indicates whether an OAuth client secret is required to + // authenticate this client. + Confidential *bool + // Token access policy + TokenAccessPolicy *TokenAccessPolicy + // OAuth scopes granted to the application. Supported scopes: all-apis, sql, + // offline_access, openid, profile, email. + Scopes []string + // Scopes that will need to be consented by end user to mint the access token. + // If the user does not authorize the access token will not be minted. Must be a + // subset of scopes. + UserAuthorizedScopes []string +} + +type CreatePublishedOAuthAppIntegrationRequest struct { + AccountId *string + // App id of the OAuth published app integration. For example power-bi, + // tableau-deskop + AppId *string + // Token access policy + TokenAccessPolicy *TokenAccessPolicy +} + +type CreatePublishedOAuthAppIntegrationResponse struct { + // Unique integration id for the published OAuth app + IntegrationId *string +} + +type CustomOAuthAppIntegration struct { + // ID of this custom app + IntegrationId *string + // The client id of the custom OAuth app + ClientId *string + // List of OAuth redirect urls + RedirectUrls []string + // The display name of the custom OAuth app + Name *string + // This field indicates whether an OAuth client secret is required to + // authenticate this client. + Confidential *bool + // Token access policy + TokenAccessPolicy *TokenAccessPolicy + Scopes []string + CreatedBy *int64 + CreateTime *string + CreatorUsername *string + // Scopes that will need to be consented by end user to mint the access token. + // If the user does not authorize the access token will not be minted. Must be a + // subset of scopes. + UserAuthorizedScopes []string +} + +type CustomOAuthAppIntegrationSecret struct { + // Unique integration id for the custom OAuth app + IntegrationId *string + // OAuth client-id generated by the + ClientId *string + // OAuth client-secret generated by the . If this is a confidential + // OAuth app client-secret will be generated. + ClientSecret *string +} + +type DeleteCustomOAuthAppIntegrationRequest struct { + AccountId *string + IntegrationId *string +} + +type DeleteCustomOAuthAppIntegrationResponse struct { +} + +type DeletePublishedOAuthAppIntegrationRequest struct { + AccountId *string + IntegrationId *string +} + +type DeletePublishedOAuthAppIntegrationResponse struct { +} + +type GetCustomOAuthAppIntegrationRequest struct { + // The account ID. + AccountId *string + // The OAuth app integration ID. + IntegrationId *string +} + +type GetPublishedOAuthAppIntegrationRequest struct { + AccountId *string + IntegrationId *string +} + +type ListCustomOAuthAppIntegrationsRequest struct { + AccountId *string + PageToken *string + PageSize *int + IncludeCreatorUsername *bool +} + +type ListCustomOAuthAppIntegrationsResponse struct { + // List of Custom OAuth App Integrations defined for the account. + Apps []CustomOAuthAppIntegration + NextPageToken *string +} + +type ListPublishedOAuthAppIntegrationsRequest struct { + AccountId *string + PageToken *string + PageSize *int +} + +type ListPublishedOAuthAppIntegrationsResponse struct { + // List of Published OAuth App Integrations defined for the account. + Apps []PublishedOAuthAppIntegration + NextPageToken *string +} + +type ListPublishedOAuthAppsRequest struct { + // The account ID. + AccountId *string + // A token that can be used to get the next page of results. + PageToken *string + // The max number of OAuth published apps to return in one page. + PageSize *int +} + +type ListPublishedOAuthAppsResponse struct { + // List of Published OAuth Apps. + Apps []PublishedOAuthApp + // A token that can be used to get the next page of results. If not present, + // there are no more results to show. + NextPageToken *string +} + +type PublishedOAuthApp struct { + // Unique ID of the published OAuth app. + AppId *string + // Client ID of the published OAuth app. It is the client_id in the OAuth flow + ClientId *string + // The display name of the published OAuth app. + Name *string + // Description of the published OAuth app. + Description *string + // Whether the published OAuth app is a confidential client. It is always false + // for published OAuth apps. + IsConfidentialClient *bool + // Redirect URLs of the published OAuth app. + RedirectUrls []string + // Required scopes for the published OAuth app. + Scopes []string +} + +type PublishedOAuthAppIntegration struct { + // App-id of the published app integration + AppId *string + // Unique integration id for the published OAuth app + IntegrationId *string + // Display name of the published OAuth app + Name *string + // Token access policy + TokenAccessPolicy *TokenAccessPolicy + CreatedBy *int64 + CreateTime *string +} + +type TokenAccessPolicy struct { + // access token time to live in minutes + AccessTokenTtlInMinutes *int + // Refresh token time to live in minutes. When single-use refresh tokens are + // enabled, this represents the TTL of an individual refresh token. If the + // refresh token is used before it expires, a new one is issued with a renewed + // individual TTL. + RefreshTokenTtlInMinutes *int + // Whether to enable single-use refresh tokens (refresh token rotation). If this + // feature is enabled, upon successfully getting a new access token using a + // refresh token, will issue a new refresh token along with the + // access token in the response and invalidate the old refresh token. The client + // should use the new refresh token to get access tokens in future requests. + EnableSingleUseRefreshTokens *bool + // Absolute OAuth session TTL in minutes. Effective only when the single-use + // refresh token feature is enabled. This is the absolute TTL of all refresh + // tokens issued in one OAuth session. When a new refresh token is issued during + // refresh token rotation, it will inherit the same absolute TTL as the old + // refresh token. In other words, this represents the maximum amount of time a + // user can stay logged in without re-authenticating. + AbsoluteSessionLifetimeInMinutes *int +} + +type UpdateCustomOAuthAppIntegrationRequest struct { + AccountId *string + IntegrationId *string + // List of OAuth redirect urls to be updated in the custom OAuth app integration + RedirectUrls []string + // Token access policy to be updated in the custom OAuth app integration + TokenAccessPolicy *TokenAccessPolicy + // List of OAuth scopes to be updated in the custom OAuth app integration, + // similar to redirect URIs this will fully replace the existing values instead + // of appending + Scopes []string + // Scopes that will need to be consented by end user to mint the access token. + // If the user does not authorize the access token will not be minted. Must be a + // subset of scopes. + UserAuthorizedScopes []string +} + +type UpdateCustomOAuthAppIntegrationResponse struct { +} + +type UpdatePublishedOAuthAppIntegrationRequest struct { + AccountId *string + IntegrationId *string + // Token access policy to be updated in the published OAuth app integration + TokenAccessPolicy *TokenAccessPolicy +} + +type UpdatePublishedOAuthAppIntegrationResponse struct { +} diff --git a/oauth/v1/wire.go b/oauth/v1/wire.go new file mode 100755 index 0000000..b3852a2 --- /dev/null +++ b/oauth/v1/wire.go @@ -0,0 +1,380 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package oauth + +import ( + "fmt" +) + +type createCustomOAuthAppIntegrationRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + RedirectUrls []string `json:"redirect_urls,omitempty"` + Name *string `json:"name,omitempty"` + Confidential *bool `json:"confidential,omitempty"` + TokenAccessPolicy *tokenAccessPolicyWire `json:"token_access_policy,omitempty"` + Scopes []string `json:"scopes,omitempty"` + UserAuthorizedScopes []string `json:"user_authorized_scopes,omitempty"` +} + +func createCustomOAuthAppIntegrationRequestToWire(v *CreateCustomOAuthAppIntegrationRequest) (*createCustomOAuthAppIntegrationRequestWire, error) { + if v == nil { + return nil, nil + } + tokenAccessPolicyWireValue, err := tokenAccessPolicyToWire(v.TokenAccessPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCustomOAuthAppIntegrationRequest.TokenAccessPolicy", err) + } + return &createCustomOAuthAppIntegrationRequestWire{ + AccountId: v.AccountId, + RedirectUrls: v.RedirectUrls, + Name: v.Name, + Confidential: v.Confidential, + TokenAccessPolicy: tokenAccessPolicyWireValue, + Scopes: v.Scopes, + UserAuthorizedScopes: v.UserAuthorizedScopes, + }, nil +} + +type createPublishedOAuthAppIntegrationRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + AppId *string `json:"app_id,omitempty"` + TokenAccessPolicy *tokenAccessPolicyWire `json:"token_access_policy,omitempty"` +} + +func createPublishedOAuthAppIntegrationRequestToWire(v *CreatePublishedOAuthAppIntegrationRequest) (*createPublishedOAuthAppIntegrationRequestWire, error) { + if v == nil { + return nil, nil + } + tokenAccessPolicyWireValue, err := tokenAccessPolicyToWire(v.TokenAccessPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePublishedOAuthAppIntegrationRequest.TokenAccessPolicy", err) + } + return &createPublishedOAuthAppIntegrationRequestWire{ + AccountId: v.AccountId, + AppId: v.AppId, + TokenAccessPolicy: tokenAccessPolicyWireValue, + }, nil +} + +type createPublishedOAuthAppIntegrationResponseWire struct { + IntegrationId *string `json:"integration_id,omitempty"` +} + +func createPublishedOAuthAppIntegrationResponseFromWire(w *createPublishedOAuthAppIntegrationResponseWire) (*CreatePublishedOAuthAppIntegrationResponse, error) { + if w == nil { + return nil, nil + } + return &CreatePublishedOAuthAppIntegrationResponse{ + IntegrationId: w.IntegrationId, + }, nil +} + +type customOAuthAppIntegrationWire struct { + IntegrationId *string `json:"integration_id,omitempty"` + ClientId *string `json:"client_id,omitempty"` + RedirectUrls []string `json:"redirect_urls,omitempty"` + Name *string `json:"name,omitempty"` + Confidential *bool `json:"confidential,omitempty"` + TokenAccessPolicy *tokenAccessPolicyWire `json:"token_access_policy,omitempty"` + Scopes []string `json:"scopes,omitempty"` + CreatedBy *int64 `json:"created_by,omitempty"` + CreateTime *string `json:"create_time,omitempty"` + CreatorUsername *string `json:"creator_username,omitempty"` + UserAuthorizedScopes []string `json:"user_authorized_scopes,omitempty"` +} + +func customOAuthAppIntegrationFromWire(w *customOAuthAppIntegrationWire) (*CustomOAuthAppIntegration, error) { + if w == nil { + return nil, nil + } + tokenAccessPolicyPublicValue, err := tokenAccessPolicyFromWire(w.TokenAccessPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CustomOAuthAppIntegration.TokenAccessPolicy", err) + } + return &CustomOAuthAppIntegration{ + IntegrationId: w.IntegrationId, + ClientId: w.ClientId, + RedirectUrls: w.RedirectUrls, + Name: w.Name, + Confidential: w.Confidential, + TokenAccessPolicy: tokenAccessPolicyPublicValue, + Scopes: w.Scopes, + CreatedBy: w.CreatedBy, + CreateTime: w.CreateTime, + CreatorUsername: w.CreatorUsername, + UserAuthorizedScopes: w.UserAuthorizedScopes, + }, nil +} + +type customOAuthAppIntegrationSecretWire struct { + IntegrationId *string `json:"integration_id,omitempty"` + ClientId *string `json:"client_id,omitempty"` + ClientSecret *string `json:"client_secret,omitempty"` +} + +func customOAuthAppIntegrationSecretFromWire(w *customOAuthAppIntegrationSecretWire) (*CustomOAuthAppIntegrationSecret, error) { + if w == nil { + return nil, nil + } + return &CustomOAuthAppIntegrationSecret{ + IntegrationId: w.IntegrationId, + ClientId: w.ClientId, + ClientSecret: w.ClientSecret, + }, nil +} + +type listCustomOAuthAppIntegrationsRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` + IncludeCreatorUsername *bool `json:"include_creator_username,omitempty"` +} + +func listCustomOAuthAppIntegrationsRequestToWire(v *ListCustomOAuthAppIntegrationsRequest) (*listCustomOAuthAppIntegrationsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCustomOAuthAppIntegrationsRequestWire{ + AccountId: v.AccountId, + PageToken: v.PageToken, + PageSize: v.PageSize, + IncludeCreatorUsername: v.IncludeCreatorUsername, + }, nil +} + +type listCustomOAuthAppIntegrationsResponseWire struct { + Apps []customOAuthAppIntegrationWire `json:"apps,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCustomOAuthAppIntegrationsResponseFromWire(w *listCustomOAuthAppIntegrationsResponseWire) (*ListCustomOAuthAppIntegrationsResponse, error) { + if w == nil { + return nil, nil + } + appsPublicValue, err := convertSlice(w.Apps, customOAuthAppIntegrationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCustomOAuthAppIntegrationsResponse.Apps", err) + } + return &ListCustomOAuthAppIntegrationsResponse{ + Apps: appsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listPublishedOAuthAppIntegrationsRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listPublishedOAuthAppIntegrationsRequestToWire(v *ListPublishedOAuthAppIntegrationsRequest) (*listPublishedOAuthAppIntegrationsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listPublishedOAuthAppIntegrationsRequestWire{ + AccountId: v.AccountId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listPublishedOAuthAppIntegrationsResponseWire struct { + Apps []publishedOAuthAppIntegrationWire `json:"apps,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listPublishedOAuthAppIntegrationsResponseFromWire(w *listPublishedOAuthAppIntegrationsResponseWire) (*ListPublishedOAuthAppIntegrationsResponse, error) { + if w == nil { + return nil, nil + } + appsPublicValue, err := convertSlice(w.Apps, publishedOAuthAppIntegrationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPublishedOAuthAppIntegrationsResponse.Apps", err) + } + return &ListPublishedOAuthAppIntegrationsResponse{ + Apps: appsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listPublishedOAuthAppsRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listPublishedOAuthAppsRequestToWire(v *ListPublishedOAuthAppsRequest) (*listPublishedOAuthAppsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listPublishedOAuthAppsRequestWire{ + AccountId: v.AccountId, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listPublishedOAuthAppsResponseWire struct { + Apps []publishedOAuthAppWire `json:"apps,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listPublishedOAuthAppsResponseFromWire(w *listPublishedOAuthAppsResponseWire) (*ListPublishedOAuthAppsResponse, error) { + if w == nil { + return nil, nil + } + appsPublicValue, err := convertSlice(w.Apps, publishedOAuthAppFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPublishedOAuthAppsResponse.Apps", err) + } + return &ListPublishedOAuthAppsResponse{ + Apps: appsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type publishedOAuthAppWire struct { + AppId *string `json:"app_id,omitempty"` + ClientId *string `json:"client_id,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + IsConfidentialClient *bool `json:"is_confidential_client,omitempty"` + RedirectUrls []string `json:"redirect_urls,omitempty"` + Scopes []string `json:"scopes,omitempty"` +} + +func publishedOAuthAppFromWire(w *publishedOAuthAppWire) (*PublishedOAuthApp, error) { + if w == nil { + return nil, nil + } + return &PublishedOAuthApp{ + AppId: w.AppId, + ClientId: w.ClientId, + Name: w.Name, + Description: w.Description, + IsConfidentialClient: w.IsConfidentialClient, + RedirectUrls: w.RedirectUrls, + Scopes: w.Scopes, + }, nil +} + +type publishedOAuthAppIntegrationWire struct { + AppId *string `json:"app_id,omitempty"` + IntegrationId *string `json:"integration_id,omitempty"` + Name *string `json:"name,omitempty"` + TokenAccessPolicy *tokenAccessPolicyWire `json:"token_access_policy,omitempty"` + CreatedBy *int64 `json:"created_by,omitempty"` + CreateTime *string `json:"create_time,omitempty"` +} + +func publishedOAuthAppIntegrationFromWire(w *publishedOAuthAppIntegrationWire) (*PublishedOAuthAppIntegration, error) { + if w == nil { + return nil, nil + } + tokenAccessPolicyPublicValue, err := tokenAccessPolicyFromWire(w.TokenAccessPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PublishedOAuthAppIntegration.TokenAccessPolicy", err) + } + return &PublishedOAuthAppIntegration{ + AppId: w.AppId, + IntegrationId: w.IntegrationId, + Name: w.Name, + TokenAccessPolicy: tokenAccessPolicyPublicValue, + CreatedBy: w.CreatedBy, + CreateTime: w.CreateTime, + }, nil +} + +type tokenAccessPolicyWire struct { + AccessTokenTtlInMinutes *int `json:"access_token_ttl_in_minutes,omitempty"` + RefreshTokenTtlInMinutes *int `json:"refresh_token_ttl_in_minutes,omitempty"` + EnableSingleUseRefreshTokens *bool `json:"enable_single_use_refresh_tokens,omitempty"` + AbsoluteSessionLifetimeInMinutes *int `json:"absolute_session_lifetime_in_minutes,omitempty"` +} + +func tokenAccessPolicyToWire(v *TokenAccessPolicy) (*tokenAccessPolicyWire, error) { + if v == nil { + return nil, nil + } + return &tokenAccessPolicyWire{ + AccessTokenTtlInMinutes: v.AccessTokenTtlInMinutes, + RefreshTokenTtlInMinutes: v.RefreshTokenTtlInMinutes, + EnableSingleUseRefreshTokens: v.EnableSingleUseRefreshTokens, + AbsoluteSessionLifetimeInMinutes: v.AbsoluteSessionLifetimeInMinutes, + }, nil +} + +func tokenAccessPolicyFromWire(w *tokenAccessPolicyWire) (*TokenAccessPolicy, error) { + if w == nil { + return nil, nil + } + return &TokenAccessPolicy{ + AccessTokenTtlInMinutes: w.AccessTokenTtlInMinutes, + RefreshTokenTtlInMinutes: w.RefreshTokenTtlInMinutes, + EnableSingleUseRefreshTokens: w.EnableSingleUseRefreshTokens, + AbsoluteSessionLifetimeInMinutes: w.AbsoluteSessionLifetimeInMinutes, + }, nil +} + +type updateCustomOAuthAppIntegrationRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + IntegrationId *string `json:"integration_id,omitempty"` + RedirectUrls []string `json:"redirect_urls,omitempty"` + TokenAccessPolicy *tokenAccessPolicyWire `json:"token_access_policy,omitempty"` + Scopes []string `json:"scopes,omitempty"` + UserAuthorizedScopes []string `json:"user_authorized_scopes,omitempty"` +} + +func updateCustomOAuthAppIntegrationRequestToWire(v *UpdateCustomOAuthAppIntegrationRequest) (*updateCustomOAuthAppIntegrationRequestWire, error) { + if v == nil { + return nil, nil + } + tokenAccessPolicyWireValue, err := tokenAccessPolicyToWire(v.TokenAccessPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCustomOAuthAppIntegrationRequest.TokenAccessPolicy", err) + } + return &updateCustomOAuthAppIntegrationRequestWire{ + AccountId: v.AccountId, + IntegrationId: v.IntegrationId, + RedirectUrls: v.RedirectUrls, + TokenAccessPolicy: tokenAccessPolicyWireValue, + Scopes: v.Scopes, + UserAuthorizedScopes: v.UserAuthorizedScopes, + }, nil +} + +type updatePublishedOAuthAppIntegrationRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + IntegrationId *string `json:"integration_id,omitempty"` + TokenAccessPolicy *tokenAccessPolicyWire `json:"token_access_policy,omitempty"` +} + +func updatePublishedOAuthAppIntegrationRequestToWire(v *UpdatePublishedOAuthAppIntegrationRequest) (*updatePublishedOAuthAppIntegrationRequestWire, error) { + if v == nil { + return nil, nil + } + tokenAccessPolicyWireValue, err := tokenAccessPolicyToWire(v.TokenAccessPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdatePublishedOAuthAppIntegrationRequest.TokenAccessPolicy", err) + } + return &updatePublishedOAuthAppIntegrationRequestWire{ + AccountId: v.AccountId, + IntegrationId: v.IntegrationId, + TokenAccessPolicy: tokenAccessPolicyWireValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/options/.package.json b/options/.package.json new file mode 100644 index 0000000..be7c8cc --- /dev/null +++ b/options/.package.json @@ -0,0 +1,3 @@ +{ + "package": "options" +} diff --git a/options/CHANGELOG.md b/options/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/options/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/options/call/call.go b/options/call/call.go index b89b231..738d28a 100644 --- a/options/call/call.go +++ b/options/call/call.go @@ -9,7 +9,8 @@ import ( "github.com/databricks/sdk-go/options/internaloptions" ) -// Option configures a single call against the Databricks API. +// Option configures a single call against the Databricks API. If multiple +// options configure the same setting, the last option takes precedence. type Option func(*internaloptions.CallOptions) error // WithRetrier returns an Option that uses the given Retrier provider. If no diff --git a/options/go.mod b/options/go.mod index d5f098c..b05da62 100644 --- a/options/go.mod +++ b/options/go.mod @@ -8,13 +8,14 @@ replace ( ) require ( - github.com/databricks/sdk-go/auth v0.0.0-dev - github.com/databricks/sdk-go/core v0.0.1-dev + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/oauth2 v0.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/options/go.sum b/options/go.sum index c2faf5a..2b9bf4b 100644 --- a/options/go.sum +++ b/options/go.sum @@ -6,6 +6,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/options/internal/version.go b/options/internal/version.go index ab946dc..8f6636e 100644 --- a/options/internal/version.go +++ b/options/internal/version.go @@ -2,4 +2,4 @@ package internal const ModuleName = "sdk-go-options" -const Version = "0.0.0-dev" +const Version = "0.0.1-dev.1" diff --git a/options/internaloptions/internaloptions.go b/options/internaloptions/internaloptions.go index 87ba2d2..bd483da 100644 --- a/options/internaloptions/internaloptions.go +++ b/options/internaloptions/internaloptions.go @@ -14,6 +14,7 @@ import ( "time" "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/auth/credentials" "github.com/databricks/sdk-go/core/ops" "github.com/databricks/sdk-go/core/profiles" ) @@ -62,15 +63,12 @@ func (c *ClientOptions) Resolve() error { // resolve fills unset options from the profile. Explicitly set options take // precedence and are never overwritten. -// -// TODO: Apply environment-variable overrides, and resolve workspace/account ID -// and credentials from the profile when not provided. func (c *ClientOptions) resolve() error { if c.DisableProfileResolution { return nil } - var opts []profiles.ResolveOption + opts := []profiles.ResolveOption{profiles.WithEnv()} if c.ProfileName != "" { opts = append(opts, profiles.WithProfile(c.ProfileName)) } else { @@ -94,6 +92,9 @@ func (c *ClientOptions) resolve() error { if c.WorkspaceID == "" { c.WorkspaceID = p.WorkspaceID } + if c.Credentials == nil { + c.Credentials = credentials.NewDefaultCredentials(credentials.DefaultCredentialsOptions{Profile: p}) + } return nil } @@ -111,3 +112,9 @@ type CallOptions struct { RateLimiter ops.Limiter Timeout time.Duration } + +// LROOptions is the resolved configuration produced by applying lro.Option +// values to a long-running operation wait. +type LROOptions struct { + Timeout time.Duration +} diff --git a/options/internaloptions/internaloptions_test.go b/options/internaloptions/internaloptions_test.go index 744c591..5d555cd 100644 --- a/options/internaloptions/internaloptions_test.go +++ b/options/internaloptions/internaloptions_test.go @@ -3,6 +3,8 @@ package internaloptions import ( "context" "log/slog" + "os" + "path/filepath" "testing" "github.com/databricks/sdk-go/auth" @@ -16,6 +18,30 @@ func (stubCredentials) Name() string { return "stub" } func (stubCredentials) AuthHeaders(context.Context) ([]auth.Header, error) { return nil, nil } +// isolateProfileEnv points profile resolution at a temp config file and clears +// the environment variables that could otherwise leak the developer's real +// credentials into the test. +func isolateProfileEnv(t *testing.T) { + t.Helper() + t.Setenv("HOME", t.TempDir()) + for _, v := range []string{ + "DATABRICKS_CONFIG_FILE", "DATABRICKS_CONFIG_PROFILE", "DATABRICKS_HOST", + "DATABRICKS_TOKEN", "DATABRICKS_CLIENT_ID", "DATABRICKS_CLIENT_SECRET", + "DATABRICKS_AUTH_TYPE", + } { + t.Setenv(v, "") + } +} + +func writeConfigFile(t *testing.T, contents string) string { + t.Helper() + path := filepath.Join(t.TempDir(), "databrickscfg") + if err := os.WriteFile(path, []byte(contents), 0600); err != nil { + t.Fatalf("writing config file: %v", err) + } + return path +} + func TestClientOptionsResolve_DefaultLogger(t *testing.T) { c := &ClientOptions{Credentials: stubCredentials{}} if err := c.Resolve(); err != nil { @@ -39,3 +65,135 @@ func TestClientOptionsResolve_PreservesProvidedLogger(t *testing.T) { t.Fatal("expected provided logger to be preserved") } } + +func TestClientOptionsResolve_DefaultCredentialsFromProfile(t *testing.T) { + isolateProfileEnv(t) + path := writeConfigFile(t, "[DEFAULT]\nhost = https://workspace.example\ntoken = dapi-abc\n") + + c := &ClientOptions{ProfileFile: path} + if err := c.Resolve(); err != nil { + t.Fatalf("Resolve: %v", err) + } + if c.Credentials == nil { + t.Fatal("expected credentials to be resolved from the profile") + } + // The PAT strategy should have won, and its header should carry the token. + headers, err := c.Credentials.AuthHeaders(context.Background()) + if err != nil { + t.Fatalf("AuthHeaders: %v", err) + } + want := []auth.Header{{Key: "Authorization", Value: "Bearer dapi-abc"}} + if len(headers) != 1 || headers[0] != want[0] { + t.Errorf("AuthHeaders() = %v, want %v", headers, want) + } +} + +func TestClientOptionsResolve_PreservesProvidedCredentials(t *testing.T) { + isolateProfileEnv(t) + path := writeConfigFile(t, "[DEFAULT]\nhost = https://workspace.example\ntoken = dapi-abc\n") + + provided := stubCredentials{} + c := &ClientOptions{ProfileFile: path, Credentials: provided} + if err := c.Resolve(); err != nil { + t.Fatalf("Resolve: %v", err) + } + if c.Credentials != auth.Credentials(provided) { + t.Error("expected explicitly provided credentials to be preserved") + } +} + +func TestClientOptionsResolve_NoCredentialsWithoutProfileResolution(t *testing.T) { + isolateProfileEnv(t) + + c := &ClientOptions{DisableProfileResolution: true} + err := c.Resolve() + if err == nil { + t.Fatal("expected an error when no credentials are available and resolution is disabled") + } +} + +func TestClientOptionsResolve_ProfilePrecedence(t *testing.T) { + testCases := []struct { + name string + configFileContents string + envHost string + envAccountID string + envWorkspaceID string + clientOptions ClientOptions + wantHost string + wantAccountID string + wantWorkspaceID string + }{ + { + name: "environment fills unset options", + envHost: "https://env.example.com", + envAccountID: "env-account", + envWorkspaceID: "env-workspace", + wantHost: "https://env.example.com", + wantAccountID: "env-account", + wantWorkspaceID: "env-workspace", + }, + { + name: "environment overrides config file values", + configFileContents: "[DEFAULT]\nhost = https://profile.example.com\naccount_id = profile-account\nworkspace_id = profile-workspace\n", + envHost: "https://env.example.com", + envAccountID: "env-account", + envWorkspaceID: "env-workspace", + wantHost: "https://env.example.com", + wantAccountID: "env-account", + wantWorkspaceID: "env-workspace", + }, + { + name: "explicit options override environment", + envHost: "https://env.example.com", + envAccountID: "env-account", + envWorkspaceID: "env-workspace", + clientOptions: ClientOptions{ + Host: "https://explicit.example.com", + AccountID: "explicit-account", + WorkspaceID: "explicit-workspace", + }, + wantHost: "https://explicit.example.com", + wantAccountID: "explicit-account", + wantWorkspaceID: "explicit-workspace", + }, + { + name: "disabled profile resolution ignores environment", + envHost: "https://env.example.com", + envAccountID: "env-account", + envWorkspaceID: "env-workspace", + clientOptions: ClientOptions{ + DisableProfileResolution: true, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Setenv("HOME", t.TempDir()) + t.Setenv("DATABRICKS_CONFIG_FILE", "") + t.Setenv("DATABRICKS_CONFIG_PROFILE", "") + t.Setenv("DATABRICKS_HOST", tc.envHost) + t.Setenv("DATABRICKS_ACCOUNT_ID", tc.envAccountID) + t.Setenv("DATABRICKS_WORKSPACE_ID", tc.envWorkspaceID) + + options := tc.clientOptions + options.Credentials = stubCredentials{} + if tc.configFileContents != "" { + options.ProfileFile = writeConfigFile(t, tc.configFileContents) + } + if err := options.Resolve(); err != nil { + t.Fatalf("Resolve: %v", err) + } + if options.Host != tc.wantHost { + t.Errorf("Host = %q, want %q", options.Host, tc.wantHost) + } + if options.AccountID != tc.wantAccountID { + t.Errorf("AccountID = %q, want %q", options.AccountID, tc.wantAccountID) + } + if options.WorkspaceID != tc.wantWorkspaceID { + t.Errorf("WorkspaceID = %q, want %q", options.WorkspaceID, tc.wantWorkspaceID) + } + }) + } +} diff --git a/options/lro/lro.go b/options/lro/lro.go new file mode 100644 index 0000000..dff16ce --- /dev/null +++ b/options/lro/lro.go @@ -0,0 +1,23 @@ +// Package lro defines options used to wait for long-running operations. +package lro + +import ( + "time" + + "github.com/databricks/sdk-go/options/internaloptions" +) + +// Option configures a wait for a long-running operation. +type Option func(*internaloptions.LROOptions) error + +// WithTimeout returns an Option that limits the complete wait, including every +// polling attempt. When the context already has a deadline, the earlier +// deadline applies. A zero duration removes a timeout set by an earlier Option. +// After all options are applied, a final negative duration returns an error +// before polling begins. +func WithTimeout(timeout time.Duration) Option { + return func(options *internaloptions.LROOptions) error { + options.Timeout = timeout + return nil + } +} diff --git a/options/lro/lro_test.go b/options/lro/lro_test.go new file mode 100644 index 0000000..b6bb6e5 --- /dev/null +++ b/options/lro/lro_test.go @@ -0,0 +1,59 @@ +package lro + +import ( + "testing" + "time" + + "github.com/databricks/sdk-go/options/internaloptions" +) + +func TestWithTimeout(t *testing.T) { + testCases := []struct { + name string + timeouts []time.Duration + wantTimeout time.Duration + }{ + { + name: "unset", + }, + { + name: "positive", + timeouts: []time.Duration{3 * time.Second}, + wantTimeout: 3 * time.Second, + }, + { + name: "later positive overrides earlier timeout", + timeouts: []time.Duration{3 * time.Second, 5 * time.Second}, + wantTimeout: 5 * time.Second, + }, + { + name: "zero clears earlier timeout", + timeouts: []time.Duration{3 * time.Second, 0}, + }, + { + name: "negative", + timeouts: []time.Duration{-time.Second}, + wantTimeout: -time.Second, + }, + { + name: "positive overrides earlier negative timeout", + timeouts: []time.Duration{-time.Second, 5 * time.Second}, + wantTimeout: 5 * time.Second, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + options := internaloptions.LROOptions{} + for _, timeout := range testCase.timeouts { + if err := WithTimeout(timeout)(&options); err != nil { + t.Fatalf("WithTimeout(): %v", err) + } + } + + if options.Timeout != testCase.wantTimeout { + t.Errorf("Timeout = %v, want %v", options.Timeout, testCase.wantTimeout) + } + }) + } +} diff --git a/pipelines/.package.json b/pipelines/.package.json new file mode 100644 index 0000000..68571b3 --- /dev/null +++ b/pipelines/.package.json @@ -0,0 +1,3 @@ +{ + "package": "pipelines" +} diff --git a/pipelines/CHANGELOG.md b/pipelines/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/pipelines/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/pipelines/README.md b/pipelines/README.md new file mode 100644 index 0000000..dfa9769 --- /dev/null +++ b/pipelines/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/pipelines + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/pipelines@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/pipelines/v2" + +client, err := pipelines.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/pipelines/go.mod b/pipelines/go.mod new file mode 100644 index 0000000..52ca071 --- /dev/null +++ b/pipelines/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/pipelines + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/pipelines/internal/version.go b/pipelines/internal/version.go new file mode 100644 index 0000000..b6f7e5b --- /dev/null +++ b/pipelines/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-pipelines" + +const Version = "0.0.1-dev.1" diff --git a/pipelines/v2/client.go b/pipelines/v2/client.go new file mode 100755 index 0000000..1a9a9f4 --- /dev/null +++ b/pipelines/v2/client.go @@ -0,0 +1,1064 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package pipelines + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" + "github.com/databricks/sdk-go/pipelines/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// * Applies the current pipeline environment onto the pipeline compute. The +// environment applied can be used by subsequent dev-mode updates. +func (c *internalClient) ApplyEnvironment(ctx context.Context, req *ApplyEnvironmentRequest, opts ...call.Option) (*ApplyEnvironmentResponse, error) { + wireReq, err := applyEnvironmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/pipelines/") + pb.singleSegment(*req.PipelineId) + pb.literal("/environment/apply") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ApplyEnvironmentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &ApplyEnvironmentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new pipeline using Unity Catalog from a pipeline using Hive +// Metastore. This method returns the ID of the newly created clone. +// Additionally, this method starts an update for the newly created pipeline. +func (c *internalClient) Clone(ctx context.Context, req *ClonePipelineRequest, opts ...call.Option) (*ClonePipelineResponse, error) { + wireReq, err := clonePipelineRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/pipelines/") + pb.singleSegment(*req.PipelineId) + pb.literal("/clone") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ClonePipelineResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp clonePipelineResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = clonePipelineResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new data processing pipeline based on the requested configuration. +// If successful, this method returns the ID of the new pipeline. +func (c *internalClient) Create(ctx context.Context, req *CreatePipelineRequest, opts ...call.Option) (*CreatePipelineResponse, error) { + wireReq, err := createPipelineRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/pipelines" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreatePipelineResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createPipelineResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createPipelineResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a pipeline. If the pipeline publishes to Unity Catalog, pipeline +// deletion will cascade to all pipeline tables. Please reach out to +// support for assistance to undo this action. +func (c *internalClient) Delete(ctx context.Context, req *DeletePipelineRequest, opts ...call.Option) (*DeletePipelineResponse, error) { + wireReq, err := deletePipelineRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/pipelines/") + pb.singleSegment(*req.PipelineId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "cascade", wireReq.Cascade); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeletePipelineResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeletePipelineResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a pipeline with the supplied configuration. +func (c *internalClient) Edit(ctx context.Context, req *EditPipelineRequest, opts ...call.Option) (*EditPipelineResponse, error) { + wireReq, err := editPipelineRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/pipelines/") + pb.singleSegment(*req.PipelineId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EditPipelineResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &EditPipelineResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves events for a pipeline. +func (c *internalClient) Events(ctx context.Context, req *ListPipelineEventsRequest, opts ...call.Option) (*ListPipelineEventsResponse, error) { + wireReq, err := listPipelineEventsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/pipelines/") + pb.singleSegment(*req.PipelineId) + pb.literal("/events") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "order_by", wireReq.OrderBy); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPipelineEventsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listPipelineEventsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listPipelineEventsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// EventsIter returns an iterator that iterates +// over the results of Events. +// +// For example: +// +// for item, err := range c.EventsIter(ctx, &ListPipelineEventsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each Events call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// Events directly. +func (c *internalClient) EventsIter(ctx context.Context, req *ListPipelineEventsRequest, opts ...call.Option) iter.Seq2[*PipelineEvent, error] { + return func(yield func(*PipelineEvent, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListPipelineEventsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.Events(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Events { + if !yield(&resp.Events[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get a pipeline. +func (c *internalClient) Get(ctx context.Context, req *GetPipelineRequest, opts ...call.Option) (*GetPipelineResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/pipelines/") + pb.singleSegment(*req.PipelineId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPipelineResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPipelineResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPipelineResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an update from an active pipeline. +func (c *internalClient) GetUpdate(ctx context.Context, req *GetUpdateRequest, opts ...call.Option) (*GetUpdateResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/pipelines/") + pb.singleSegment(*req.PipelineId) + pb.literal("/updates/") + pb.singleSegment(*req.UpdateId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetUpdateResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getUpdateResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getUpdateResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists pipelines defined in the Spark Declarative Pipelines system. +func (c *internalClient) List(ctx context.Context, req *ListPipelinesRequest, opts ...call.Option) (*ListPipelinesResponse, error) { + wireReq, err := listPipelinesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/pipelines" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "order_by", wireReq.OrderBy); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPipelinesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listPipelinesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listPipelinesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListIter returns an iterator that iterates +// over the results of List. +// +// For example: +// +// for item, err := range c.ListIter(ctx, &ListPipelinesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each List call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// List directly. +func (c *internalClient) ListIter(ctx context.Context, req *ListPipelinesRequest, opts ...call.Option) iter.Seq2[*PipelineStateInfo, error] { + return func(yield func(*PipelineStateInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListPipelinesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.List(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Statuses { + if !yield(&resp.Statuses[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List updates for an active pipeline. +func (c *internalClient) ListUpdates(ctx context.Context, req *ListUpdatesRequest, opts ...call.Option) (*ListUpdatesResponse, error) { + wireReq, err := listUpdatesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/pipelines/") + pb.singleSegment(*req.PipelineId) + pb.literal("/updates") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "until_update_id", wireReq.UntilUpdateId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListUpdatesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listUpdatesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listUpdatesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Starts a new update for the pipeline. If there is already an active update +// for the pipeline, the request will fail and the active update will remain +// running. +func (c *internalClient) Start(ctx context.Context, req *StartUpdateRequest, opts ...call.Option) (*StartUpdateResponse, error) { + wireReq, err := startUpdateRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/pipelines/") + pb.singleSegment(*req.PipelineId) + pb.literal("/updates") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StartUpdateResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp startUpdateResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = startUpdateResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Stops the pipeline by canceling the active update. If there is no active +// update for the pipeline, this request is a no-op. +func (c *internalClient) stopBase(ctx context.Context, req *StopPipelineRequest, opts ...call.Option) (*StopPipelineResponse, error) { + wireReq, err := stopPipelineRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/pipelines/") + pb.singleSegment(*req.PipelineId) + pb.literal("/stop") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StopPipelineResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &StopPipelineResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Stops the pipeline by canceling the active update. If there is no active +// update for the pipeline, this request is a no-op. +func (c *internalClient) Stop(ctx context.Context, req *StopPipelineRequest, opts ...call.Option) (*StopWaiter, error) { + if req.PipelineId == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "PipelineId") + } + capturedPipelineId := *req.PipelineId + _, err := c.stopBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &StopWaiter{ + poll: c.Get, + pipelineId: capturedPipelineId, + }, nil +} + +// StopWaiter tracks the state of the operation started by Stop. +type StopWaiter struct { + poll func(context.Context, *GetPipelineRequest, ...call.Option) (*GetPipelineResponse, error) + pipelineId string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *StopWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetPipelineRequest{ + PipelineId: &w.pipelineId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case PipelineState_PipelineState_Idle, PipelineState_PipelineState_Failed: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *StopWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetPipelineResponse, error) { + var result *GetPipelineResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetPipelineRequest{ + PipelineId: &w.pipelineId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case PipelineState_PipelineState_Idle: + result = pollResp + return nil + case PipelineState_PipelineState_Failed: + message := "(no message)" + if pollResp.Cause != nil { + message = fmt.Sprintf("%v", *pollResp.Cause) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} diff --git a/pipelines/v2/genhelper.go b/pipelines/v2/genhelper.go new file mode 100755 index 0000000..275146b --- /dev/null +++ b/pipelines/v2/genhelper.go @@ -0,0 +1,243 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package pipelines + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/pipelines/v2/model.go b/pipelines/v2/model.go new file mode 100755 index 0000000..565db34 --- /dev/null +++ b/pipelines/v2/model.go @@ -0,0 +1,2835 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package pipelines + +// Enum to specify which mode of clone to execute +type CloneMode string + +const ( + CloneMode_Unspecified CloneMode = "" + // Data and metadata are copied + CloneMode_MigrateToUc CloneMode = "MIGRATE_TO_UC" +) + +// For certain database sources LakeFlow Connect offers both query based and cdc +// ingestion, ConnectorType can bse used to convey the type of ingestion. If +// connection_name is provided for database sources, we default to Query Based +// ingestion +type ConnectorType string + +const ( + ConnectorType_Unspecified ConnectorType = "" + // If connector_type = CDC and ingestion_gateway_id is provided then we use + // Ingestion Gateway pipeline with Cdc Managed Ingestion Pipeline for ingestion, + // if connector_type = CDC and connection_name is provided then we use Combined + // Cdc Managed Ingestion Pipeline. + ConnectorType_Cdc ConnectorType = "CDC" + ConnectorType_QueryBased ConnectorType = "QUERY_BASED" +) + +// Days of week in which the window is allowed to happen. If not specified all +// days of the week will be used. +type DayOfWeek string + +const ( + DayOfWeek_Unspecified DayOfWeek = "" + DayOfWeek_Monday DayOfWeek = "MONDAY" + DayOfWeek_Tuesday DayOfWeek = "TUESDAY" + DayOfWeek_Wednesday DayOfWeek = "WEDNESDAY" + DayOfWeek_Thursday DayOfWeek = "THURSDAY" + DayOfWeek_Friday DayOfWeek = "FRIDAY" + DayOfWeek_Saturday DayOfWeek = "SATURDAY" + DayOfWeek_Sunday DayOfWeek = "SUNDAY" +) + +// The deployment method that manages the pipeline: - BUNDLE: The pipeline is +// managed by a Databricks Asset Bundle. +type DeploymentKind string + +const ( + DeploymentKind_Unspecified DeploymentKind = "" + // Databricks Asset Bundle (DAB) + DeploymentKind_Bundle DeploymentKind = "BUNDLE" +) + +// The severity level of the event. +type EventLevel string + +const ( + EventLevel_Unspecified EventLevel = "" + EventLevel_Info EventLevel = "INFO" + EventLevel_Warn EventLevel = "WARN" + EventLevel_Error EventLevel = "ERROR" + EventLevel_Metrics EventLevel = "METRICS" +) + +type IngestionSourceType string + +const ( + IngestionSourceType_Unspecified IngestionSourceType = "" + IngestionSourceType_Mysql IngestionSourceType = "MYSQL" + IngestionSourceType_Postgresql IngestionSourceType = "POSTGRESQL" + IngestionSourceType_Sqlserver IngestionSourceType = "SQLSERVER" + IngestionSourceType_Salesforce IngestionSourceType = "SALESFORCE" + IngestionSourceType_Bigquery IngestionSourceType = "BIGQUERY" + IngestionSourceType_Netsuite IngestionSourceType = "NETSUITE" + IngestionSourceType_WorkdayRaas IngestionSourceType = "WORKDAY_RAAS" + IngestionSourceType_Ga4RawData IngestionSourceType = "GA4_RAW_DATA" + IngestionSourceType_Servicenow IngestionSourceType = "SERVICENOW" + IngestionSourceType_ManagedPostgresql IngestionSourceType = "MANAGED_POSTGRESQL" + IngestionSourceType_Oracle IngestionSourceType = "ORACLE" + IngestionSourceType_Teradata IngestionSourceType = "TERADATA" + IngestionSourceType_Sharepoint IngestionSourceType = "SHAREPOINT" + IngestionSourceType_Dynamics365 IngestionSourceType = "DYNAMICS365" + IngestionSourceType_GoogleDrive IngestionSourceType = "GOOGLE_DRIVE" + IngestionSourceType_Jira IngestionSourceType = "JIRA" + IngestionSourceType_Confluence IngestionSourceType = "CONFLUENCE" + IngestionSourceType_MetaMarketing IngestionSourceType = "META_MARKETING" + IngestionSourceType_Zendesk IngestionSourceType = "ZENDESK" + IngestionSourceType_ForeignCatalog IngestionSourceType = "FOREIGN_CATALOG" +) + +// Maturity level for EventDetails. +type MaturityLevel string + +const ( + MaturityLevel_Unspecified MaturityLevel = "" + MaturityLevel_Evolving MaturityLevel = "EVOLVING" + MaturityLevel_Deprecated MaturityLevel = "DEPRECATED" +) + +// Attachment behavior mode for Outlook ingestion +type OutlookAttachmentMode string + +const ( + OutlookAttachmentMode_Unspecified OutlookAttachmentMode = "" + // Ingest all attachments (both inline and non-inline) + OutlookAttachmentMode_All OutlookAttachmentMode = "ALL" + // Ingest only non-inline attachments (recommended to avoid corporate signature + // images) + OutlookAttachmentMode_NonInlineOnly OutlookAttachmentMode = "NON_INLINE_ONLY" + // Ingest only inline attachments + OutlookAttachmentMode_InlineOnly OutlookAttachmentMode = "INLINE_ONLY" + // Do not ingest any attachments + OutlookAttachmentMode_None OutlookAttachmentMode = "NONE" +) + +// Body format for Outlook email content +type OutlookBodyFormat string + +const ( + OutlookBodyFormat_Unspecified OutlookBodyFormat = "" + OutlookBodyFormat_TextHtml OutlookBodyFormat = "TEXT_HTML" + OutlookBodyFormat_TextPlain OutlookBodyFormat = "TEXT_PLAIN" +) + +// The health of a pipeline. +type PipelineHealthStatus string + +const ( + PipelineHealthStatus_Unspecified PipelineHealthStatus = "" + PipelineHealthStatus_Healthy PipelineHealthStatus = "HEALTHY" + PipelineHealthStatus_Unhealthy PipelineHealthStatus = "UNHEALTHY" +) + +// The set of AWS availability types supported when setting up nodes for a +// cluster. +type PipelinesAwsAvailability string + +const ( + PipelinesAwsAvailability_Unspecified PipelinesAwsAvailability = "" + // Use spot instances. + PipelinesAwsAvailability_Spot PipelinesAwsAvailability = "SPOT" + // Use on-demand instances. + PipelinesAwsAvailability_OnDemand PipelinesAwsAvailability = "ON_DEMAND" + // Preferably use spot instances, but fall back to on-demand instances if spot + // instances cannot be acquired (e.g., if AWS spot prices are too high). + PipelinesAwsAvailability_SpotWithFallback PipelinesAwsAvailability = "SPOT_WITH_FALLBACK" +) + +// The set of Azure availability types supported when setting up nodes for a +// cluster. +type PipelinesAzureAvailability string + +const ( + PipelinesAzureAvailability_Unspecified PipelinesAzureAvailability = "" + // Use spot instances. + PipelinesAzureAvailability_SpotAzure PipelinesAzureAvailability = "SPOT_AZURE" + // Use on-demand instances. + PipelinesAzureAvailability_OnDemandAzure PipelinesAzureAvailability = "ON_DEMAND_AZURE" + // Preferably use spot instances, but fall back to on-demand instances if spot + // instances cannot be acquired (e.g., if Azure is out of Quota). + PipelinesAzureAvailability_SpotWithFallbackAzure PipelinesAzureAvailability = "SPOT_WITH_FALLBACK_AZURE" +) + +// All EBS volume types that supports. See +// https://aws.amazon.com/ebs/details/ for details. +type PipelinesEbsVolumeType string + +const ( + PipelinesEbsVolumeType_Unspecified PipelinesEbsVolumeType = "" + // Provision extra storage using AWS gp2 EBS volumes. + PipelinesEbsVolumeType_GeneralPurposeSsd PipelinesEbsVolumeType = "GENERAL_PURPOSE_SSD" + // Provision extra storage using AWS st1 volumes. + PipelinesEbsVolumeType_ThroughputOptimizedHdd PipelinesEbsVolumeType = "THROUGHPUT_OPTIMIZED_HDD" +) + +// The set of GCP availability types supported when setting up nodes for a +// cluster (configurable only for executors). +type PipelinesGcpAvailability string + +const ( + PipelinesGcpAvailability_Unspecified PipelinesGcpAvailability = "" + PipelinesGcpAvailability_PreemptibleGcp PipelinesGcpAvailability = "PREEMPTIBLE_GCP" + PipelinesGcpAvailability_OnDemandGcp PipelinesGcpAvailability = "ON_DEMAND_GCP" + PipelinesGcpAvailability_PreemptibleWithFallbackGcp PipelinesGcpAvailability = "PREEMPTIBLE_WITH_FALLBACK_GCP" +) + +// Enum representing the publishing mode of a pipeline. +type PublishingMode string + +const ( + PublishingMode_Unspecified PublishingMode = "" + PublishingMode_LegacyPublishingMode PublishingMode = "LEGACY_PUBLISHING_MODE" + PublishingMode_DefaultPublishingMode PublishingMode = "DEFAULT_PUBLISHING_MODE" +) + +// What triggered this update. +type UpdateCause string + +const ( + UpdateCause_Unspecified UpdateCause = "" + // Started through an API call. + UpdateCause_ApiCall UpdateCause = "API_CALL" + // Started as a retry for a failed update. + UpdateCause_RetryOnFailure UpdateCause = "RETRY_ON_FAILURE" + // Started as a result of a service upgrade. + UpdateCause_ServiceUpgrade UpdateCause = "SERVICE_UPGRADE" + // Started as a result of a schema change. + UpdateCause_SchemaChange UpdateCause = "SCHEMA_CHANGE" + // Started by the Jobs service. + UpdateCause_JobTask UpdateCause = "JOB_TASK" + // Started by an action a user performed. + UpdateCause_UserAction UpdateCause = "USER_ACTION" + // Started for infrastructure maintenance reason. + UpdateCause_InfrastructureMaintenance UpdateCause = "INFRASTRUCTURE_MAINTENANCE" +) + +type UpdateMode string + +const ( + UpdateMode_Unspecified UpdateMode = "" + // continuous execution mode (regardless of whether the update was triggered by + // a continuous job or by a legacy continuous pipeline) + UpdateMode_Continuous UpdateMode = "CONTINUOUS" +) + +// The update state. +type UpdateState string + +const ( + UpdateState_Unspecified UpdateState = "" + // Update is waiting for previous update to finish. + UpdateState_Queued UpdateState = "QUEUED" + // Initial state of an update. + UpdateState_Created UpdateState = "CREATED" + // Update is waiting for clusters, jobs, or other resources. + UpdateState_WaitingForResources UpdateState = "WAITING_FOR_RESOURCES" + // Update is creating the dataflow graph. + UpdateState_Initializing UpdateState = "INITIALIZING" + // Update is resetting datasets and checkpoints to the beginning. + UpdateState_Resetting UpdateState = "RESETTING" + // If necessary, Update is creating tables or updating their schemas. + UpdateState_SettingUpTables UpdateState = "SETTING_UP_TABLES" + // Update is currently executing queries. + UpdateState_Running UpdateState = "RUNNING" + // Update is waiting for queries to shut down. + UpdateState_Stopping UpdateState = "STOPPING" + // Update is complete and all necessary resources are cleaned up. + UpdateState_Completed UpdateState = "COMPLETED" + // Update has run into an error that could not be recovered from. + UpdateState_Failed UpdateState = "FAILED" + // Update was canceled while it was running or queued. + UpdateState_Canceled UpdateState = "CANCELED" +) + +type FileIngestionOptions_FileFormat string + +const ( + FileIngestionOptions_FileFormat_Unspecified FileIngestionOptions_FileFormat = "" + FileIngestionOptions_FileFormat_Binaryfile FileIngestionOptions_FileFormat = "BINARYFILE" + FileIngestionOptions_FileFormat_Json FileIngestionOptions_FileFormat = "JSON" + FileIngestionOptions_FileFormat_Csv FileIngestionOptions_FileFormat = "CSV" + FileIngestionOptions_FileFormat_Xml FileIngestionOptions_FileFormat = "XML" + FileIngestionOptions_FileFormat_Excel FileIngestionOptions_FileFormat = "EXCEL" + FileIngestionOptions_FileFormat_Parquet FileIngestionOptions_FileFormat = "PARQUET" + FileIngestionOptions_FileFormat_Avro FileIngestionOptions_FileFormat = "AVRO" + FileIngestionOptions_FileFormat_Orc FileIngestionOptions_FileFormat = "ORC" +) + +// Based on +// https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#how-does-auto-loader-schema-evolution-work +type FileIngestionOptions_SchemaEvolutionMode string + +const ( + FileIngestionOptions_SchemaEvolutionMode_Unspecified FileIngestionOptions_SchemaEvolutionMode = "" + FileIngestionOptions_SchemaEvolutionMode_AddNewColumnsWithTypeWidening FileIngestionOptions_SchemaEvolutionMode = "ADD_NEW_COLUMNS_WITH_TYPE_WIDENING" + FileIngestionOptions_SchemaEvolutionMode_AddNewColumns FileIngestionOptions_SchemaEvolutionMode = "ADD_NEW_COLUMNS" + FileIngestionOptions_SchemaEvolutionMode_Rescue FileIngestionOptions_SchemaEvolutionMode = "RESCUE" + FileIngestionOptions_SchemaEvolutionMode_FailOnNewColumns FileIngestionOptions_SchemaEvolutionMode = "FAIL_ON_NEW_COLUMNS" + FileIngestionOptions_SchemaEvolutionMode_None FileIngestionOptions_SchemaEvolutionMode = "NONE" +) + +type GoogleDriveOptions_GoogleDriveEntityType string + +const ( + GoogleDriveOptions_GoogleDriveEntityType_Unspecified GoogleDriveOptions_GoogleDriveEntityType = "" + GoogleDriveOptions_GoogleDriveEntityType_File GoogleDriveOptions_GoogleDriveEntityType = "FILE" + GoogleDriveOptions_GoogleDriveEntityType_FileMetadata GoogleDriveOptions_GoogleDriveEntityType = "FILE_METADATA" + GoogleDriveOptions_GoogleDriveEntityType_Permission GoogleDriveOptions_GoogleDriveEntityType = "PERMISSION" +) + +// Entity pivot to group by. +type LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity string + +const ( + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity_Unspecified LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity = "" + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity_Campaign LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity = "CAMPAIGN" + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity_Creative LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity = "CREATIVE" + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity_CampaignGroup LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity = "CAMPAIGN_GROUP" +) + +// adAnalytics finder. Determines call shape, valid pivots, and metric +// requirements. +type LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder string + +const ( + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder_Unspecified LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder = "" + // exactly 1 pivot, customer metrics ("analytics") + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder_Analytics LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder = "ANALYTICS" + // 1-3 pivots, customer metrics ("statistics") + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder_Statistics LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder = "STATISTICS" + // 1-2 pivots (CAMPAIGN/CAMPAIGN_GROUP only), full revenue-metric struct + // ("attributedRevenueMetrics") + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder_AttributedRevenueMetrics LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder = "ATTRIBUTED_REVENUE_METRICS" +) + +// Time aggregation. Used by analytics/statistics; ignored for +// attributedRevenueMetrics. Defaults to DAILY when unspecified. +type LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity string + +const ( + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity_Unspecified LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity = "" + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity_All LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity = "ALL" + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity_Daily LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity = "DAILY" + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity_Monthly LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity = "MONTHLY" + LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity_Yearly LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity = "YEARLY" +) + +// The pipeline state. +type PipelineState_PipelineState string + +const ( + PipelineState_PipelineState_Unspecified PipelineState_PipelineState = "" + // Pipeline is being deployed and waiting for clusters, jobs, or other resources + PipelineState_PipelineState_Deploying PipelineState_PipelineState = "DEPLOYING" + // Pipeline is deployed but waiting for streams to start and make progress + PipelineState_PipelineState_Starting PipelineState_PipelineState = "STARTING" + // Pipeline is currently executing + PipelineState_PipelineState_Running PipelineState_PipelineState = "RUNNING" + // Pipeline is waiting for streams to shut down + PipelineState_PipelineState_Stopping PipelineState_PipelineState = "STOPPING" + // All clusters, jobs, and other resources associated with the pipeline have + // been cleaned up + PipelineState_PipelineState_Deleted PipelineState_PipelineState = "DELETED" + // Pipeline has run into an error, but the daemon is attempting to fix it + PipelineState_PipelineState_Recovering PipelineState_PipelineState = "RECOVERING" + // Pipeline has run into an error that could not be recovered from + PipelineState_PipelineState_Failed PipelineState_PipelineState = "FAILED" + // Pipeline is currently being reset + PipelineState_PipelineState_Resetting PipelineState_PipelineState = "RESETTING" + // Pipeline is stopped and is not processing data. Can be resumed by calling + // `run` + PipelineState_PipelineState_Idle PipelineState_PipelineState = "IDLE" +) + +// The SCD type to use to ingest the table. +type ScdType_ScdType string + +const ( + ScdType_ScdType_Unspecified ScdType_ScdType = "" + ScdType_ScdType_ScdType1 ScdType_ScdType = "SCD_TYPE_1" + ScdType_ScdType_ScdType2 ScdType_ScdType = "SCD_TYPE_2" + // Source data will be appended to destination table rather than merged in the + // absence of row key. + ScdType_ScdType_AppendOnly ScdType_ScdType = "APPEND_ONLY" +) + +type SharepointOptions_SharepointEntityType string + +const ( + SharepointOptions_SharepointEntityType_Unspecified SharepointOptions_SharepointEntityType = "" + SharepointOptions_SharepointEntityType_File SharepointOptions_SharepointEntityType = "FILE" + SharepointOptions_SharepointEntityType_FileMetadata SharepointOptions_SharepointEntityType = "FILE_METADATA" + SharepointOptions_SharepointEntityType_Permission SharepointOptions_SharepointEntityType = "PERMISSION" + SharepointOptions_SharepointEntityType_List SharepointOptions_SharepointEntityType = "LIST" +) + +// Data level for TikTok Ads report aggregation. +type TikTokAdsOptions_TikTokDataLevel string + +const ( + TikTokAdsOptions_TikTokDataLevel_Unspecified TikTokAdsOptions_TikTokDataLevel = "" + TikTokAdsOptions_TikTokDataLevel_AuctionAdvertiser TikTokAdsOptions_TikTokDataLevel = "AUCTION_ADVERTISER" + TikTokAdsOptions_TikTokDataLevel_AuctionCampaign TikTokAdsOptions_TikTokDataLevel = "AUCTION_CAMPAIGN" + TikTokAdsOptions_TikTokDataLevel_AuctionAdgroup TikTokAdsOptions_TikTokDataLevel = "AUCTION_ADGROUP" + TikTokAdsOptions_TikTokDataLevel_AuctionAd TikTokAdsOptions_TikTokDataLevel = "AUCTION_AD" +) + +// Report type for TikTok Ads API. +type TikTokAdsOptions_TikTokReportType string + +const ( + TikTokAdsOptions_TikTokReportType_Unspecified TikTokAdsOptions_TikTokReportType = "" + TikTokAdsOptions_TikTokReportType_Basic TikTokAdsOptions_TikTokReportType = "BASIC" + TikTokAdsOptions_TikTokReportType_Audience TikTokAdsOptions_TikTokReportType = "AUDIENCE" + TikTokAdsOptions_TikTokReportType_PlayableAd TikTokAdsOptions_TikTokReportType = "PLAYABLE_AD" + TikTokAdsOptions_TikTokReportType_Dsa TikTokAdsOptions_TikTokReportType = "DSA" + TikTokAdsOptions_TikTokReportType_BusinessCenter TikTokAdsOptions_TikTokReportType = "BUSINESS_CENTER" + TikTokAdsOptions_TikTokReportType_GmvMax TikTokAdsOptions_TikTokReportType = "GMV_MAX" +) + +type Transformer_Format string + +const ( + Transformer_Format_Unspecified Transformer_Format = "" + Transformer_Format_String Transformer_Format = "STRING" + Transformer_Format_Json Transformer_Format = "JSON" +) + +// Top-level configuration for API Source connectors with arbitrary +// configuration.. +type ApiSourceConnectorConfig struct { + // Arbitrary key-value configuration values for the API Source connector. + Configs map[string]string +} + +// Options for API Source connectors with arbitrary configuration.. +type ApiSourceConnectorOptions struct { + // Arbitrary key-value configuration options for the API Source connector. + Options map[string]string +} + +type ApplyEnvironmentRequest struct { + PipelineId *string +} + +type ApplyEnvironmentResponse struct { +} + +// Policy for auto full refresh.. +type AutoFullRefreshPolicy struct { + // (Required, Mutable) Whether to enable auto full refresh or not. + Enabled *bool + // (Optional, Mutable) Specify the minimum interval in hours between the + // timestamp at which a table was last full refreshed and the current timestamp + // for triggering auto full If unspecified and autoFullRefresh is enabled then + // by default min_interval_hours is 24 hours. + MinIntervalHours *int +} + +type ClonePipelineRequest struct { + // Source pipeline to clone from + PipelineId *string + // If present, the last-modified time of the pipeline settings before the clone. + // If the settings were modified after that time, then the request will fail + // with a conflict. + ExpectedLastModified *int64 + // If false, deployment will fail if name conflicts with that of another + // pipeline. + AllowDuplicateNames *bool + // Unique identifier for this pipeline. + Id *string + // Friendly identifier for this pipeline. + Name *string + // DBFS root directory for storing checkpoints and tables. + Storage *string + // String-String configuration for this pipeline execution. + Configuration map[string]string + // Cluster settings for this pipeline deployment. + Clusters []PipelineCluster + // Libraries or code needed by this deployment. + Libraries []PipelineLibrary + // The configuration for a managed ingestion pipeline. These settings cannot be + // used with the 'libraries', 'schema', 'target', or 'catalog' settings. + IngestionDefinition *IngestionPipelineDefinition + // The definition of a gateway pipeline to support change data capture. + GatewayDefinition *IngestionGatewayPipelineDefinition + // Which pipeline trigger to use. Deprecated: Use `continuous` instead. + Trigger *PipelineTrigger + // Target schema (database) to add tables in this pipeline to. Exactly one of + // `schema` or `target` must be specified. To publish to Unity Catalog, also + // specify `catalog`. This legacy field is deprecated for pipeline creation in + // favor of the `schema` field. + Target *string + // The default schema (database) where tables are read from or published to. + Schema *string + // Filters on which Pipeline packages to include in the deployed graph. + Filters *Filters + // Whether the pipeline is continuous or triggered. This replaces `trigger`. + // + // Deprecated: wrap the pipeline in a continuous job instead, which also lets + // you take advantage of job-level settings such as performance mode. When the + // pipeline is started by a continuous job, the job's setting takes precedence + // and this field is ignored. + Continuous *bool + // Whether the pipeline is in Development mode. Defaults to false. + Development *bool + // Whether Photon is enabled for this pipeline. + Photon *bool + // Pipeline product edition. + Edition *string + // SDP Release Channel that specifies which version to use. + Channel *string + // A catalog in Unity Catalog to publish data from this pipeline to. If `target` + // is specified, tables in this pipeline are published to a `target` schema + // inside `catalog` (for example, `catalog`.`target`.`table`). If `target` is + // not specified, no data is published to Unity Catalog. + Catalog *string + // List of notification settings for this pipeline. + Notifications []Notifications + // Whether serverless compute is enabled for this pipeline. + Serverless *bool + // Deployment type of this pipeline. + Deployment *PipelineDeployment + // Restart window of this pipeline. + RestartWindow *RestartWindow + // Budget policy of this pipeline. + BudgetPolicyId *string + // A map of tags associated with the pipeline. These are forwarded to the + // cluster as cluster tags, and are therefore subject to the same limitations. A + // maximum of 25 tags can be added to the pipeline. + Tags map[string]string + // Event log configuration for this pipeline + EventLog *EventLogSpec + // Root path for this pipeline. This is used as the root directory when editing + // the pipeline in the user interface and it is added to sys.path + // when executing Python sources during pipeline execution. + RootPath *string + // Environment specification for this pipeline used to install dependencies. + Environment *PipelinesEnvironment + // Usage policy of this pipeline. + UsagePolicyId *string + // Serverless compute ID specified by the user for serverless pipelines. + ServerlessComputeId *string + // The type of clone to perform. Currently, only deep copies are supported + CloneMode CloneMode +} + +type ClonePipelineResponse struct { + // The pipeline id of the cloned pipeline + PipelineId *string +} + +// Confluence specific options for ingestion. +type ConfluenceConnectorOptions struct { + // (Optional) Spaces to filter Confluence data on + IncludeConfluenceSpaces []string +} + +type ConnectionParameters struct { + // Source catalog for initial connection. This is necessary for schema + // exploration in some database systems like Oracle, and optional but + // nice-to-have in some other database systems like Postgres. For Oracle + // databases, this maps to a service name. + SourceCatalog *string +} + +// Wrapper message for source-specific options to support multiple connector +// types. +type ConnectorOptions struct { + ConnectorOptions isConnectorOptions_ConnectorOptions +} + +type isConnectorOptions_ConnectorOptions interface { + isConnectorOptions_ConnectorOptions() +} + +// ConnectorOptions_ConnectorOptions_GoogleAdsOptions selects GoogleAdsOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_GoogleAdsOptions struct { + GoogleAdsOptions GoogleAdsOptions +} + +func (*ConnectorOptions_ConnectorOptions_GoogleAdsOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_TiktokAdsOptions selects TiktokAdsOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_TiktokAdsOptions struct { + TiktokAdsOptions TikTokAdsOptions +} + +func (*ConnectorOptions_ConnectorOptions_TiktokAdsOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_SharepointOptions selects SharepointOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_SharepointOptions struct { + SharepointOptions SharepointOptions +} + +func (*ConnectorOptions_ConnectorOptions_SharepointOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_GdriveOptions selects GdriveOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_GdriveOptions struct { + GdriveOptions GoogleDriveOptions +} + +func (*ConnectorOptions_ConnectorOptions_GdriveOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_OutlookOptions selects OutlookOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_OutlookOptions struct { + OutlookOptions OutlookOptions +} + +func (*ConnectorOptions_ConnectorOptions_OutlookOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_SmartsheetOptions selects SmartsheetOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_SmartsheetOptions struct { + SmartsheetOptions SmartsheetOptions +} + +func (*ConnectorOptions_ConnectorOptions_SmartsheetOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_JiraOptions selects JiraOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_JiraOptions struct { + JiraOptions JiraConnectorOptions +} + +func (*ConnectorOptions_ConnectorOptions_JiraOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_ConfluenceOptions selects ConfluenceOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_ConfluenceOptions struct { + ConfluenceOptions ConfluenceConnectorOptions +} + +func (*ConnectorOptions_ConnectorOptions_ConfluenceOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_MetaAdsOptions selects MetaAdsOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_MetaAdsOptions struct { + MetaAdsOptions MetaMarketingOptions +} + +func (*ConnectorOptions_ConnectorOptions_MetaAdsOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_ZendeskSupportOptions selects ZendeskSupportOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_ZendeskSupportOptions struct { + ZendeskSupportOptions ZendeskSupportOptions +} + +func (*ConnectorOptions_ConnectorOptions_ZendeskSupportOptions) isConnectorOptions_ConnectorOptions() { +} + +// ConnectorOptions_ConnectorOptions_KafkaOptions selects KafkaOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_KafkaOptions struct { + KafkaOptions KafkaOptions +} + +func (*ConnectorOptions_ConnectorOptions_KafkaOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_MarketoOptions selects MarketoOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_MarketoOptions struct { + MarketoOptions MarketoOptions +} + +func (*ConnectorOptions_ConnectorOptions_MarketoOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_LinkedinAdsOptions selects LinkedinAdsOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_LinkedinAdsOptions struct { + LinkedinAdsOptions LinkedInAdsOptions +} + +func (*ConnectorOptions_ConnectorOptions_LinkedinAdsOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_RedditAdsOptions selects RedditAdsOptions for ConnectorOptions.ConnectorOptions. +type ConnectorOptions_ConnectorOptions_RedditAdsOptions struct { + RedditAdsOptions RedditAdsOptions +} + +func (*ConnectorOptions_ConnectorOptions_RedditAdsOptions) isConnectorOptions_ConnectorOptions() {} + +// ConnectorOptions_ConnectorOptions_ApiSourceConnectorOptions selects ApiSourceConnectorOptions for ConnectorOptions.ConnectorOptions. +// Connector-specific options for API Source connectors. +type ConnectorOptions_ConnectorOptions_ApiSourceConnectorOptions struct { + ApiSourceConnectorOptions ApiSourceConnectorOptions +} + +func (*ConnectorOptions_ConnectorOptions_ApiSourceConnectorOptions) isConnectorOptions_ConnectorOptions() { +} + +type CreatePipelineRequest struct { + // If false, deployment will fail if name conflicts with that of another + // pipeline. + AllowDuplicateNames *bool + DryRun *bool + RunAs *PipelinesJobRunAs + // Key/value map of default parameters to use for pipeline execution. Maximum + // total size: 10k characters (JSON format) + Parameters map[string]string + // Unique identifier for this pipeline. + Id *string + // Friendly identifier for this pipeline. + Name *string + // DBFS root directory for storing checkpoints and tables. + Storage *string + // String-String configuration for this pipeline execution. + Configuration map[string]string + // Cluster settings for this pipeline deployment. + Clusters []PipelineCluster + // Libraries or code needed by this deployment. + Libraries []PipelineLibrary + // The configuration for a managed ingestion pipeline. These settings cannot be + // used with the 'libraries', 'schema', 'target', or 'catalog' settings. + IngestionDefinition *IngestionPipelineDefinition + // The definition of a gateway pipeline to support change data capture. + GatewayDefinition *IngestionGatewayPipelineDefinition + // Which pipeline trigger to use. Deprecated: Use `continuous` instead. + Trigger *PipelineTrigger + // Target schema (database) to add tables in this pipeline to. Exactly one of + // `schema` or `target` must be specified. To publish to Unity Catalog, also + // specify `catalog`. This legacy field is deprecated for pipeline creation in + // favor of the `schema` field. + Target *string + // The default schema (database) where tables are read from or published to. + Schema *string + // Filters on which Pipeline packages to include in the deployed graph. + Filters *Filters + // Whether the pipeline is continuous or triggered. This replaces `trigger`. + // + // Deprecated: wrap the pipeline in a continuous job instead, which also lets + // you take advantage of job-level settings such as performance mode. When the + // pipeline is started by a continuous job, the job's setting takes precedence + // and this field is ignored. + Continuous *bool + // Whether the pipeline is in Development mode. Defaults to false. + Development *bool + // Whether Photon is enabled for this pipeline. + Photon *bool + // Pipeline product edition. + Edition *string + // SDP Release Channel that specifies which version to use. + Channel *string + // A catalog in Unity Catalog to publish data from this pipeline to. If `target` + // is specified, tables in this pipeline are published to a `target` schema + // inside `catalog` (for example, `catalog`.`target`.`table`). If `target` is + // not specified, no data is published to Unity Catalog. + Catalog *string + // List of notification settings for this pipeline. + Notifications []Notifications + // Whether serverless compute is enabled for this pipeline. + Serverless *bool + // Deployment type of this pipeline. + Deployment *PipelineDeployment + // Restart window of this pipeline. + RestartWindow *RestartWindow + // Budget policy of this pipeline. + BudgetPolicyId *string + // A map of tags associated with the pipeline. These are forwarded to the + // cluster as cluster tags, and are therefore subject to the same limitations. A + // maximum of 25 tags can be added to the pipeline. + Tags map[string]string + // Event log configuration for this pipeline + EventLog *EventLogSpec + // Root path for this pipeline. This is used as the root directory when editing + // the pipeline in the user interface and it is added to sys.path + // when executing Python sources during pipeline execution. + RootPath *string + // Environment specification for this pipeline used to install dependencies. + Environment *PipelinesEnvironment + // Usage policy of this pipeline. + UsagePolicyId *string + // Serverless compute ID specified by the user for serverless pipelines. + ServerlessComputeId *string +} + +type CreatePipelineResponse struct { + // The unique identifier for the newly created pipeline. Only returned when + // dry_run is false. + PipelineId *string + // Only returned when dry_run is true. + EffectiveSettings *PipelineSpec +} + +type CronTrigger struct { + QuartzCronSchedule *string + TimezoneId *string +} + +type DataPlaneId struct { + // The instance name of the data plane emitting an event. + Instance *string + // A sequence number, unique and increasing within the data plane instance. + SeqNo *int64 +} + +// Location of staged data storage. +type DataStagingOptions struct { + // (Required, Immutable) The name of the catalog for the connector's staging + // storage location. + CatalogName *string + // (Required, Immutable) The name of the schema for the connector's staging + // storage location. + SchemaName *string + // (Optional) The Unity Catalog-compatible name for the storage location. This + // is the volume to use for the data that is extracted by the connector. Spark + // Declarative Pipelines system will automatically create the volume under the + // catalog and schema. For Combined Cdc Managed Ingestion pipelines default name + // for the volume would be : + // __databricks_ingestion_gateway_staging_data-$pipelineId + VolumeName *string +} + +type DeletePipelineRequest struct { + PipelineId *string + // If true, deletion will proceed even if resource cleanup fails. By default, + // deletion will fail if resources cleanup is required but fails. + Force *bool + // If false, pipeline deletion will not cascade to its datasets (MVs, STs, + // Views). By default, this parameter will be true and all tables will be + // deleted with the pipeline. + Cascade *bool +} + +type DeletePipelineResponse struct { +} + +type EditPipelineRequest struct { + // Unique identifier for this pipeline. + PipelineId *string + // If false, deployment will fail if name has changed and conflicts the name of + // another pipeline. + AllowDuplicateNames *bool + // If present, the last-modified time of the pipeline settings before the edit. + // If the settings were modified after that time, then the request will fail + // with a conflict. + ExpectedLastModified *int64 + RunAs *PipelinesJobRunAs + // Key/value map of default parameters to use for pipeline execution. Maximum + // total size: 10k characters (JSON format) + Parameters map[string]string + // Unique identifier for this pipeline. + Id *string + // Friendly identifier for this pipeline. + Name *string + // DBFS root directory for storing checkpoints and tables. + Storage *string + // String-String configuration for this pipeline execution. + Configuration map[string]string + // Cluster settings for this pipeline deployment. + Clusters []PipelineCluster + // Libraries or code needed by this deployment. + Libraries []PipelineLibrary + // The configuration for a managed ingestion pipeline. These settings cannot be + // used with the 'libraries', 'schema', 'target', or 'catalog' settings. + IngestionDefinition *IngestionPipelineDefinition + // The definition of a gateway pipeline to support change data capture. + GatewayDefinition *IngestionGatewayPipelineDefinition + // Which pipeline trigger to use. Deprecated: Use `continuous` instead. + Trigger *PipelineTrigger + // Target schema (database) to add tables in this pipeline to. Exactly one of + // `schema` or `target` must be specified. To publish to Unity Catalog, also + // specify `catalog`. This legacy field is deprecated for pipeline creation in + // favor of the `schema` field. + Target *string + // The default schema (database) where tables are read from or published to. + Schema *string + // Filters on which Pipeline packages to include in the deployed graph. + Filters *Filters + // Whether the pipeline is continuous or triggered. This replaces `trigger`. + // + // Deprecated: wrap the pipeline in a continuous job instead, which also lets + // you take advantage of job-level settings such as performance mode. When the + // pipeline is started by a continuous job, the job's setting takes precedence + // and this field is ignored. + Continuous *bool + // Whether the pipeline is in Development mode. Defaults to false. + Development *bool + // Whether Photon is enabled for this pipeline. + Photon *bool + // Pipeline product edition. + Edition *string + // SDP Release Channel that specifies which version to use. + Channel *string + // A catalog in Unity Catalog to publish data from this pipeline to. If `target` + // is specified, tables in this pipeline are published to a `target` schema + // inside `catalog` (for example, `catalog`.`target`.`table`). If `target` is + // not specified, no data is published to Unity Catalog. + Catalog *string + // List of notification settings for this pipeline. + Notifications []Notifications + // Whether serverless compute is enabled for this pipeline. + Serverless *bool + // Deployment type of this pipeline. + Deployment *PipelineDeployment + // Restart window of this pipeline. + RestartWindow *RestartWindow + // Budget policy of this pipeline. + BudgetPolicyId *string + // A map of tags associated with the pipeline. These are forwarded to the + // cluster as cluster tags, and are therefore subject to the same limitations. A + // maximum of 25 tags can be added to the pipeline. + Tags map[string]string + // Event log configuration for this pipeline + EventLog *EventLogSpec + // Root path for this pipeline. This is used as the root directory when editing + // the pipeline in the user interface and it is added to sys.path + // when executing Python sources during pipeline execution. + RootPath *string + // Environment specification for this pipeline used to install dependencies. + Environment *PipelinesEnvironment + // Usage policy of this pipeline. + UsagePolicyId *string + // Serverless compute ID specified by the user for serverless pipelines. + ServerlessComputeId *string +} + +type EditPipelineResponse struct { +} + +type ErrorDetail struct { + // The exception thrown for this error, with its chain of cause. + Exceptions []SerializedException + // Whether this error is considered fatal, that is, unrecoverable. + Fatal *bool +} + +// Configurable event log parameters.. +type EventLogSpec struct { + // The name the event log is published to in UC. + Name *string + // The UC schema the event log is published under. + Schema *string + // The UC catalog the event log is published under. + Catalog *string +} + +type FileFilter struct { + Filter isFileFilter_Filter +} + +type isFileFilter_Filter interface { + isFileFilter_Filter() +} + +// FileFilter_Filter_PathFilter selects PathFilter for FileFilter.Filter. +// Include files with file names matching the pattern Based on +// https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#path-glob-filter +type FileFilter_Filter_PathFilter struct { + PathFilter string +} + +func (*FileFilter_Filter_PathFilter) isFileFilter_Filter() {} + +// FileFilter_Filter_ModifiedBefore selects ModifiedBefore for FileFilter.Filter. +// Include files with modification times occurring before the specified time. +// Timestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00) Based on +// https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters +type FileFilter_Filter_ModifiedBefore struct { + ModifiedBefore string +} + +func (*FileFilter_Filter_ModifiedBefore) isFileFilter_Filter() {} + +// FileFilter_Filter_ModifiedAfter selects ModifiedAfter for FileFilter.Filter. +// Include files with modification times occurring after the specified time. +// Timestamp format: YYYY-MM-DDTHH:mm:ss (e.g. 2020-06-01T13:00:00) Based on +// https://spark.apache.org/docs/latest/sql-data-sources-generic-options.html#modification-time-path-filters +type FileFilter_Filter_ModifiedAfter struct { + ModifiedAfter string +} + +func (*FileFilter_Filter_ModifiedAfter) isFileFilter_Filter() {} + +type FileIngestionOptions struct { + // required for TableSpec + Format FileIngestionOptions_FileFormat + // Generic options + FileFilters []FileFilter + InferColumnTypes *bool + SchemaEvolutionMode FileIngestionOptions_SchemaEvolutionMode + // Override inferred schema of specific columns Based on + // https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#override-schema-inference-with-schema-hints + SchemaHints *string + IgnoreCorruptFiles *bool + CorruptRecordColumn *string + RescuedDataColumn *string + SingleVariantColumn *string + // Column name case sensitivity + // https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/schema#change-case-sensitive-behavior + ReaderCaseSensitive *bool + // Format-specific options Based on + // https://docs.databricks.com/aws/en/ingestion/cloud-object-storage/auto-loader/options#file-format-options + FormatOptions map[string]string +} + +type Filters struct { + // Paths to include. + Include []string + // Paths to exclude. + Exclude []string +} + +type GetPipelineRequest struct { + PipelineId *string +} + +type GetPipelineResponse struct { + // The ID of the pipeline. + PipelineId *string + // The pipeline specification. This field is not returned when called by + // `ListPipelines`. + Spec *PipelineSpec + // The pipeline state. + State PipelineState_PipelineState + // An optional message detailing the cause of the pipeline state. + Cause *string + // The ID of the cluster that the pipeline is running on. + ClusterId *string + // A human friendly identifier for the pipeline, taken from the `spec`. + Name *string + // The health of a pipeline. + Health PipelineHealthStatus + // The username of the pipeline creator. + CreatorUserName *string + // Status of the latest updates for the pipeline. Ordered with the newest update + // first. + LatestUpdates []UpdateStateInfo + // The last time the pipeline settings were modified or created. + LastModified *int64 + // Username of the user that the pipeline will run on behalf of. + RunAsUserName *string + // Serverless budget policy ID of this pipeline. + EffectiveBudgetPolicyId *string + // Publishing mode of the pipeline + EffectivePublishingMode PublishingMode + // The user or service principal that the pipeline runs as, if specified in the + // request. This field indicates the explicit configuration of `run_as` for the + // pipeline. To find the value in all cases, explicit or implicit, use + // `run_as_user_name`. + RunAs *PipelinesJobRunAs + // Key/value map of default parameters to use for pipeline execution. Maximum + // total size: 10k characters (JSON format) + Parameters map[string]string + // Serverless compute ID resolved for the pipeline. + EffectiveServerlessComputeId *string +} + +type GetUpdateRequest struct { + // The ID of the pipeline. + PipelineId *string + // The ID of the update. + UpdateId *string +} + +type GetUpdateResponse struct { + // The current update info. + Update *UpdateInfo +} + +type GoogleAdsConfig struct { + // (Required) Manager Account ID (also called MCC Account ID) used to list and + // access customer accounts under this manager account. This is required for + // fetching the list of customer accounts during source selection. If the same + // field is also set in the object-level GoogleAdsOptions (connector_options), + // the object-level value takes precedence over this top-level config. + ManagerAccountId *string +} + +// User-defined custom report for the Google Ads connector. Mirrors the resource +// + fields + segments + metrics model that Google Ads GAQL exposes. The +// customer account this report runs against is supplied by the source schema +// (namespace), not by this message. The whole message is gated by the parent +// GoogleAdsOptions.custom_report_options stage; per-field stage annotations are +// intentionally omitted. Only supported on table-type objects: a custom report +// requires a destination table, so it cannot be specified at the schema/source +// level.. +type GoogleAdsCustomReportOptions struct { + // (Required) Google Ads resource to query (e.g. "ad_group_ad", "keyword_view", + // "search_term_view"). Must be a resource that has metrics. Values are + // validated against Google Ads' field-service catalog at pipeline plan time. + Resource *string + // (Optional) Resource fields to select, in fully-qualified GAQL form (e.g. + // "ad_group_ad.ad.id", "ad_group_ad.status"). Multiple values are joined into + // the GAQL SELECT clause. + ResourceFields []string + // (Optional) Segment fields to select (e.g. "segments.date", + // "segments.device"). Must include at least one of segments.date, + // segments.week, or segments.month — that segment is used as the incremental + // cursor for the table. + Segments []string + // (Optional) Metric fields to select (e.g. "metrics.clicks", + // "metrics.cost_micros"). Multiple values are joined into the GAQL SELECT + // clause. + Metrics []string +} + +// Google Ads specific options for ingestion (object-level). When set, these +// values override the corresponding fields in GoogleAdsConfig +// (source_configurations).. +type GoogleAdsOptions struct { + // (Optional at this level) Manager Account ID (also called MCC Account ID) used + // to list and access customer accounts under this manager account. Overrides + // GoogleAdsConfig.manager_account_id from source_configurations when set. + ManagerAccountId *string + // (Optional) Number of days to look back for report tables to capture + // late-arriving data. If not specified, defaults to 30 days. + LookbackWindowDays *int + // (Optional) Start date for the initial sync of report tables in YYYY-MM-DD + // format. This determines the earliest date from which to sync historical data. + // If not specified, defaults to 2 years of historical data. + SyncStartDate *string + // (Optional) Custom report definition. When set, the table is treated as a + // user-defined Google Ads custom report: the connector synthesizes a GAQL query + // from the resource, fields, segments, and metrics specified here. When unset, + // the table must match one of the connector's prebuilt sources. + CustomReportOptions *GoogleAdsCustomReportOptions +} + +type GoogleDriveOptions struct { + // Google Drive URL. + Url *string + EntityType GoogleDriveOptions_GoogleDriveEntityType + FileIngestionOptions *FileIngestionOptions +} + +type IngestionGatewayPipelineDefinition struct { + // Immutable. The Unity Catalog connection that this gateway pipeline uses to + // communicate with the source. + ConnectionName *string + // [Deprecated, use connection_name instead] Immutable. The Unity Catalog + // connection that this gateway pipeline uses to communicate with the source. + ConnectionId *string + // Required, Immutable. The name of the catalog for the gateway pipeline's + // storage location. + GatewayStorageCatalog *string + // Required, Immutable. The name of the schema for the gateway pipelines's + // storage location. + GatewayStorageSchema *string + // Optional. The Unity Catalog-compatible name for the gateway storage location. + // This is the destination to use for the data that is extracted by the gateway. + // Spark Declarative Pipelines system will automatically create the storage + // location under the catalog and schema. + GatewayStorageName *string + // Optional, Internal. Parameters required to establish an initial connection + // with the source. + ConnectionParameters *ConnectionParameters +} + +type IngestionPipelineDefinition struct { + // (Required, Mutable) Identifies the data source for the Lakeflow Connect + // Ingestion pipeline. Exactly one option must be specified. + Source isIngestionPipelineDefinition_Source + // Required. Settings specifying tables to replicate and the destination for the + // replicated tables. + Objects []IngestionPipelineDefinition_IngestionConfig + // The type of the foreign source. The source type will be inferred from the + // source connection or ingestion gateway. This field is output only and will be + // ignored if provided. + SourceType IngestionSourceType + // Configuration settings to control the ingestion of tables. These settings are + // applied to all tables in the pipeline. + TableConfiguration *IngestionPipelineDefinition_TableSpecificConfig + // Netsuite only configuration. When the field is set for a netsuite connector, + // the jar stored in the field will be validated and added to the classpath of + // pipeline's cluster. + NetsuiteJarPath *string + // Top-level source configurations + SourceConfigurations []SourceConfig + // (Optional) A window that specifies a set of time ranges for snapshot queries + // in CDC. + FullRefreshWindow *OperationTimeWindow + // (Optional) Connector Type for sources. Ex: CDC, Query Based. + ConnectorType ConnectorType + // (Optional) Location of staged data storage. This is required for migration + // from Cdc Managed Ingestion Pipeline with Gateway pipeline to Combined Cdc + // Managed Ingestion Pipeline. If not specified, the volume for staged data will + // be created in catalog and schema/target specified in the top level pipeline + // definition. + DataStagingOptions *DataStagingOptions +} + +type isIngestionPipelineDefinition_Source interface { + isIngestionPipelineDefinition_Source() +} + +// IngestionPipelineDefinition_Source_ConnectionName selects ConnectionName for IngestionPipelineDefinition.Source. +// The Unity Catalog connection that this ingestion pipeline uses to communicate +// with the source. This is used with both connectors for applications like +// Salesforce, Workday, and so on, and also database connectors like Oracle, +// (connector_type = QUERY_BASED OR connector_type = CDC). If connection name +// corresponds to database connectors like Oracle, and connector_type is not +// provided then connector_type defaults to QUERY_BASED. If connector_type is +// passed as CDC we use Combined Cdc Managed Ingestion pipeline. Under certain +// conditions, this can be replaced with ingestion_gateway_id to change the +// connector to Cdc Managed Ingestion Pipeline with Gateway pipeline. +type IngestionPipelineDefinition_Source_ConnectionName struct { + ConnectionName string +} + +func (*IngestionPipelineDefinition_Source_ConnectionName) isIngestionPipelineDefinition_Source() {} + +// IngestionPipelineDefinition_Source_IngestionGatewayId selects IngestionGatewayId for IngestionPipelineDefinition.Source. +// Identifier for the gateway that is used by this ingestion pipeline to +// communicate with the source database. This is used with CDC connectors to +// databases like SQL Server using a gateway pipeline (connector_type = CDC). +// Under certain conditions, this can be replaced with connection_name to change +// the connector to Combined Cdc Managed Ingestion Pipeline. +type IngestionPipelineDefinition_Source_IngestionGatewayId struct { + IngestionGatewayId string +} + +func (*IngestionPipelineDefinition_Source_IngestionGatewayId) isIngestionPipelineDefinition_Source() { +} + +// IngestionPipelineDefinition_Source_IngestFromUcForeignCatalog selects IngestFromUcForeignCatalog for IngestionPipelineDefinition.Source. +// Immutable. If set to true, the pipeline will ingest tables from the UC +// foreign catalogs directly without the need to specify a UC connection or +// ingestion gateway. The `source_catalog` fields in objects of IngestionConfig +// are interpreted as the UC foreign catalogs to ingest from. +type IngestionPipelineDefinition_Source_IngestFromUcForeignCatalog struct { + IngestFromUcForeignCatalog bool +} + +func (*IngestionPipelineDefinition_Source_IngestFromUcForeignCatalog) isIngestionPipelineDefinition_Source() { +} + +// Fanout configuration for multi-table routing from streaming sources. Routes +// each input record to a destination table based on a routing key derived from +// the record. The key value becomes the table name suffix: +// {destination_catalog}.{destination_schema}.{key_value}.. +type IngestionPipelineDefinition_FanoutOptions struct { + // Column path or SQL expression whose value determines the destination table. + // Supports dotted paths (e.g. "value.event_name") and expressions (e.g. + // "value:event_name::string"). + FanoutBy *string + // Optional transforms applied to each route's DataFrame before writing to the + // destination table. + Transforms []Transformer +} + +type IngestionPipelineDefinition_IngestionConfig struct { + SourceTables isIngestionPipelineDefinition_IngestionConfig_SourceTables +} + +type isIngestionPipelineDefinition_IngestionConfig_SourceTables interface { + isIngestionPipelineDefinition_IngestionConfig_SourceTables() +} + +// IngestionPipelineDefinition_IngestionConfig_SourceTables_Schema selects Schema for IngestionPipelineDefinition_IngestionConfig.SourceTables. +// Select all tables from a specific source schema. +type IngestionPipelineDefinition_IngestionConfig_SourceTables_Schema struct { + Schema IngestionPipelineDefinition_SchemaSpec +} + +func (*IngestionPipelineDefinition_IngestionConfig_SourceTables_Schema) isIngestionPipelineDefinition_IngestionConfig_SourceTables() { +} + +// IngestionPipelineDefinition_IngestionConfig_SourceTables_Table selects Table for IngestionPipelineDefinition_IngestionConfig.SourceTables. +// Select a specific source table. +type IngestionPipelineDefinition_IngestionConfig_SourceTables_Table struct { + Table IngestionPipelineDefinition_TableSpec +} + +func (*IngestionPipelineDefinition_IngestionConfig_SourceTables_Table) isIngestionPipelineDefinition_IngestionConfig_SourceTables() { +} + +// IngestionPipelineDefinition_IngestionConfig_SourceTables_Report selects Report for IngestionPipelineDefinition_IngestionConfig.SourceTables. +// Select a specific source report. +type IngestionPipelineDefinition_IngestionConfig_SourceTables_Report struct { + Report IngestionPipelineDefinition_ReportSpec +} + +func (*IngestionPipelineDefinition_IngestionConfig_SourceTables_Report) isIngestionPipelineDefinition_IngestionConfig_SourceTables() { +} + +type IngestionPipelineDefinition_ReportSpec struct { + // Required. Report URL in the source system. + SourceUrl *string + // Required. Destination catalog to store table. + DestinationCatalog *string + // Required. Destination schema to store table. + DestinationSchema *string + // Required. Destination table name. The pipeline fails if a table with that + // name already exists. + DestinationTable *string + // Configuration settings to control the ingestion of tables. These settings + // override the table_configuration defined in the IngestionPipelineDefinition + // object. + TableConfiguration *IngestionPipelineDefinition_TableSpecificConfig +} + +type IngestionPipelineDefinition_SchemaSpec struct { + // The source catalog name. Might be optional depending on the type of source. + SourceCatalog *string + // Schema name in the source database. Currently required; this field will + // become optional in an upcoming release, since some source types (for example + // streaming / message-bus connectors) do not use it. When that change ships, + // this field's type in the generated SDKs and CLI will change from required to + // optional (nullable); clients that assume it is always present should handle + // its absence. + SourceSchema *string + // Required. Destination catalog to store tables. + DestinationCatalog *string + // Required. Destination schema to store tables in. Tables with the same name as + // the source tables are created in this destination schema. The pipeline fails + // If a table with the same name already exists. + DestinationSchema *string + // Configuration settings to control the ingestion of tables. These settings are + // applied to all tables in this schema and override the table_configuration + // defined in the IngestionPipelineDefinition object. + TableConfiguration *IngestionPipelineDefinition_TableSpecificConfig + // (Optional) Source Specific Connector Options + ConnectorOptions *ConnectorOptions + // Fanout options for multi-table routing from streaming sources. When set, + // records are routed to destination tables based on a per-record routing key. + // The key value becomes the table name: + // {destination_catalog}.{destination_schema}.{key_value}. + FanoutOptions *IngestionPipelineDefinition_FanoutOptions +} + +type IngestionPipelineDefinition_TableSpec struct { + // Source catalog name. Might be optional depending on the type of source. + SourceCatalog *string + // Schema name in the source database. Might be optional depending on the type + // of source. + SourceSchema *string + // Table name in the source database. Currently required; this field will become + // optional in an upcoming release, since some source types (for example + // streaming / message-bus connectors) do not use it. When that change ships, + // this field's type in the generated SDKs and CLI will change from required to + // optional (nullable); clients that assume it is always present should handle + // its absence. + SourceTable *string + // Required. Destination catalog to store table. + DestinationCatalog *string + // Required. Destination schema to store table. + DestinationSchema *string + // Optional. Destination table name. The pipeline fails if a table with that + // name already exists. If not set, the source table name is used. + DestinationTable *string + // Configuration settings to control the ingestion of tables. These settings + // override the table_configuration defined in the IngestionPipelineDefinition + // object and the SchemaSpec. + TableConfiguration *IngestionPipelineDefinition_TableSpecificConfig + // (Optional) Source Specific Connector Options + ConnectorOptions *ConnectorOptions +} + +type IngestionPipelineDefinition_TableSpecificConfig struct { + ScdType ScdType_ScdType + // The primary key of the table used to apply changes. + PrimaryKeys []string + // The column names specifying the logical order of events in the source data. + // Spark Declarative Pipelines uses this sequencing to handle change events that + // arrive out of order. + SequenceBy []string + // A list of column names to be included for the ingestion. When not specified, + // all columns except ones in exclude_columns will be included. Future columns + // will be automatically included. When specified, all other future columns will + // be automatically excluded from ingestion. This field in mutually exclusive + // with `exclude_columns`. + IncludeColumns []string + // A list of column names to be excluded for the ingestion. When not specified, + // include_columns fully controls what columns to be ingested. When specified, + // all other columns including future ones will be automatically included for + // ingestion. This field in mutually exclusive with `include_columns`. + ExcludeColumns []string + // If true, formula fields defined in the table are included in the ingestion. + // This setting is only valid for the Salesforce connector + SalesforceIncludeFormulaFields *bool + // (Optional) Additional custom parameters for Workday Report + WorkdayReportParameters *IngestionPipelineDefinition_WorkdayReportParameters + // (Optional, Immutable) The row filter condition to be applied to the table. It + // must not contain the WHERE keyword, only the actual filter condition. It must + // be in DBSQL format. + RowFilter *string + QueryBasedConnectorConfig *IngestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfig + // (Optional, Mutable) Policy for auto full refresh, if enabled pipeline will + // automatically try to fix issues by doing a full refresh on the table in the + // retry run. auto_full_refresh_policy in table configuration will override the + // above level auto_full_refresh_policy. For example, { + // "auto_full_refresh_policy": { "enabled": true, "min_interval_hours": 23, } } + // If unspecified, auto full refresh is disabled. + AutoFullRefreshPolicy *AutoFullRefreshPolicy + // Table properties to set on the destination table. These are key-value pairs + // that configure various Delta table behaviors or any user defined properties. + // Example: {"delta.feature.variantType": "supported", + // "delta.enableTypeWidening": "true"} Note: table_properties in table specific + // configuration will override the table_properties of the pipeline definition. + TableProperties map[string]string + // Whether to enable auto clustering on the destination table. When enabled, + // Delta will automatically optimize the data layout based on the clustering + // columns for improved query performance. Note: enable_auto_clustering in table + // specific configuration will override the pipeline definition. Note: we can + // only provide enable_auto_clustering or clustering_columns, added as separate + // fields as we cannot have repeated field in oneof. + EnableAutoClustering *bool + // List of column names to use for clustering the destination table. When + // specified, the destination Delta table will be clustered by these columns. + // This can improve query performance when filtering on these columns. Note: + // clustering_columns in table specific configuration will override the pipeline + // definition. Note: we can only provide enable_auto_clustering or + // clustering_columns, added as separate fields as we cannot have repeated field + // in oneof. + ClusteringColumns []string + // (Optional) Name of the struct column added to each ingested record to hold + // per row source metadata. + SourceMetadataColumn *string +} + +// Configurations that are only applicable for query-based ingestion connectors.. +type IngestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfig struct { + // The names of the monotonically increasing columns in the source table that + // are used to enable the table to be read and ingested incrementally through + // structured streaming. The columns are allowed to have repeated values but + // have to be non-decreasing. If the source data is merged into the destination + // (e.g., using SCD Type 1 or Type 2), these columns will implicitly define the + // `sequence_by` behavior. You can still explicitly set `sequence_by` to + // override this default. + CursorColumns []string + // Specifies a SQL WHERE condition that specifies that the source row has been + // deleted. This is sometimes referred to as "soft-deletes". For example: + // "Operation = 'DELETE'" or "is_deleted = true". This field is orthogonal to + // `hard_deletion_sync_interval_in_seconds`, one for soft-deletes and the other + // for hard-deletes. See also the hard_deletion_sync_min_interval_in_seconds + // field for handling of "hard deletes" where the source rows are physically + // removed from the table. + DeletionCondition *string + // Specifies the minimum interval (in seconds) between snapshots on primary keys + // for detecting and synchronizing hard deletions—i.e., rows that have been + // physically removed from the source table. This interval acts as a lower + // bound. If ingestion runs less frequently than this value, hard deletion + // synchronization will align with the actual ingestion frequency instead of + // happening more often. If not set, hard deletion synchronization via snapshots + // is disabled. This field is mutable and can be updated without triggering a + // full snapshot. + HardDeletionSyncMinIntervalInSeconds *int64 +} + +type IngestionPipelineDefinition_WorkdayReportParameters struct { + // (Optional) Marks the report as incremental. This field is deprecated and + // should not be used. Use `parameters` instead. The incremental behavior is now + // controlled by the `parameters` field. + Incremental *bool + // (Optional) Additional custom parameters for Workday Report This field is + // deprecated and should not be used. Use `parameters` instead. + ReportParameters []IngestionPipelineDefinition_WorkdayReportParameters_QueryKeyValue + // Parameters for the Workday report. Each key represents the parameter name + // (e.g., "start_date", "end_date"), and the corresponding value is a SQL-like + // expression used to compute the parameter value at runtime. Example: { + // "start_date": "{ coalesce(current_offset(), date(\"2025-02-01\")) }", + // "end_date": "{ current_date() - INTERVAL 1 DAY }" } + Parameters map[string]string +} + +type IngestionPipelineDefinition_WorkdayReportParameters_QueryKeyValue struct { + // Key for the report parameter, can be a column name or other metadata + Key *string + // Value for the report parameter. Possible values it can take are these sql + // functions: 1. coalesce(current_offset(), date("YYYY-MM-DD")) -> if + // current_offset() is null, then the passed date, else current_offset() 2. + // current_date() 3. date_sub(current_date(), x) -> subtract x (some + // non-negative integer) days from current date + Value *string +} + +// Jira specific options for ingestion. +type JiraConnectorOptions struct { + // (Optional) Projects to filter Jira data on + IncludeJiraSpaces []string +} + +type JsonTransformerOptions struct { + // Parse the entire value as a single Variant column. + AsVariant *bool + // Inline schema string for JSON parsing (Spark DDL format). + Schema *string + // Path to a schema file (.ddl). + SchemaFilePath *string + // (Optional) Schema evolution mode for schema inference. + SchemaEvolutionMode FileIngestionOptions_SchemaEvolutionMode + // (Optional) Schema hints as a comma-separated string of "column_name type" + // pairs. + SchemaHints *string +} + +type KafkaOptions struct { + // Topics to subscribe to. Only one of topics or topic_pattern must be + // specified. + Topics []string + // Java regex pattern to subscribe to matching topics. Only one of topics or + // topic_pattern must be specified. + TopicPattern *string + // (Optional) Transformer for the message key. If not specified, the key is left + // as raw bytes. + KeyTransformer *Transformer + // (Optional) Transformer for the message value. If not specified, the value is + // left as raw bytes. + ValueTransformer *Transformer + // (Optional) Where to begin reading when no checkpoint exists. Valid values: + // "latest" and "earliest". Defaults to "latest". + StartingOffset *string + // Internal option to control the maximum number of offsets to process per + // trigger. + MaxOffsetsPerTrigger *int64 + // Undocumented backdoor mechanism for overriding parameters to pass to the + // Kafka client. This is not supported and may break at any time. + ClientConfig map[string]string +} + +// LinkedIn Ads specific options for ingestion. sync_start_date and +// lookback_window_days apply to both the prebuilt analytics tables and custom +// reports. custom_report_options defines a custom (user-defined) adAnalytics +// report and is only valid on a table object.. +type LinkedInAdsOptions struct { + // (Optional) Start date for the initial sync of report tables, YYYY-MM-DD. + // Earliest date from which to sync historical data; overrides the default when + // set. For finder attributedRevenueMetrics, this must be between 30 and 366 + // days before today. If not specified, defaults to 1 year of history. + SyncStartDate *string + // (Optional) Days to look back during incremental sync for late-arriving data. + // If not specified, defaults to 30 days. + LookbackWindowDays *int + // (Optional) Custom report definition. Only valid on a table object. When set, + // the table is synthesized from /rest/adAnalytics using the finder, pivots, + // time granularity and metrics here. When unset, the table must match one of + // the connector's prebuilt sources. + CustomReportOptions *LinkedInAdsOptions_LinkedInAdsCustomReportOptions +} + +// User-defined custom report for the LinkedIn Ads connector. The destination +// table name comes from the enclosing TableSpec.destination_table, the start +// date from the enclosing LinkedInAdsOptions.sync_start_date, and the account +// it runs against from the source schema (namespace) -- none are repeated here.. +type LinkedInAdsOptions_LinkedInAdsCustomReportOptions struct { + // (Required) adAnalytics finder. See LinkedInAdsFinder. + Finder LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder + // (Required) Entity pivots to group by; count/constraints depend on finder. + EntityGranularity []LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity + // (Optional) Time aggregation. Defaults to DAILY when unspecified. Used by + // analytics/statistics; ignored for attributedRevenueMetrics. + TimeGranularity LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity + // (Optional) LinkedIn metric names for the report. Open vocabulary (not an + // enum): the valid set is large (~100) and evolves with the LinkedIn + // adAnalytics API, so values are passed through verbatim. If empty, a + // pivot-safe default core set is ingested: impressions, clicks, + // costInLocalCurrency, externalWebsiteConversions (valid for every pivot). + // Ignored for attributedRevenueMetrics (always returns the full + // RevenueAttributionMetrics struct). + Metrics []string +} + +// The request/response messages for the ListPipelines API. The default behavior +// is to return the 25 newest events in timestamp descending order for the given +// pipeline.. +type ListPipelineEventsRequest struct { + // The pipeline to return events for. + PipelineId *string + // Page token returned by previous call. This field is mutually exclusive with + // all fields in this request except max_results. An error is returned if any + // fields other than max_results are set when this field is set. + PageToken *string + // Max number of entries to return in a single page. The system may return fewer + // than max_results events in a response, even if there are more events + // available. + MaxResults *int + // A string indicating a sort order by timestamp for the results, for example, + // ["timestamp asc"]. The sort order can be ascending or descending. By default, + // events are returned in descending order by timestamp. + OrderBy []string + // Criteria to select a subset of results, expressed using a SQL-like syntax. + // The supported filters are: 1. level='INFO' (or WARN or ERROR) 2. level in + // ('INFO', 'WARN') 3. id='[event-id]' 4. timestamp > 'TIMESTAMP' (or >=,<,<=,=) + // + // Composite expressions are supported, for example: level in ('ERROR', 'WARN') + // AND timestamp> '2021-07-22T06:37:33.083Z' + Filter *string +} + +type ListPipelineEventsResponse struct { + // The list of events matching the request criteria. + Events []PipelineEvent + // If present, a token to fetch the next page of events. + NextPageToken *string + // If present, a token to fetch the previous page of events. + PrevPageToken *string +} + +// The request/response messages for the ListPipelines API. The default behavior +// is to return the 25 first pipelines in ascending order of pipeline id.. +type ListPipelinesRequest struct { + // Page token returned by previous call + PageToken *string + // The maximum number of entries to return in a single page. The system may + // return fewer than max_results events in a response, even if there are more + // events available. This field is optional. The default value is 25. The + // maximum value is 100. An error is returned if the value of max_results is + // greater than 100. + MaxResults *int + // A list of strings specifying the order of results. Supported order_by fields + // are id and name. The default is id asc. This field is optional. + OrderBy []string + // Select a subset of results based on the specified criteria. The supported + // filters are: + // + // * `notebook=''` to select pipelines that reference the provided + // notebook path. * `name LIKE '[pattern]'` to select pipelines with a name that + // matches pattern. Wildcards are supported, for example: `name LIKE + // '%shopping%'` + // + // Composite filters are not supported. This field is optional. + Filter *string +} + +type ListPipelinesResponse struct { + // The list of events matching the request criteria. + Statuses []PipelineStateInfo + // If present, a token to fetch the next page of events. + NextPageToken *string +} + +// The request/response messages for the ListUpdates API. The default behavior +// is to return the 25 most recent updates in timestamp descending order for the +// given pipeline. No custom sorting or filtering is supported.. +type ListUpdatesRequest struct { + // The pipeline to return updates for. + PipelineId *string + // Page token returned by previous call + PageToken *string + // Max number of entries to return in a single page. + MaxResults *int + // If present, returns updates until and including this update_id. + UntilUpdateId *string +} + +type ListUpdatesResponse struct { + Updates []UpdateInfo + // If present, then there are more results, and this a token to be used in a + // subsequent request to fetch the next page. + NextPageToken *string + // If present, then this token can be used in a subsequent request to fetch the + // previous page. + PrevPageToken *string +} + +type ManualTrigger struct { +} + +// Marketo specific options for ingestion. +type MarketoOptions struct { + // (Optional) Start date for the initial sync in YYYY-MM-DD format. This + // determines the earliest date from which to sync historical data. If not + // specified, complete history is ingested. + SyncStartDate *string +} + +// Meta Marketing (Meta Ads) specific options for ingestion. +type MetaMarketingOptions struct { + // (Optional, DEPRECATED — use custom_report_options.level) Granularity of + // data to pull (account, ad, adset, campaign) + Level *string + // (Optional, DEPRECATED — use custom_report_options.breakdowns) Breakdowns to + // configure + Breakdowns []string + // (Optional, DEPRECATED — use custom_report_options.action_breakdowns) Action + // breakdowns + ActionBreakdowns []string + // (Optional, DEPRECATED — use custom_report_options.action_report_time) + // Timing used to report action statistics (impression, conversion, mixed, or + // lifetime) + ActionReportTime *string + // (Optional) Start date in yyyy-MM-dd format (e.g. 2025-01-15). Data added + // after this date will be ingested, shared by prebuilt and custom reports. + StartDate *string + // (Optional) Window in days to revisit data during sync to capture updated + // conversion data from the API, shared by prebuilt and custom reports. + CustomInsightsLookbackWindow *int + // (Optional, DEPRECATED — use custom_report_options.time_increment) Value in + // string by which to aggregate statistics (can take all_days, monthly or number + // of days) + TimeIncrement *string + // (Optional, DEPRECATED — use + // custom_report_options.action_attribution_windows) Action attribution windows + // for insights reporting (e.g. "28d_click", "1d_view") + ActionAttributionWindows []string + // (Optional) Per-table custom report definition. When set, defines the shape of + // the insights call for this table + // (level/fields/breakdowns/action_breakdowns/etc.). Supersedes the deprecated + // flat report-shape fields above. + CustomReportOptions *MetaMarketingOptions_MetaMarketingCustomReportOptions +} + +// Defines the shape of a single Meta Ads custom report (one /insights call +// shape). start_date, custom_insights_lookback_window live on +// MetaMarketingOptions, not here. Metrics are not customer-selectable; the +// connector returns a fixed standard metric set.. +type MetaMarketingOptions_MetaMarketingCustomReportOptions struct { + // (Optional) Granularity of data to pull (account, ad, adset, campaign) + Level *string + // (Optional) Breakdowns to configure for data aggregation + Breakdowns []string + // (Optional) Action breakdowns to configure for data aggregation + ActionBreakdowns []string + // (Optional) Timing used to report action statistics (impression, conversion, + // mixed, or lifetime) + ActionReportTime *string + // (Optional) Value in string by which to aggregate statistics (all_days, + // monthly or number of days) + TimeIncrement *string + // (Optional) Action attribution windows for insights reporting (e.g. + // "28d_click", "1d_view") + ActionAttributionWindows []string +} + +type NotebookLibrary struct { + // The absolute path of the source code. + Path *string +} + +type Notifications struct { + // A list of email addresses notified when a configured alert is triggered. + EmailRecipients []string + // A list of alerts that trigger the sending of notifications to the configured + // destinations. The supported alerts are: + // + // * `on-update-success`: A pipeline update completes successfully. * + // `on-update-failure`: Each time a pipeline update fails. * + // `on-update-fatal-failure`: A pipeline update fails with a non-retryable + // (fatal) error. * `on-flow-failure`: A single data flow fails. + Alerts []string +} + +// Proto representing a window. +type OperationTimeWindow struct { + // An integer between 0 and 23 denoting the start hour for the window in the + // 24-hour day. + StartHour *int + // Days of week in which the window is allowed to happen If not specified all + // days of the week will be used. + DaysOfWeek []DayOfWeek + // Time zone id of window. See + // https://docs.databricks.com/sql/language-manual/sql-ref-syntax-aux-conf-mgmt-set-timezone.html + // for details. If not specified, UTC will be used. + TimeZoneId *string +} + +type Origin struct { + // The cloud provider, e.g., AWS or Azure. + Cloud *string + // The cloud region. + Region *string + // The org id of the user. Unique within a cloud. + OrgId *int64 + // The id of the pipeline. Globally unique. + PipelineId *string + // The name of the pipeline. Not unique. + PipelineName *string + // The id of the cluster where an execution happens. Unique within a region. + ClusterId *string + // The id of an execution. Globally unique. + UpdateId *string + // The id of a maintenance run. Globally unique. + MaintenanceId *string + // The id of a (delta) table. Globally unique. + TableId *string + // The name of a dataset. Unique within a pipeline. + DatasetName *string + // The id of the flow. Globally unique. Incremental queries will generally reuse + // the same id while complete queries will have a new id per update. + FlowId *string + // The name of the flow. Not unique. + FlowName *string + // The id of a batch. Unique within a flow. + BatchId *int64 + // The id of the request that caused an update. + RequestId *string + // The Unity Catalog id of the MV or ST being updated. + UcResourceId *string + // The optional host name where the event was triggered + Host *string + // Materialization name. + MaterializationName *string + // The name of the source UC connection (if known) from whose data ingestion is + // described by this event. + IngestionSourceConnectionName *string + // The name of the source catalog name (if known) from whose data ingestion is + // described by this event. + IngestionSourceCatalogName *string + // The name of the source schema name (if known) from whose data ingestion is + // described by this event. + IngestionSourceSchemaName *string + // The name of the source table name (if known) from whose data ingestion is + // described by this event. + IngestionSourceTableName *string + // An optional implementation-defined source table version of a dataset being + // (re)ingested. + IngestionSourceTableVersion *string +} + +// Outlook specific options for ingestion. +type OutlookOptions struct { + // Deprecated. Use include_folders instead. + FolderFilter []string + // Deprecated. Use include_senders instead. + SenderFilter []string + // Deprecated. Use include_subjects instead. + SubjectFilter []string + // (Optional) Start date for the initial sync in YYYY-MM-DD format. Format: + // YYYY-MM-DD (e.g., 2024-01-01) This determines the earliest date from which to + // sync historical data. If not specified, complete history is ingested. + StartDate *string + // (Optional) Defines how the body_content column is populated. TEXT_HTML: + // Preserves full formatting, links, and styling. TEXT_PLAIN: Converts body to + // plain text. Recommended for AI/RAG pipelines to reduce token usage and noise. + BodyFormat OutlookBodyFormat + // (Optional) Controls which attachments to ingest. If not specified, defaults + // to ALL. + AttachmentMode OutlookAttachmentMode + // (Optional) List of mailboxes to sync (e.g. mailbox email addresses or + // identifiers). If not specified, all accessible mailboxes are ingested. Filter + // semantics: OR between different mailboxes. + IncludeMailboxes []string + // (Optional) Filter mail folders to include in the sync. If not specified, all + // folders will be synced. Examples: Inbox, Sent Items, Custom_Folder Filter + // semantics: OR between different folders. + IncludeFolders []string + // (Optional) Filter emails by sender address. Uses exact email match. Examples: + // user@vendor.com, alerts@system.io, noreply@company.com If not specified, + // emails from all senders will be synced. Filter semantics: OR between + // different senders. + IncludeSenders []string + // (Optional) Filter emails by subject line. Values ending with "*" use prefix + // match (subject starts with the part before "*"); otherwise substring match + // (subject contains the value). Examples: "Invoice" (substring), "Re:*" + // (prefix), "Support Ticket", "URGENT*" If not specified, emails with all + // subjects will be synced. Filter semantics: OR between different subjects. + IncludeSubjects []string +} + +type PathPattern struct { + // The source code to include for pipelines + Include *string +} + +type PipelineCluster struct { + // A label for the cluster specification, either `default` to configure the + // default cluster, or `maintenance` to configure the maintenance cluster. This + // field is optional. The default value is `default`. + Label *string + // Note: This field won't be persisted. Only API users will check this field. + ApplyPolicyDefaultValues *bool + // An object containing a set of optional, user-specified Spark configuration + // key-value pairs. See :method:clusters/create for more details. + SparkConf map[string]string + // Attributes related to clusters running on Amazon Web Services. If not + // specified at cluster creation, a set of default values will be used. + AwsAttributes *PipelinesAwsAttributes + // Attributes related to clusters running on Microsoft Azure. If not specified + // at cluster creation, a set of default values will be used. + AzureAttributes *PipelinesAzureAttributes + // Attributes related to clusters running on Google Cloud Platform. If not + // specified at cluster creation, a set of default values will be used. + GcpAttributes *PipelinesGcpAttributes + // This field encodes, through a single value, the resources available to each + // of the Spark nodes in this cluster. For example, the Spark nodes can be + // provisioned and optimized for memory or compute intensive workloads. A list + // of available node types can be retrieved by using the + // :method:clusters/listNodeTypes API call. + NodeTypeId *string + // The node type of the Spark driver. Note that this field is optional; if + // unset, the driver node type will be set as the same value as `node_type_id` + // defined above. + DriverNodeTypeId *string + // SSH public key contents that will be added to each Spark node in this + // cluster. The corresponding private keys can be used to login with the user + // name `ubuntu` on port `2200`. Up to 10 keys can be specified. + SshPublicKeys []string + // Additional tags for cluster resources. will tag all cluster + // resources (e.g., AWS instances and EBS volumes) with these tags in addition + // to `default_tags`. Notes: + // + // - Currently, allows at most 45 custom tags + // + // - Clusters can only reuse cloud resources if the resources' tags are a subset + // of the cluster tags + CustomTags map[string]string + // The configuration for delivering spark logs to a long-term storage + // destination. Only dbfs destinations are supported. Only one destination can + // be specified for one cluster. If the conf is given, the logs will be + // delivered to the destination every `5 mins`. The destination of driver logs + // is `$destination/$clusterId/driver`, while the destination of executor logs + // is `$destination/$clusterId/executor`. + ClusterLogConf *PipelinesClusterLogConf + // An object containing a set of optional, user-specified environment variable + // key-value pairs. Please note that key-value pair of the form (X,Y) will be + // exported as is (i.e., `export X='Y'`) while launching the driver and workers. + // + // In order to specify an additional set of `SPARK_DAEMON_JAVA_OPTS`, we + // recommend appending them to `$SPARK_DAEMON_JAVA_OPTS` as shown in the example + // below. This ensures that all default databricks managed environmental + // variables are included as well. + // + // Example Spark environment variables: `{"SPARK_WORKER_MEMORY": "28000m", + // "SPARK_LOCAL_DIRS": "/local_disk0"}` or `{"SPARK_DAEMON_JAVA_OPTS": + // "$SPARK_DAEMON_JAVA_OPTS -Dspark.shuffle.service.enabled=true"}` + SparkEnvVars map[string]string + // The configuration for storing init scripts. Any number of destinations can be + // specified. The scripts are executed sequentially in the order provided. If + // `cluster_log_conf` is specified, init script logs are sent to + // `//init_scripts`. + InitScripts []PipelinesInitScriptInfo + // The optional ID of the instance pool to which the cluster belongs. + InstancePoolId *string + // The ID of the cluster policy used to create the cluster if applicable. + PolicyId *string + // Whether to enable local disk encryption for the cluster. + EnableLocalDiskEncryption *bool + // The optional ID of the instance pool for the driver of the cluster belongs. + // The pool cluster uses the instance pool with id (instance_pool_id) if the + // driver pool is not assigned. + DriverInstancePoolId *string + Size isPipelineCluster_Size +} + +type isPipelineCluster_Size interface { + isPipelineCluster_Size() +} + +// PipelineCluster_Size_NumWorkers selects NumWorkers for PipelineCluster.Size. +// Number of worker nodes that this cluster should have. A cluster has one Spark +// Driver and `num_workers` Executors for a total of `num_workers` + 1 Spark +// nodes. +// +// Note: When reading the properties of a cluster, this field reflects the +// desired number of workers rather than the actual current number of workers. +// For instance, if a cluster is resized from 5 to 10 workers, this field will +// immediately be updated to reflect the target size of 10 workers, whereas the +// workers listed in `spark_info` will gradually increase from 5 to 10 as the +// new nodes are provisioned. +type PipelineCluster_Size_NumWorkers struct { + NumWorkers int +} + +func (*PipelineCluster_Size_NumWorkers) isPipelineCluster_Size() {} + +// PipelineCluster_Size_Autoscale selects Autoscale for PipelineCluster.Size. +// Parameters needed in order to automatically scale clusters up and down based +// on load. Note: autoscaling works best with DB runtime versions 3.0 or later. +type PipelineCluster_Size_Autoscale struct { + Autoscale PipelinesAutoScale +} + +func (*PipelineCluster_Size_Autoscale) isPipelineCluster_Size() {} + +type PipelineDeployment struct { + // The deployment method that manages the pipeline. + Kind DeploymentKind + // The path to the file containing metadata about the deployment. + MetadataFilePath *string + // ID of the deployment that manages this pipeline. Only set when `kind` is + // `BUNDLE`. Used to look up deployment metadata from the Deployment Metadata + // service. + DeploymentId *string + // ID of the version of the deployment that produced this pipeline. Only set + // when `kind` is `BUNDLE`. Identifies a specific snapshot of the deployment in + // the Deployment Metadata service. + VersionId *string +} + +type PipelineEvent struct { + // A time-based, globally unique id. + Id *string + // A sequencing object to identify and order events. + Sequence *Sequencing + // Describes where the event originates from. + Origin *Origin + // The time of the event. + Timestamp *string + // The display message associated with the event. + Message *string + // The severity level of the event. + Level EventLevel + // Information about an error captured by the event. + Error *ErrorDetail + // The event type. Should always correspond to the details + EventType *string + // Maturity level for event_type. + MaturityLevel MaturityLevel + // Information about which fields were truncated from this event due to size + // constraints. If empty or absent, no truncation occurred. See + // https://docs.databricks.com/en/ldp/monitor-event-logs for information on + // retrieving complete event data. + Truncation *Truncation +} + +type PipelineLibrary struct { + Lib isPipelineLibrary_Lib +} + +type isPipelineLibrary_Lib interface { + isPipelineLibrary_Lib() +} + +// PipelineLibrary_Lib_Jar selects Jar for PipelineLibrary.Lib. +// URI of the jar to be installed. Currently only DBFS is supported. +type PipelineLibrary_Lib_Jar struct { + Jar string +} + +func (*PipelineLibrary_Lib_Jar) isPipelineLibrary_Lib() {} + +// PipelineLibrary_Lib_Maven selects Maven for PipelineLibrary.Lib. +// Specification of a maven library to be installed. +type PipelineLibrary_Lib_Maven struct { + Maven PipelinesMavenLibrary +} + +func (*PipelineLibrary_Lib_Maven) isPipelineLibrary_Lib() {} + +// PipelineLibrary_Lib_Whl selects Whl for PipelineLibrary.Lib. +// URI of the whl to be installed. +type PipelineLibrary_Lib_Whl struct { + Whl string +} + +func (*PipelineLibrary_Lib_Whl) isPipelineLibrary_Lib() {} + +// PipelineLibrary_Lib_Notebook selects Notebook for PipelineLibrary.Lib. +// The path to a notebook that defines a pipeline and is stored in the +// workspace. +type PipelineLibrary_Lib_Notebook struct { + Notebook NotebookLibrary +} + +func (*PipelineLibrary_Lib_Notebook) isPipelineLibrary_Lib() {} + +// PipelineLibrary_Lib_File selects File for PipelineLibrary.Lib. +// The path to a file that defines a pipeline and is stored in the Databricks +// Repos. +type PipelineLibrary_Lib_File struct { + File NotebookLibrary +} + +func (*PipelineLibrary_Lib_File) isPipelineLibrary_Lib() {} + +// PipelineLibrary_Lib_Glob selects Glob for PipelineLibrary.Lib. +// The unified field to include source codes. Each entry can be a notebook path, +// a file path, or a folder path that ends `/**`. This field cannot be used +// together with `notebook` or `file`. +type PipelineLibrary_Lib_Glob struct { + Glob PathPattern +} + +func (*PipelineLibrary_Lib_Glob) isPipelineLibrary_Lib() {} + +type PipelineSpec struct { + // Unique identifier for this pipeline. + Id *string + // Friendly identifier for this pipeline. + Name *string + // DBFS root directory for storing checkpoints and tables. + Storage *string + // String-String configuration for this pipeline execution. + Configuration map[string]string + // Cluster settings for this pipeline deployment. + Clusters []PipelineCluster + // Libraries or code needed by this deployment. + Libraries []PipelineLibrary + // The configuration for a managed ingestion pipeline. These settings cannot be + // used with the 'libraries', 'schema', 'target', or 'catalog' settings. + IngestionDefinition *IngestionPipelineDefinition + // The definition of a gateway pipeline to support change data capture. + GatewayDefinition *IngestionGatewayPipelineDefinition + // Which pipeline trigger to use. Deprecated: Use `continuous` instead. + Trigger *PipelineTrigger + // Target schema (database) to add tables in this pipeline to. Exactly one of + // `schema` or `target` must be specified. To publish to Unity Catalog, also + // specify `catalog`. This legacy field is deprecated for pipeline creation in + // favor of the `schema` field. + Target *string + // The default schema (database) where tables are read from or published to. + Schema *string + // Filters on which Pipeline packages to include in the deployed graph. + Filters *Filters + // Whether the pipeline is continuous or triggered. This replaces `trigger`. + // + // Deprecated: wrap the pipeline in a continuous job instead, which also lets + // you take advantage of job-level settings such as performance mode. When the + // pipeline is started by a continuous job, the job's setting takes precedence + // and this field is ignored. + Continuous *bool + // Whether the pipeline is in Development mode. Defaults to false. + Development *bool + // Whether Photon is enabled for this pipeline. + Photon *bool + // Pipeline product edition. + Edition *string + // SDP Release Channel that specifies which version to use. + Channel *string + // A catalog in Unity Catalog to publish data from this pipeline to. If `target` + // is specified, tables in this pipeline are published to a `target` schema + // inside `catalog` (for example, `catalog`.`target`.`table`). If `target` is + // not specified, no data is published to Unity Catalog. + Catalog *string + // List of notification settings for this pipeline. + Notifications []Notifications + // Whether serverless compute is enabled for this pipeline. + Serverless *bool + // Deployment type of this pipeline. + Deployment *PipelineDeployment + // Restart window of this pipeline. + RestartWindow *RestartWindow + // Budget policy of this pipeline. + BudgetPolicyId *string + // A map of tags associated with the pipeline. These are forwarded to the + // cluster as cluster tags, and are therefore subject to the same limitations. A + // maximum of 25 tags can be added to the pipeline. + Tags map[string]string + // Event log configuration for this pipeline + EventLog *EventLogSpec + // Root path for this pipeline. This is used as the root directory when editing + // the pipeline in the user interface and it is added to sys.path + // when executing Python sources during pipeline execution. + RootPath *string + // Environment specification for this pipeline used to install dependencies. + Environment *PipelinesEnvironment + // Usage policy of this pipeline. + UsagePolicyId *string + // Serverless compute ID specified by the user for serverless pipelines. + ServerlessComputeId *string +} + +type PipelineState struct { +} + +type PipelineStateInfo struct { + // The unique identifier of the pipeline. + PipelineId *string + State PipelineState_PipelineState + // The unique identifier of the cluster running the pipeline. + ClusterId *string + // The user-friendly name of the pipeline. + Name *string + // Status of the latest updates for the pipeline. Ordered with the newest update + // first. + LatestUpdates []UpdateStateInfo + // The username of the pipeline creator. + CreatorUserName *string + // The username that the pipeline runs as. This is a read only value derived + // from the pipeline owner. + RunAsUserName *string + // The health of a pipeline. + Health PipelineHealthStatus +} + +type PipelineTrigger struct { + Trigger isPipelineTrigger_Trigger +} + +type isPipelineTrigger_Trigger interface { + isPipelineTrigger_Trigger() +} + +// PipelineTrigger_Trigger_Manual selects Manual for PipelineTrigger.Trigger. +type PipelineTrigger_Trigger_Manual struct { + Manual ManualTrigger +} + +func (*PipelineTrigger_Trigger_Manual) isPipelineTrigger_Trigger() {} + +// PipelineTrigger_Trigger_Cron selects Cron for PipelineTrigger.Trigger. +type PipelineTrigger_Trigger_Cron struct { + Cron CronTrigger +} + +func (*PipelineTrigger_Trigger_Cron) isPipelineTrigger_Trigger() {} + +type PipelinesAutoScale struct { + // The minimum number of workers the cluster can scale down to when + // underutilized. It is also the initial number of workers the cluster will have + // after creation. + MinWorkers *int + // The maximum number of workers to which the cluster can scale up when + // overloaded. `max_workers` must be strictly greater than `min_workers`. + MaxWorkers *int + // Databricks Enhanced Autoscaling optimizes cluster utilization by + // automatically allocating cluster resources based on workload volume, with + // minimal impact to the data processing latency of your pipelines. Enhanced + // Autoscaling is available for `updates` clusters only. The legacy autoscaling + // feature is used for `maintenance` clusters. + Mode *string +} + +// Attributes set during cluster creation which are related to Amazon Web +// Services.. +type PipelinesAwsAttributes struct { + // The first ``first_on_demand`` nodes of the cluster will be placed on + // on-demand instances. If this value is greater than 0, the cluster driver node + // in particular will be placed on an on-demand instance. If this value is + // greater than or equal to the current cluster size, all nodes will be placed + // on on-demand instances. If this value is less than the current cluster size, + // ``first_on_demand`` nodes will be placed on on-demand instances and the + // remainder will be placed on ``availability`` instances. Note that this value + // does not affect cluster size and cannot currently be mutated over the + // lifetime of a cluster. + FirstOnDemand *int + // Availability type used for all subsequent nodes past the ``first_on_demand`` + // ones. Note: If ``first_on_demand`` is zero, this availability type will be + // used for the entire cluster. + Availability PipelinesAwsAvailability + // Identifier for the availability zone/datacenter in which the cluster resides. + // This string will be of a form like "us-west-2a". The provided availability + // zone must be in the same region as the deployment. For example, + // "us-west-2a" is not a valid zone id if the deployment resides in + // the "us-east-1" region. This is an optional field at cluster creation, and if + // not specified, a default zone will be used. If the zone specified is "auto", + // will try to place cluster in a zone with high availability, and will retry + // placement in a different AZ if there is not enough capacity. See + // [[AutoAZHelper.scala]] for more details. The list of available zones as well + // as the default value can be found by using the `List Zones`_ method. + ZoneId *string + // Nodes for this cluster will only be placed on AWS instances with this + // instance profile. If omitted, nodes will be placed on instances without an + // IAM instance profile. The instance profile must have previously been added to + // the environment by an account administrator. + // + // This feature may only be available to certain customer plans. + // + // ***internal If this field is ommitted, we will pull in the default from the + // conf if it exists. + InstanceProfileArn *string + // The bid price for AWS spot instances, as a percentage of the corresponding + // instance type's on-demand price. For example, if this field is set to 50, and + // the cluster needs a new ``r3.xlarge`` spot instance, then the bid price is + // half of the price of on-demand ``r3.xlarge`` instances. Similarly, if this + // field is set to 200, the bid price is twice the price of on-demand + // ``r3.xlarge`` instances. If not specified, the default value is 100. When + // spot instances are requested for this cluster, only spot instances whose bid + // price percentage matches this field will be considered. Note that, for + // safety, we enforce this field to be no more than 10000. + // + // ***internal The default value and documentation here should be kept + // consistent with CommonConf.defaultSpotBidPricePercent and + // CommonConf.maxSpotBidPricePercent. + SpotBidPricePercent *int + // The type of EBS volumes that will be launched with this cluster. + EbsVolumeType PipelinesEbsVolumeType + // The number of volumes launched for each instance. Users can choose up to 10 + // volumes. This feature is only enabled for supported node types. Legacy node + // types cannot specify custom EBS volumes. For node types with no instance + // store, at least one EBS volume needs to be specified; otherwise, cluster + // creation will fail. + // + // These EBS volumes will be mounted at ``/ebs0``, ``/ebs1``, and etc. Instance + // store volumes will be mounted at ``/local_disk0``, ``/local_disk1``, and etc. + // + // If EBS volumes are attached, will configure Spark to use only + // the EBS volumes for scratch storage because heterogeneously sized scratch + // devices can lead to inefficient disk utilization. If no EBS volumes are + // attached, will configure Spark to use instance store volumes. + // + // Please note that if EBS volumes are specified, then the Spark configuration + // ``spark.local.dir`` will be overridden. + EbsVolumeCount *int + // The size of each EBS volume (in GiB) launched for each instance. For general + // purpose SSD, this value must be within the range 100 - 4096. For throughput + // optimized HDD, this value must be within the range 500 - 4096. + EbsVolumeSize *int + EbsVolumeIops *int + EbsVolumeThroughput *int +} + +// Attributes set during cluster creation which are related to Azure.. +type PipelinesAzureAttributes struct { + // The first ``first_on_demand`` nodes of the cluster will be placed on + // on-demand instances. This value should be greater than 0, to make sure the + // cluster driver node is placed on an on-demand instance. If this value is + // greater than or equal to the current cluster size, all nodes will be placed + // on on-demand instances. If this value is less than the current cluster size, + // ``first_on_demand`` nodes will be placed on on-demand instances and the + // remainder will be placed on ``availability`` instances. Note that this value + // does not affect cluster size and cannot currently be mutated over the + // lifetime of a cluster. + FirstOnDemand *int + // Availability type used for all subsequent nodes past the ``first_on_demand`` + // ones. Note: If ``first_on_demand`` is zero (which only happens on pool + // clusters), this availability type will be used for the entire cluster. + Availability PipelinesAzureAvailability + // The max bid price to be used for Azure spot instances. The Max price for the + // bid cannot be higher than the on-demand price of the instance. If not + // specified, the default value is -1, which specifies that the instance cannot + // be evicted on the basis of price, and only on the basis of availability. + // Further, the value should > 0 or -1. + SpotBidMaxPrice *float64 +} + +// Cluster log delivery config. +type PipelinesClusterLogConf struct { + StorageInfo isPipelinesClusterLogConf_StorageInfo +} + +type isPipelinesClusterLogConf_StorageInfo interface { + isPipelinesClusterLogConf_StorageInfo() +} + +// PipelinesClusterLogConf_StorageInfo_Dbfs selects Dbfs for PipelinesClusterLogConf.StorageInfo. +// destination needs to be provided. e.g. “{ "dbfs" : { "destination" : +// "dbfs:/home/cluster_log" } }“ +type PipelinesClusterLogConf_StorageInfo_Dbfs struct { + Dbfs PipelinesDbfsStorageInfo +} + +func (*PipelinesClusterLogConf_StorageInfo_Dbfs) isPipelinesClusterLogConf_StorageInfo() {} + +// A storage location in DBFS. +type PipelinesDbfsStorageInfo struct { + // dbfs destination, e.g. ``dbfs:/my/path`` + Destination *string +} + +// The environment entity used to preserve serverless environment side panel, +// jobs' environment for non-notebook task, and SDP's environment for classic +// and serverless pipelines. In this minimal environment spec, only pip +// dependencies are supported.. +type PipelinesEnvironment struct { + // List of pip dependencies, as supported by the version of pip in this + // environment. Each dependency is a pip requirement file line + // https://pip.pypa.io/en/stable/reference/requirements-file-format/ Allowed + // dependency could be , , (WSFS or Volumes in ), + Dependencies []string + // The environment version of the serverless Python environment used to execute + // customer Python code. Each environment version includes a specific Python + // version and a curated set of pre-installed libraries with defined versions, + // providing a stable and reproducible execution environment. + // + // supports a three-year lifecycle for each environment version. + // For available versions and their included packages, see + // https://docs.databricks.com/aws/en/release-notes/serverless/environment-version/ + // + // The value should be a string representing the environment version number, for + // example: `"4"`. + EnvironmentVersion *string +} + +// Attributes set during cluster creation which are related to Gcp.. +type PipelinesGcpAttributes struct { + // If provided, the cluster will impersonate the google service account when + // accessing gcloud services (like GCS). The google service account must have + // previously been added to the environment by an account + // administrator. + GoogleServiceAccount *string + // boot disk size in GB + BootDiskSize *int + // This field determines whether the spark executors will be scheduled to run on + // preemptible VMs, on-demand VMs, or preemptible VMs with a fallback to + // on-demand VMs if the former is unavailable. + Availability PipelinesGcpAvailability + // Identifier for the availability zone in which the cluster resides. This can + // be one of the following: - "HA" => High availability, spread nodes across + // availability zones for a deployment region [default]. - "AUTO" + // => picks an availability zone to schedule the cluster on. - A + // GCP availability zone => Pick One of the available zones for (machine type + + // region) from https://cloud.google.com/compute/docs/regions-zones. + ZoneId *string + // The number of local SSDs to attach to each worker and driver for this + // cluster. If left unspecified, the default number of local SSDs for the node + // type will be used. + // + // NOTE: Each instance type can only support a certain number of attached local + // SSDs. The value specified in local_ssd_count must be valid for BOTH the + // driver and worker instance type. See GCP docs here: + // https://cloud.google.com/compute/docs/disks#local_ssd_machine_type_restrictions + // + // Validation is performed at the RPC layer and the RPC will be rejected if the + // specified local_ssd_count is invalid. + LocalSsdCount *int +} + +// Config for an individual init script. +type PipelinesInitScriptInfo struct { + StorageInfo isPipelinesInitScriptInfo_StorageInfo +} + +type isPipelinesInitScriptInfo_StorageInfo interface { + isPipelinesInitScriptInfo_StorageInfo() +} + +// PipelinesInitScriptInfo_StorageInfo_Dbfs selects Dbfs for PipelinesInitScriptInfo.StorageInfo. +// destination needs to be provided. e.g. “{ "dbfs" : { "destination" : +// "dbfs:/init-scripts/my_script.sh" } }“ +type PipelinesInitScriptInfo_StorageInfo_Dbfs struct { + Dbfs PipelinesDbfsStorageInfo +} + +func (*PipelinesInitScriptInfo_StorageInfo_Dbfs) isPipelinesInitScriptInfo_StorageInfo() {} + +// PipelinesInitScriptInfo_StorageInfo_S3 selects S3 for PipelinesInitScriptInfo.StorageInfo. +// destination and either region or endpoint should also be provided. e.g. “{ +// "s3": { "destination" : "s3://init-scripts/my_script.sh", "region" : +// "us-west-2" } }“ Cluster iam role is used to access s3, please make sure the +// cluster iam role in “instance_profile_arn“ has permission to write data to +// the s3 destination. +type PipelinesInitScriptInfo_StorageInfo_S3 struct { + S3 PipelinesS3StorageInfo +} + +func (*PipelinesInitScriptInfo_StorageInfo_S3) isPipelinesInitScriptInfo_StorageInfo() {} + +// Write-only setting, available only in Create/Update calls. Specifies the user +// or service principal that the pipeline runs as. If not specified, the +// pipeline runs as the user who created the pipeline. +// +// Only `user_name` or `service_principal_name` can be specified. If both are +// specified, an error is thrown.. +type PipelinesJobRunAs struct { + Identity isPipelinesJobRunAs_Identity +} + +type isPipelinesJobRunAs_Identity interface { + isPipelinesJobRunAs_Identity() +} + +// PipelinesJobRunAs_Identity_UserName selects UserName for PipelinesJobRunAs.Identity. +// The email of an active workspace user. Users can only set this field to their +// own email. +type PipelinesJobRunAs_Identity_UserName struct { + UserName string +} + +func (*PipelinesJobRunAs_Identity_UserName) isPipelinesJobRunAs_Identity() {} + +// PipelinesJobRunAs_Identity_ServicePrincipalName selects ServicePrincipalName for PipelinesJobRunAs.Identity. +// Application ID of an active service principal. Setting this field requires +// the `servicePrincipal/user` role. +type PipelinesJobRunAs_Identity_ServicePrincipalName struct { + ServicePrincipalName string +} + +func (*PipelinesJobRunAs_Identity_ServicePrincipalName) isPipelinesJobRunAs_Identity() {} + +type PipelinesMavenLibrary struct { + // Gradle-style maven coordinates. For example: "org.jsoup:jsoup:1.7.2". + Coordinates *string + // Maven repo to install the Maven package from. If omitted, both Maven Central + // Repository and Spark Packages are searched. + Repo *string + // List of dependencies to exclude. For example: `["slf4j:slf4j", + // "*:hadoop-client"]`. + // + // Maven dependency exclusions: + // https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html. + Exclusions []string +} + +// A storage location in Amazon S3. +type PipelinesS3StorageInfo struct { + // S3 destination, e.g. ``s3://my-bucket/some-prefix`` Note that logs will be + // delivered using cluster iam role, please make sure you set cluster iam role + // and the role has write access to the destination. Please also note that you + // cannot use AWS keys to deliver logs. + Destination *string + // S3 region, e.g. ``us-west-2``. Either region or endpoint needs to be set. If + // both are set, endpoint will be used. + Region *string + // S3 endpoint, e.g. ``https://s3-us-west-2.amazonaws.com``. Either region or + // endpoint needs to be set. If both are set, endpoint will be used. + Endpoint *string + // Flag to enable server side encryption, ``false`` by default. + EnableEncryption *bool + // The encryption type, it could be ``sse-s3`` or ``sse-kms``. It will be used + // only when encryption is enabled and the default type is ``sse-s3``. + EncryptionType *string + // Kms key which will be used if encryption is enabled and encryption type is + // set to ``sse-kms``. + KmsKey *string + // Set canned access control list for the logs, e.g. + // ``bucket-owner-full-control``. If ``canned_cal`` is set, please make sure the + // cluster iam role has ``s3:PutObjectAcl`` permission on the destination bucket + // and prefix. The full list of possible canned acl can be found at + // http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl. + // Please also note that by default only the object owner gets full controls. If + // you are using cross account role for writing data, you may want to set + // ``bucket-owner-full-control`` to make bucket owner able to read the logs. + CannedAcl *string +} + +// PG-specific catalog-level configuration parameters. +type PostgresCatalogConfig struct { + // Optional. The Postgres slot configuration to use for logical replication + SlotConfig *PostgresSlotConfig +} + +// PostgresSlotConfig contains the configuration for a Postgres logical +// replication slot. +type PostgresSlotConfig struct { + // The name of the logical replication slot to use for the Postgres source + SlotName *string + // The name of the publication to use for the Postgres source + PublicationName *string +} + +// Reddit Ads specific options for ingestion. +type RedditAdsOptions struct { + // (Optional) Start date for the initial sync of report tables in YYYY-MM-DD + // format. This determines the earliest date from which to sync historical data. + // If not specified, defaults to 2 years ago. + SyncStartDate *string + // (Optional) Number of days to look back for report tables during incremental + // sync to capture late-arriving conversions and attribution data. If not + // specified, defaults to 30 days. + LookbackWindowDays *int + // (Optional) Custom report definition. When set, the table is treated as a + // user-defined Reddit Ads custom report. When unset, the table must match one + // of the connector's prebuilt sources. + CustomReportOptions *RedditAdsOptions_RedditAdsCustomReportOptions +} + +// User-defined custom report for the Reddit Ads connector. Applies only to the +// custom_report table — prebuilt tables ignore this.. +type RedditAdsOptions_RedditAdsCustomReportOptions struct { + // (Optional) Fields to include in the report (maps to the Reddit Ads API + // `fields` parameter). Examples: IMPRESSIONS, CLICKS, SPEND, CPC, CTR. + Fields []string + // (Optional) Breakdown dimensions to group report data by. Examples: + // CAMPAIGN_ID, DATE, COUNTRY, REGION, AD_ID. Must include at least one time + // dimension (DATE or HOUR). + Breakdowns []string +} + +// Specifies a replace_where predicate override for a replace where flow.. +type ReplaceWhereOverride struct { + // Name of the flow to apply this override to. + FlowName *string + // SQL predicate string to use as replace_where condition. Example: `date = + // '2024-10-10' AND city = 'xyz'` + PredicateOverride *string +} + +type RestartWindow struct { + // An integer between 0 and 23 denoting the start hour for the restart window in + // the 24-hour day. Continuous pipeline restart is triggered only within a + // five-hour window starting at this hour. + StartHour *int + // Days of week in which the restart is allowed to happen (within a five-hour + // window starting at start_hour). If not specified all days of the week will be + // used. + DaysOfWeek []DayOfWeek + // Time zone id of restart window. See + // https://docs.databricks.com/sql/language-manual/sql-ref-syntax-aux-conf-mgmt-set-timezone.html + // for details. If not specified, UTC will be used. + TimeZoneId *string +} + +// Configuration for rewinding a specific dataset.. +type RewindDatasetSpec struct { + // The identifier of the dataset (e.g., "main.foo.tbl1"). + Identifier *string + // Whether to cascade the rewind to dependent datasets. Must be specified. + Cascade *bool + // Whether to reset checkpoints for this dataset. + ResetCheckpoints *bool +} + +// Information about a rewind being requested for this pipeline or some of the +// datasets in it.. +type RewindSpec struct { + // The base timestamp to rewind to. Exactly one of rewind_timestamp or + // rewind_point_id must be specified. + RewindTimestamp *string + // If true, this is a dry run and we should emit the RewindSummary but not + // perform the rewind. + DryRun *bool + // List of datasets to rewind with specific configuration for each. When not + // specified, all datasets will be rewound with cascade = true and + // reset_checkpoints = true. + Datasets []RewindDatasetSpec +} + +type ScdType struct { +} + +type Sequencing struct { + // the ID assigned by the data plane. + DataPlaneId *DataPlaneId + // A sequence number, unique and increasing per pipeline. + ControlPlaneSeqNo *int64 +} + +type SerializedException struct { + // Runtime class of the exception + ClassName *string + // Exception message + Message *string + // Stack trace consisting of a list of stack frames + Stack []StackFrame +} + +type SharepointOptions struct { + // Required. The SharePoint URL. + Url *string + // (Optional) The type of SharePoint entity to ingest. If not specified, + // defaults to FILE. + EntityType SharepointOptions_SharepointEntityType + // (Optional) File ingestion options for processing files. + FileIngestionOptions *FileIngestionOptions +} + +// Smartsheet specific options for ingestion. +type SmartsheetOptions struct { + // (Optional) When true, maps each column to its Smartsheet-declared type + // (Text/Number/Date/ Checkbox/etc.). Cells that do not conform to the declared + // type are set to NULL. When false, all columns land as STRING. Use false for + // sheets with irregular data or columns that frequently violate their own + // declared type. If not specified, defaults to true. + EnforceSchema *bool +} + +// SourceCatalogConfig contains catalog-level custom configuration parameters +// for each source. +type SourceCatalogConfig struct { + // Source catalog name + SourceCatalog *string + // Configuration options for the source catalog + Options isSourceCatalogConfig_Options +} + +type isSourceCatalogConfig_Options interface { + isSourceCatalogConfig_Options() +} + +// SourceCatalogConfig_Options_Postgres selects Postgres for SourceCatalogConfig.Options. +// Postgres-specific catalog-level configuration parameters +type SourceCatalogConfig_Options_Postgres struct { + Postgres PostgresCatalogConfig +} + +func (*SourceCatalogConfig_Options_Postgres) isSourceCatalogConfig_Options() {} + +type SourceConfig struct { + // Catalog-level source configuration parameters + Catalog *SourceCatalogConfig + // Connector-specific top-level configuration. Values here act as defaults and + // can be overridden by the same field in the object-level connector_options. + ConnectorConfig isSourceConfig_ConnectorConfig +} + +type isSourceConfig_ConnectorConfig interface { + isSourceConfig_ConnectorConfig() +} + +// SourceConfig_ConnectorConfig_GoogleAdsConfig selects GoogleAdsConfig for SourceConfig.ConnectorConfig. +type SourceConfig_ConnectorConfig_GoogleAdsConfig struct { + GoogleAdsConfig GoogleAdsConfig +} + +func (*SourceConfig_ConnectorConfig_GoogleAdsConfig) isSourceConfig_ConnectorConfig() {} + +// SourceConfig_ConnectorConfig_ApiSourceConnectorConfig selects ApiSourceConnectorConfig for SourceConfig.ConnectorConfig. +// Connector-specific top-level configuration for API Source connectors. +type SourceConfig_ConnectorConfig_ApiSourceConnectorConfig struct { + ApiSourceConnectorConfig ApiSourceConnectorConfig +} + +func (*SourceConfig_ConnectorConfig_ApiSourceConnectorConfig) isSourceConfig_ConnectorConfig() {} + +type StackFrame struct { + // Class from which the method call originated + DeclaringClass *string + // Name of the method which was called + MethodName *string + // File where the method is defined + FileName *string + // Line from which the method was called + LineNumber *int +} + +type StartUpdateRequest struct { + PipelineId *string + // If true, this update will reset all tables before running. + FullRefresh *bool + Cause UpdateCause + // A list of tables to update without fullRefresh. If both refresh_selection and + // full_refresh_selection are empty, this is a full graph update. Full Refresh + // on a table means that the states of the table will be reset before the + // refresh. + RefreshSelection []string + // A list of tables to update with fullRefresh. If both refresh_selection and + // full_refresh_selection are empty, this is a full graph update. Full Refresh + // on a table means that the states of the table will be reset before the + // refresh. + FullRefreshSelection []string + // A list of flows for which this update should reset the streaming checkpoint. + // This selection will not clear the data in the flow's target table. Flows in + // this list may also appear in refresh_selection and full_refresh_selection. + ResetCheckpointSelection []string + // If true, this update only validates the correctness of pipeline source code + // but does not materialize or publish any datasets. + ValidateOnly *bool + // The information about the requested rewind operation. If specified this is a + // rewind mode update. + RewindSpec *RewindSpec + // Key/value map of parameters to pass to the pipeline execution + Parameters map[string]string + // A list of predicate overrides for replace_where flows in this update. Only + // replace_where flows may be specified. Flows not listed use their original + // predicate. + ReplaceWhereOverrides []ReplaceWhereOverride +} + +type StartUpdateResponse struct { + UpdateId *string +} + +type StopPipelineRequest struct { + PipelineId *string +} + +type StopPipelineResponse struct { +} + +// TikTok Ads specific options for ingestion. +type TikTokAdsOptions struct { + // (Optional) Number of days to look back for report tables during incremental + // sync to capture late-arriving conversions and attribution data. + LookbackWindowDays *int + // (Optional) Start date for the initial sync of report tables in YYYY-MM-DD + // format. This determines the earliest date from which to sync historical data. + SyncStartDate *string + // Deprecated. Use custom_report_options.dimensions instead. + Dimensions []string + // Deprecated. Use custom_report_options.metrics instead. + Metrics []string + // Deprecated. Use custom_report_options.report_type instead. + ReportType TikTokAdsOptions_TikTokReportType + // Deprecated. Use custom_report_options.data_level instead. + DataLevel TikTokAdsOptions_TikTokDataLevel + // Deprecated. Use custom_report_options.query_lifetime instead. + QueryLifetime *bool + // (Optional) Custom report definition. When set, the table is treated as a + // user-defined TikTok Ads custom report: the connector synthesizes a report + // request from the dimensions, metrics, report type, and data level specified + // here. Supersedes the deprecated top-level dimensions/metrics/report_type/ + // data_level/query_lifetime fields above. + CustomReportOptions *TikTokAdsOptions_TikTokAdsCustomReportOptions +} + +// User-defined custom report for the TikTok Ads connector. Groups the +// dimensions + metrics + report type + data level that define a TikTok Ads +// custom report request.. +type TikTokAdsOptions_TikTokAdsCustomReportOptions struct { + // (Optional) Dimensions to include in the report (e.g. "campaign_id", + // "adgroup_id", "ad_id", "stat_time_day", "stat_time_hour"). + Dimensions []string + // (Optional) Metrics to include in the report (e.g. "spend", "impressions", + // "clicks", "conversion", "cpc"). + Metrics []string + // (Optional) Report type for the TikTok Ads API. If not specified, defaults to + // BASIC. + ReportType TikTokAdsOptions_TikTokReportType + // (Optional) Data level for the report. If not specified, defaults to + // AUCTION_CAMPAIGN. + DataLevel TikTokAdsOptions_TikTokDataLevel + // (Optional) Whether to request lifetime metrics (all-time aggregated data). + // When true, the report returns all-time data. If not specified, defaults to + // false. + QueryLifetime *bool +} + +// Specifies how to transform binary data into structured data.. +type Transformer struct { + // Required: the wire format of the data. + Format Transformer_Format + // Format-specific configuration. Only required for JSON, Avro, and Protobuf. + // STRING format requires no additional config. + Config isTransformer_Config + // Optional input column to transform. When set, the transformer reads from this + // column instead of the default source column. + InputColumn *string + // Optional output column name. When set, the transformed result is written to + // this column instead of replacing the input column. + OutputColumn *string +} + +type isTransformer_Config interface { + isTransformer_Config() +} + +// Transformer_Config_JsonOptions selects JsonOptions for Transformer.Config. +type Transformer_Config_JsonOptions struct { + JsonOptions JsonTransformerOptions +} + +func (*Transformer_Config_JsonOptions) isTransformer_Config() {} + +// Information about truncations applied to this event.. +type Truncation struct { + // List of fields that were truncated from this event. If empty or absent, no + // truncation occurred. + TruncatedFields []Truncation_TruncationDetail +} + +// Details about a specific field that was truncated.. +type Truncation_TruncationDetail struct { + // The name of the truncated field (e.g., "error"). Corresponds to field names + // in PipelineEvent. + FieldName *string +} + +type UpdateInfo struct { + // The ID of the pipeline. + PipelineId *string + // The ID of this update. + UpdateId *string + // The pipeline configuration with system defaults applied where unspecified by + // the user. Not returned by ListUpdates. + Config *PipelineSpec + // What triggered this update. + Cause UpdateCause + // The update state. + State UpdateState + // The ID of the cluster that the update is running on. + ClusterId *string + // The time when this update was created. + CreationTime *int64 + // If true, this update will reset all tables before running. + FullRefresh *bool + // A list of tables to update without fullRefresh. If both refresh_selection and + // full_refresh_selection are empty, this is a full graph update. Full Refresh + // on a table means that the states of the table will be reset before the + // refresh. + RefreshSelection []string + // A list of tables to update with fullRefresh. If both refresh_selection and + // full_refresh_selection are empty, this is a full graph update. Full Refresh + // on a table means that the states of the table will be reset before the + // refresh. + FullRefreshSelection []string + // If true, this update only validates the correctness of pipeline source code + // but does not materialize or publish any datasets. + ValidateOnly *bool + // Indicates whether the update is either part of a continuous job run, or + // running in legacy continuous pipeline mode. Returned only for GetUpdate; not + // populated in ListUpdates responses. + Mode UpdateMode + // Key/value map of parameters used to initiate the update + Parameters map[string]string +} + +type UpdateStateInfo struct { + UpdateId *string + State UpdateState + CreationTime *string +} + +// Zendesk Support specific options for ingestion. +type ZendeskSupportOptions struct { + // (Optional) Start date in YYYY-MM-DD format for the initial sync. This + // determines the earliest date from which to sync historical data. + StartDate *string +} diff --git a/pipelines/v2/wire.go b/pipelines/v2/wire.go new file mode 100755 index 0000000..d3d3720 --- /dev/null +++ b/pipelines/v2/wire.go @@ -0,0 +1,4433 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package pipelines + +import ( + "fmt" +) + +type apiSourceConnectorConfigWire struct { + Configs map[string]string `json:"configs,omitempty"` +} + +func apiSourceConnectorConfigToWire(v *ApiSourceConnectorConfig) (*apiSourceConnectorConfigWire, error) { + if v == nil { + return nil, nil + } + return &apiSourceConnectorConfigWire{ + Configs: v.Configs, + }, nil +} + +func apiSourceConnectorConfigFromWire(w *apiSourceConnectorConfigWire) (*ApiSourceConnectorConfig, error) { + if w == nil { + return nil, nil + } + return &ApiSourceConnectorConfig{ + Configs: w.Configs, + }, nil +} + +type apiSourceConnectorOptionsWire struct { + Options map[string]string `json:"options,omitempty"` +} + +func apiSourceConnectorOptionsToWire(v *ApiSourceConnectorOptions) (*apiSourceConnectorOptionsWire, error) { + if v == nil { + return nil, nil + } + return &apiSourceConnectorOptionsWire{ + Options: v.Options, + }, nil +} + +func apiSourceConnectorOptionsFromWire(w *apiSourceConnectorOptionsWire) (*ApiSourceConnectorOptions, error) { + if w == nil { + return nil, nil + } + return &ApiSourceConnectorOptions{ + Options: w.Options, + }, nil +} + +type applyEnvironmentRequestWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` +} + +func applyEnvironmentRequestToWire(v *ApplyEnvironmentRequest) (*applyEnvironmentRequestWire, error) { + if v == nil { + return nil, nil + } + return &applyEnvironmentRequestWire{ + PipelineId: v.PipelineId, + }, nil +} + +type autoFullRefreshPolicyWire struct { + Enabled *bool `json:"enabled,omitempty"` + MinIntervalHours *int `json:"min_interval_hours,omitempty"` +} + +func autoFullRefreshPolicyToWire(v *AutoFullRefreshPolicy) (*autoFullRefreshPolicyWire, error) { + if v == nil { + return nil, nil + } + return &autoFullRefreshPolicyWire{ + Enabled: v.Enabled, + MinIntervalHours: v.MinIntervalHours, + }, nil +} + +func autoFullRefreshPolicyFromWire(w *autoFullRefreshPolicyWire) (*AutoFullRefreshPolicy, error) { + if w == nil { + return nil, nil + } + return &AutoFullRefreshPolicy{ + Enabled: w.Enabled, + MinIntervalHours: w.MinIntervalHours, + }, nil +} + +type clonePipelineRequestWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + ExpectedLastModified *int64 `json:"expected_last_modified,omitempty"` + AllowDuplicateNames *bool `json:"allow_duplicate_names,omitempty"` + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Storage *string `json:"storage,omitempty"` + Configuration map[string]string `json:"configuration,omitempty"` + Clusters []pipelineClusterWire `json:"clusters,omitempty"` + Libraries []pipelineLibraryWire `json:"libraries,omitempty"` + IngestionDefinition *ingestionPipelineDefinitionWire `json:"ingestion_definition,omitempty"` + GatewayDefinition *ingestionGatewayPipelineDefinitionWire `json:"gateway_definition,omitempty"` + Trigger *pipelineTriggerWire `json:"trigger,omitempty"` + Target *string `json:"target,omitempty"` + Schema *string `json:"schema,omitempty"` + Filters *filtersWire `json:"filters,omitempty"` + Continuous *bool `json:"continuous,omitempty"` + Development *bool `json:"development,omitempty"` + Photon *bool `json:"photon,omitempty"` + Edition *string `json:"edition,omitempty"` + Channel *string `json:"channel,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Notifications []notificationsWire `json:"notifications,omitempty"` + Serverless *bool `json:"serverless,omitempty"` + Deployment *pipelineDeploymentWire `json:"deployment,omitempty"` + RestartWindow *restartWindowWire `json:"restart_window,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + Tags map[string]string `json:"tags,omitempty"` + EventLog *eventLogSpecWire `json:"event_log,omitempty"` + RootPath *string `json:"root_path,omitempty"` + Environment *pipelinesEnvironmentWire `json:"environment,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + ServerlessComputeId *string `json:"serverless_compute_id,omitempty"` + CloneMode CloneMode `json:"clone_mode,omitempty"` +} + +func clonePipelineRequestToWire(v *ClonePipelineRequest) (*clonePipelineRequestWire, error) { + if v == nil { + return nil, nil + } + clustersWireValue, err := convertSlice(v.Clusters, pipelineClusterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.Clusters", err) + } + librariesWireValue, err := convertSlice(v.Libraries, pipelineLibraryToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.Libraries", err) + } + ingestionDefinitionWireValue, err := ingestionPipelineDefinitionToWire(v.IngestionDefinition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.IngestionDefinition", err) + } + gatewayDefinitionWireValue, err := ingestionGatewayPipelineDefinitionToWire(v.GatewayDefinition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.GatewayDefinition", err) + } + triggerWireValue, err := pipelineTriggerToWire(v.Trigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.Trigger", err) + } + filtersWireValue, err := filtersToWire(v.Filters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.Filters", err) + } + notificationsWireValue, err := convertSlice(v.Notifications, notificationsToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.Notifications", err) + } + deploymentWireValue, err := pipelineDeploymentToWire(v.Deployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.Deployment", err) + } + restartWindowWireValue, err := restartWindowToWire(v.RestartWindow) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.RestartWindow", err) + } + eventLogWireValue, err := eventLogSpecToWire(v.EventLog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.EventLog", err) + } + environmentWireValue, err := pipelinesEnvironmentToWire(v.Environment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClonePipelineRequest.Environment", err) + } + return &clonePipelineRequestWire{ + PipelineId: v.PipelineId, + ExpectedLastModified: v.ExpectedLastModified, + AllowDuplicateNames: v.AllowDuplicateNames, + Id: v.Id, + Name: v.Name, + Storage: v.Storage, + Configuration: v.Configuration, + Clusters: clustersWireValue, + Libraries: librariesWireValue, + IngestionDefinition: ingestionDefinitionWireValue, + GatewayDefinition: gatewayDefinitionWireValue, + Trigger: triggerWireValue, + Target: v.Target, + Schema: v.Schema, + Filters: filtersWireValue, + Continuous: v.Continuous, + Development: v.Development, + Photon: v.Photon, + Edition: v.Edition, + Channel: v.Channel, + Catalog: v.Catalog, + Notifications: notificationsWireValue, + Serverless: v.Serverless, + Deployment: deploymentWireValue, + RestartWindow: restartWindowWireValue, + BudgetPolicyId: v.BudgetPolicyId, + Tags: v.Tags, + EventLog: eventLogWireValue, + RootPath: v.RootPath, + Environment: environmentWireValue, + UsagePolicyId: v.UsagePolicyId, + ServerlessComputeId: v.ServerlessComputeId, + CloneMode: v.CloneMode, + }, nil +} + +type clonePipelineResponseWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` +} + +func clonePipelineResponseFromWire(w *clonePipelineResponseWire) (*ClonePipelineResponse, error) { + if w == nil { + return nil, nil + } + return &ClonePipelineResponse{ + PipelineId: w.PipelineId, + }, nil +} + +type confluenceConnectorOptionsWire struct { + IncludeConfluenceSpaces []string `json:"include_confluence_spaces,omitempty"` +} + +func confluenceConnectorOptionsToWire(v *ConfluenceConnectorOptions) (*confluenceConnectorOptionsWire, error) { + if v == nil { + return nil, nil + } + return &confluenceConnectorOptionsWire{ + IncludeConfluenceSpaces: v.IncludeConfluenceSpaces, + }, nil +} + +func confluenceConnectorOptionsFromWire(w *confluenceConnectorOptionsWire) (*ConfluenceConnectorOptions, error) { + if w == nil { + return nil, nil + } + return &ConfluenceConnectorOptions{ + IncludeConfluenceSpaces: w.IncludeConfluenceSpaces, + }, nil +} + +type connectionParametersWire struct { + SourceCatalog *string `json:"source_catalog,omitempty"` +} + +func connectionParametersToWire(v *ConnectionParameters) (*connectionParametersWire, error) { + if v == nil { + return nil, nil + } + return &connectionParametersWire{ + SourceCatalog: v.SourceCatalog, + }, nil +} + +func connectionParametersFromWire(w *connectionParametersWire) (*ConnectionParameters, error) { + if w == nil { + return nil, nil + } + return &ConnectionParameters{ + SourceCatalog: w.SourceCatalog, + }, nil +} + +type connectorOptionsWire struct { + GoogleAdsOptions *googleAdsOptionsWire `json:"google_ads_options,omitempty"` + TiktokAdsOptions *tikTokAdsOptionsWire `json:"tiktok_ads_options,omitempty"` + SharepointOptions *sharepointOptionsWire `json:"sharepoint_options,omitempty"` + GdriveOptions *googleDriveOptionsWire `json:"gdrive_options,omitempty"` + OutlookOptions *outlookOptionsWire `json:"outlook_options,omitempty"` + SmartsheetOptions *smartsheetOptionsWire `json:"smartsheet_options,omitempty"` + JiraOptions *jiraConnectorOptionsWire `json:"jira_options,omitempty"` + ConfluenceOptions *confluenceConnectorOptionsWire `json:"confluence_options,omitempty"` + MetaAdsOptions *metaMarketingOptionsWire `json:"meta_ads_options,omitempty"` + ZendeskSupportOptions *zendeskSupportOptionsWire `json:"zendesk_support_options,omitempty"` + KafkaOptions *kafkaOptionsWire `json:"kafka_options,omitempty"` + MarketoOptions *marketoOptionsWire `json:"marketo_options,omitempty"` + LinkedinAdsOptions *linkedInAdsOptionsWire `json:"linkedin_ads_options,omitempty"` + RedditAdsOptions *redditAdsOptionsWire `json:"reddit_ads_options,omitempty"` + ApiSourceConnectorOptions *apiSourceConnectorOptionsWire `json:"api_source_connector_options,omitempty"` +} + +func connectorOptionsToWire(v *ConnectorOptions) (*connectorOptionsWire, error) { + if v == nil { + return nil, nil + } + var connectorOptionsGoogleAdsOptionsWire *googleAdsOptionsWire + var connectorOptionsTiktokAdsOptionsWire *tikTokAdsOptionsWire + var connectorOptionsSharepointOptionsWire *sharepointOptionsWire + var connectorOptionsGdriveOptionsWire *googleDriveOptionsWire + var connectorOptionsOutlookOptionsWire *outlookOptionsWire + var connectorOptionsSmartsheetOptionsWire *smartsheetOptionsWire + var connectorOptionsJiraOptionsWire *jiraConnectorOptionsWire + var connectorOptionsConfluenceOptionsWire *confluenceConnectorOptionsWire + var connectorOptionsMetaAdsOptionsWire *metaMarketingOptionsWire + var connectorOptionsZendeskSupportOptionsWire *zendeskSupportOptionsWire + var connectorOptionsKafkaOptionsWire *kafkaOptionsWire + var connectorOptionsMarketoOptionsWire *marketoOptionsWire + var connectorOptionsLinkedinAdsOptionsWire *linkedInAdsOptionsWire + var connectorOptionsRedditAdsOptionsWire *redditAdsOptionsWire + var connectorOptionsApiSourceConnectorOptionsWire *apiSourceConnectorOptionsWire + switch value := v.ConnectorOptions.(type) { + case nil: + case *ConnectorOptions_ConnectorOptions_GoogleAdsOptions: + if value != nil { + connectorOptionsGoogleAdsOptionsConverted, err := googleAdsOptionsToWire(&value.GoogleAdsOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.GoogleAdsOptions", err) + } + connectorOptionsGoogleAdsOptionsWire = connectorOptionsGoogleAdsOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_TiktokAdsOptions: + if value != nil { + connectorOptionsTiktokAdsOptionsConverted, err := tikTokAdsOptionsToWire(&value.TiktokAdsOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.TiktokAdsOptions", err) + } + connectorOptionsTiktokAdsOptionsWire = connectorOptionsTiktokAdsOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_SharepointOptions: + if value != nil { + connectorOptionsSharepointOptionsConverted, err := sharepointOptionsToWire(&value.SharepointOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.SharepointOptions", err) + } + connectorOptionsSharepointOptionsWire = connectorOptionsSharepointOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_GdriveOptions: + if value != nil { + connectorOptionsGdriveOptionsConverted, err := googleDriveOptionsToWire(&value.GdriveOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.GdriveOptions", err) + } + connectorOptionsGdriveOptionsWire = connectorOptionsGdriveOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_OutlookOptions: + if value != nil { + connectorOptionsOutlookOptionsConverted, err := outlookOptionsToWire(&value.OutlookOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.OutlookOptions", err) + } + connectorOptionsOutlookOptionsWire = connectorOptionsOutlookOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_SmartsheetOptions: + if value != nil { + connectorOptionsSmartsheetOptionsConverted, err := smartsheetOptionsToWire(&value.SmartsheetOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.SmartsheetOptions", err) + } + connectorOptionsSmartsheetOptionsWire = connectorOptionsSmartsheetOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_JiraOptions: + if value != nil { + connectorOptionsJiraOptionsConverted, err := jiraConnectorOptionsToWire(&value.JiraOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.JiraOptions", err) + } + connectorOptionsJiraOptionsWire = connectorOptionsJiraOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_ConfluenceOptions: + if value != nil { + connectorOptionsConfluenceOptionsConverted, err := confluenceConnectorOptionsToWire(&value.ConfluenceOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.ConfluenceOptions", err) + } + connectorOptionsConfluenceOptionsWire = connectorOptionsConfluenceOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_MetaAdsOptions: + if value != nil { + connectorOptionsMetaAdsOptionsConverted, err := metaMarketingOptionsToWire(&value.MetaAdsOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.MetaAdsOptions", err) + } + connectorOptionsMetaAdsOptionsWire = connectorOptionsMetaAdsOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_ZendeskSupportOptions: + if value != nil { + connectorOptionsZendeskSupportOptionsConverted, err := zendeskSupportOptionsToWire(&value.ZendeskSupportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.ZendeskSupportOptions", err) + } + connectorOptionsZendeskSupportOptionsWire = connectorOptionsZendeskSupportOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_KafkaOptions: + if value != nil { + connectorOptionsKafkaOptionsConverted, err := kafkaOptionsToWire(&value.KafkaOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.KafkaOptions", err) + } + connectorOptionsKafkaOptionsWire = connectorOptionsKafkaOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_MarketoOptions: + if value != nil { + connectorOptionsMarketoOptionsConverted, err := marketoOptionsToWire(&value.MarketoOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.MarketoOptions", err) + } + connectorOptionsMarketoOptionsWire = connectorOptionsMarketoOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_LinkedinAdsOptions: + if value != nil { + connectorOptionsLinkedinAdsOptionsConverted, err := linkedInAdsOptionsToWire(&value.LinkedinAdsOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.LinkedinAdsOptions", err) + } + connectorOptionsLinkedinAdsOptionsWire = connectorOptionsLinkedinAdsOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_RedditAdsOptions: + if value != nil { + connectorOptionsRedditAdsOptionsConverted, err := redditAdsOptionsToWire(&value.RedditAdsOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.RedditAdsOptions", err) + } + connectorOptionsRedditAdsOptionsWire = connectorOptionsRedditAdsOptionsConverted + } + case *ConnectorOptions_ConnectorOptions_ApiSourceConnectorOptions: + if value != nil { + connectorOptionsApiSourceConnectorOptionsConverted, err := apiSourceConnectorOptionsToWire(&value.ApiSourceConnectorOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.ApiSourceConnectorOptions", err) + } + connectorOptionsApiSourceConnectorOptionsWire = connectorOptionsApiSourceConnectorOptionsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ConnectorOptions.ConnectorOptions", value) + } + return &connectorOptionsWire{ + GoogleAdsOptions: connectorOptionsGoogleAdsOptionsWire, + TiktokAdsOptions: connectorOptionsTiktokAdsOptionsWire, + SharepointOptions: connectorOptionsSharepointOptionsWire, + GdriveOptions: connectorOptionsGdriveOptionsWire, + OutlookOptions: connectorOptionsOutlookOptionsWire, + SmartsheetOptions: connectorOptionsSmartsheetOptionsWire, + JiraOptions: connectorOptionsJiraOptionsWire, + ConfluenceOptions: connectorOptionsConfluenceOptionsWire, + MetaAdsOptions: connectorOptionsMetaAdsOptionsWire, + ZendeskSupportOptions: connectorOptionsZendeskSupportOptionsWire, + KafkaOptions: connectorOptionsKafkaOptionsWire, + MarketoOptions: connectorOptionsMarketoOptionsWire, + LinkedinAdsOptions: connectorOptionsLinkedinAdsOptionsWire, + RedditAdsOptions: connectorOptionsRedditAdsOptionsWire, + ApiSourceConnectorOptions: connectorOptionsApiSourceConnectorOptionsWire, + }, nil +} + +func connectorOptionsFromWire(w *connectorOptionsWire) (*ConnectorOptions, error) { + if w == nil { + return nil, nil + } + connectorOptionsMembers := 0 + if w.GoogleAdsOptions != nil { + connectorOptionsMembers++ + } + if w.TiktokAdsOptions != nil { + connectorOptionsMembers++ + } + if w.SharepointOptions != nil { + connectorOptionsMembers++ + } + if w.GdriveOptions != nil { + connectorOptionsMembers++ + } + if w.OutlookOptions != nil { + connectorOptionsMembers++ + } + if w.SmartsheetOptions != nil { + connectorOptionsMembers++ + } + if w.JiraOptions != nil { + connectorOptionsMembers++ + } + if w.ConfluenceOptions != nil { + connectorOptionsMembers++ + } + if w.MetaAdsOptions != nil { + connectorOptionsMembers++ + } + if w.ZendeskSupportOptions != nil { + connectorOptionsMembers++ + } + if w.KafkaOptions != nil { + connectorOptionsMembers++ + } + if w.MarketoOptions != nil { + connectorOptionsMembers++ + } + if w.LinkedinAdsOptions != nil { + connectorOptionsMembers++ + } + if w.RedditAdsOptions != nil { + connectorOptionsMembers++ + } + if w.ApiSourceConnectorOptions != nil { + connectorOptionsMembers++ + } + if connectorOptionsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ConnectorOptions.ConnectorOptions") + } + var connectorOptionsSelection isConnectorOptions_ConnectorOptions + switch { + case w.GoogleAdsOptions != nil: + connectorOptionsGoogleAdsOptionsConverted, err := googleAdsOptionsFromWire(w.GoogleAdsOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.GoogleAdsOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_GoogleAdsOptions{GoogleAdsOptions: *connectorOptionsGoogleAdsOptionsConverted} + case w.TiktokAdsOptions != nil: + connectorOptionsTiktokAdsOptionsConverted, err := tikTokAdsOptionsFromWire(w.TiktokAdsOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.TiktokAdsOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_TiktokAdsOptions{TiktokAdsOptions: *connectorOptionsTiktokAdsOptionsConverted} + case w.SharepointOptions != nil: + connectorOptionsSharepointOptionsConverted, err := sharepointOptionsFromWire(w.SharepointOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.SharepointOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_SharepointOptions{SharepointOptions: *connectorOptionsSharepointOptionsConverted} + case w.GdriveOptions != nil: + connectorOptionsGdriveOptionsConverted, err := googleDriveOptionsFromWire(w.GdriveOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.GdriveOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_GdriveOptions{GdriveOptions: *connectorOptionsGdriveOptionsConverted} + case w.OutlookOptions != nil: + connectorOptionsOutlookOptionsConverted, err := outlookOptionsFromWire(w.OutlookOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.OutlookOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_OutlookOptions{OutlookOptions: *connectorOptionsOutlookOptionsConverted} + case w.SmartsheetOptions != nil: + connectorOptionsSmartsheetOptionsConverted, err := smartsheetOptionsFromWire(w.SmartsheetOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.SmartsheetOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_SmartsheetOptions{SmartsheetOptions: *connectorOptionsSmartsheetOptionsConverted} + case w.JiraOptions != nil: + connectorOptionsJiraOptionsConverted, err := jiraConnectorOptionsFromWire(w.JiraOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.JiraOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_JiraOptions{JiraOptions: *connectorOptionsJiraOptionsConverted} + case w.ConfluenceOptions != nil: + connectorOptionsConfluenceOptionsConverted, err := confluenceConnectorOptionsFromWire(w.ConfluenceOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.ConfluenceOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_ConfluenceOptions{ConfluenceOptions: *connectorOptionsConfluenceOptionsConverted} + case w.MetaAdsOptions != nil: + connectorOptionsMetaAdsOptionsConverted, err := metaMarketingOptionsFromWire(w.MetaAdsOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.MetaAdsOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_MetaAdsOptions{MetaAdsOptions: *connectorOptionsMetaAdsOptionsConverted} + case w.ZendeskSupportOptions != nil: + connectorOptionsZendeskSupportOptionsConverted, err := zendeskSupportOptionsFromWire(w.ZendeskSupportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.ZendeskSupportOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_ZendeskSupportOptions{ZendeskSupportOptions: *connectorOptionsZendeskSupportOptionsConverted} + case w.KafkaOptions != nil: + connectorOptionsKafkaOptionsConverted, err := kafkaOptionsFromWire(w.KafkaOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.KafkaOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_KafkaOptions{KafkaOptions: *connectorOptionsKafkaOptionsConverted} + case w.MarketoOptions != nil: + connectorOptionsMarketoOptionsConverted, err := marketoOptionsFromWire(w.MarketoOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.MarketoOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_MarketoOptions{MarketoOptions: *connectorOptionsMarketoOptionsConverted} + case w.LinkedinAdsOptions != nil: + connectorOptionsLinkedinAdsOptionsConverted, err := linkedInAdsOptionsFromWire(w.LinkedinAdsOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.LinkedinAdsOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_LinkedinAdsOptions{LinkedinAdsOptions: *connectorOptionsLinkedinAdsOptionsConverted} + case w.RedditAdsOptions != nil: + connectorOptionsRedditAdsOptionsConverted, err := redditAdsOptionsFromWire(w.RedditAdsOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.RedditAdsOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_RedditAdsOptions{RedditAdsOptions: *connectorOptionsRedditAdsOptionsConverted} + case w.ApiSourceConnectorOptions != nil: + connectorOptionsApiSourceConnectorOptionsConverted, err := apiSourceConnectorOptionsFromWire(w.ApiSourceConnectorOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectorOptions.ConnectorOptions.ApiSourceConnectorOptions", err) + } + connectorOptionsSelection = &ConnectorOptions_ConnectorOptions_ApiSourceConnectorOptions{ApiSourceConnectorOptions: *connectorOptionsApiSourceConnectorOptionsConverted} + } + return &ConnectorOptions{ + ConnectorOptions: connectorOptionsSelection, + }, nil +} + +type createPipelineRequestWire struct { + AllowDuplicateNames *bool `json:"allow_duplicate_names,omitempty"` + DryRun *bool `json:"dry_run,omitempty"` + RunAs *pipelinesJobRunAsWire `json:"run_as,omitempty"` + Parameters map[string]string `json:"parameters,omitempty"` + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Storage *string `json:"storage,omitempty"` + Configuration map[string]string `json:"configuration,omitempty"` + Clusters []pipelineClusterWire `json:"clusters,omitempty"` + Libraries []pipelineLibraryWire `json:"libraries,omitempty"` + IngestionDefinition *ingestionPipelineDefinitionWire `json:"ingestion_definition,omitempty"` + GatewayDefinition *ingestionGatewayPipelineDefinitionWire `json:"gateway_definition,omitempty"` + Trigger *pipelineTriggerWire `json:"trigger,omitempty"` + Target *string `json:"target,omitempty"` + Schema *string `json:"schema,omitempty"` + Filters *filtersWire `json:"filters,omitempty"` + Continuous *bool `json:"continuous,omitempty"` + Development *bool `json:"development,omitempty"` + Photon *bool `json:"photon,omitempty"` + Edition *string `json:"edition,omitempty"` + Channel *string `json:"channel,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Notifications []notificationsWire `json:"notifications,omitempty"` + Serverless *bool `json:"serverless,omitempty"` + Deployment *pipelineDeploymentWire `json:"deployment,omitempty"` + RestartWindow *restartWindowWire `json:"restart_window,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + Tags map[string]string `json:"tags,omitempty"` + EventLog *eventLogSpecWire `json:"event_log,omitempty"` + RootPath *string `json:"root_path,omitempty"` + Environment *pipelinesEnvironmentWire `json:"environment,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + ServerlessComputeId *string `json:"serverless_compute_id,omitempty"` +} + +func createPipelineRequestToWire(v *CreatePipelineRequest) (*createPipelineRequestWire, error) { + if v == nil { + return nil, nil + } + runAsWireValue, err := pipelinesJobRunAsToWire(v.RunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.RunAs", err) + } + clustersWireValue, err := convertSlice(v.Clusters, pipelineClusterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.Clusters", err) + } + librariesWireValue, err := convertSlice(v.Libraries, pipelineLibraryToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.Libraries", err) + } + ingestionDefinitionWireValue, err := ingestionPipelineDefinitionToWire(v.IngestionDefinition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.IngestionDefinition", err) + } + gatewayDefinitionWireValue, err := ingestionGatewayPipelineDefinitionToWire(v.GatewayDefinition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.GatewayDefinition", err) + } + triggerWireValue, err := pipelineTriggerToWire(v.Trigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.Trigger", err) + } + filtersWireValue, err := filtersToWire(v.Filters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.Filters", err) + } + notificationsWireValue, err := convertSlice(v.Notifications, notificationsToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.Notifications", err) + } + deploymentWireValue, err := pipelineDeploymentToWire(v.Deployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.Deployment", err) + } + restartWindowWireValue, err := restartWindowToWire(v.RestartWindow) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.RestartWindow", err) + } + eventLogWireValue, err := eventLogSpecToWire(v.EventLog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.EventLog", err) + } + environmentWireValue, err := pipelinesEnvironmentToWire(v.Environment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineRequest.Environment", err) + } + return &createPipelineRequestWire{ + AllowDuplicateNames: v.AllowDuplicateNames, + DryRun: v.DryRun, + RunAs: runAsWireValue, + Parameters: v.Parameters, + Id: v.Id, + Name: v.Name, + Storage: v.Storage, + Configuration: v.Configuration, + Clusters: clustersWireValue, + Libraries: librariesWireValue, + IngestionDefinition: ingestionDefinitionWireValue, + GatewayDefinition: gatewayDefinitionWireValue, + Trigger: triggerWireValue, + Target: v.Target, + Schema: v.Schema, + Filters: filtersWireValue, + Continuous: v.Continuous, + Development: v.Development, + Photon: v.Photon, + Edition: v.Edition, + Channel: v.Channel, + Catalog: v.Catalog, + Notifications: notificationsWireValue, + Serverless: v.Serverless, + Deployment: deploymentWireValue, + RestartWindow: restartWindowWireValue, + BudgetPolicyId: v.BudgetPolicyId, + Tags: v.Tags, + EventLog: eventLogWireValue, + RootPath: v.RootPath, + Environment: environmentWireValue, + UsagePolicyId: v.UsagePolicyId, + ServerlessComputeId: v.ServerlessComputeId, + }, nil +} + +type createPipelineResponseWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + EffectiveSettings *pipelineSpecWire `json:"effective_settings,omitempty"` +} + +func createPipelineResponseFromWire(w *createPipelineResponseWire) (*CreatePipelineResponse, error) { + if w == nil { + return nil, nil + } + effectiveSettingsPublicValue, err := pipelineSpecFromWire(w.EffectiveSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePipelineResponse.EffectiveSettings", err) + } + return &CreatePipelineResponse{ + PipelineId: w.PipelineId, + EffectiveSettings: effectiveSettingsPublicValue, + }, nil +} + +type cronTriggerWire struct { + QuartzCronSchedule *string `json:"quartz_cron_schedule,omitempty"` + TimezoneId *string `json:"timezone_id,omitempty"` +} + +func cronTriggerToWire(v *CronTrigger) (*cronTriggerWire, error) { + if v == nil { + return nil, nil + } + return &cronTriggerWire{ + QuartzCronSchedule: v.QuartzCronSchedule, + TimezoneId: v.TimezoneId, + }, nil +} + +func cronTriggerFromWire(w *cronTriggerWire) (*CronTrigger, error) { + if w == nil { + return nil, nil + } + return &CronTrigger{ + QuartzCronSchedule: w.QuartzCronSchedule, + TimezoneId: w.TimezoneId, + }, nil +} + +type dataPlaneIdWire struct { + Instance *string `json:"instance,omitempty"` + SeqNo *int64 `json:"seq_no,omitempty"` +} + +func dataPlaneIdFromWire(w *dataPlaneIdWire) (*DataPlaneId, error) { + if w == nil { + return nil, nil + } + return &DataPlaneId{ + Instance: w.Instance, + SeqNo: w.SeqNo, + }, nil +} + +type dataStagingOptionsWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + VolumeName *string `json:"volume_name,omitempty"` +} + +func dataStagingOptionsToWire(v *DataStagingOptions) (*dataStagingOptionsWire, error) { + if v == nil { + return nil, nil + } + return &dataStagingOptionsWire{ + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + VolumeName: v.VolumeName, + }, nil +} + +func dataStagingOptionsFromWire(w *dataStagingOptionsWire) (*DataStagingOptions, error) { + if w == nil { + return nil, nil + } + return &DataStagingOptions{ + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + VolumeName: w.VolumeName, + }, nil +} + +type deletePipelineRequestWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + Force *bool `json:"force,omitempty"` + Cascade *bool `json:"cascade,omitempty"` +} + +func deletePipelineRequestToWire(v *DeletePipelineRequest) (*deletePipelineRequestWire, error) { + if v == nil { + return nil, nil + } + return &deletePipelineRequestWire{ + PipelineId: v.PipelineId, + Force: v.Force, + Cascade: v.Cascade, + }, nil +} + +type editPipelineRequestWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + AllowDuplicateNames *bool `json:"allow_duplicate_names,omitempty"` + ExpectedLastModified *int64 `json:"expected_last_modified,omitempty"` + RunAs *pipelinesJobRunAsWire `json:"run_as,omitempty"` + Parameters map[string]string `json:"parameters,omitempty"` + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Storage *string `json:"storage,omitempty"` + Configuration map[string]string `json:"configuration,omitempty"` + Clusters []pipelineClusterWire `json:"clusters,omitempty"` + Libraries []pipelineLibraryWire `json:"libraries,omitempty"` + IngestionDefinition *ingestionPipelineDefinitionWire `json:"ingestion_definition,omitempty"` + GatewayDefinition *ingestionGatewayPipelineDefinitionWire `json:"gateway_definition,omitempty"` + Trigger *pipelineTriggerWire `json:"trigger,omitempty"` + Target *string `json:"target,omitempty"` + Schema *string `json:"schema,omitempty"` + Filters *filtersWire `json:"filters,omitempty"` + Continuous *bool `json:"continuous,omitempty"` + Development *bool `json:"development,omitempty"` + Photon *bool `json:"photon,omitempty"` + Edition *string `json:"edition,omitempty"` + Channel *string `json:"channel,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Notifications []notificationsWire `json:"notifications,omitempty"` + Serverless *bool `json:"serverless,omitempty"` + Deployment *pipelineDeploymentWire `json:"deployment,omitempty"` + RestartWindow *restartWindowWire `json:"restart_window,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + Tags map[string]string `json:"tags,omitempty"` + EventLog *eventLogSpecWire `json:"event_log,omitempty"` + RootPath *string `json:"root_path,omitempty"` + Environment *pipelinesEnvironmentWire `json:"environment,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + ServerlessComputeId *string `json:"serverless_compute_id,omitempty"` +} + +func editPipelineRequestToWire(v *EditPipelineRequest) (*editPipelineRequestWire, error) { + if v == nil { + return nil, nil + } + runAsWireValue, err := pipelinesJobRunAsToWire(v.RunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.RunAs", err) + } + clustersWireValue, err := convertSlice(v.Clusters, pipelineClusterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.Clusters", err) + } + librariesWireValue, err := convertSlice(v.Libraries, pipelineLibraryToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.Libraries", err) + } + ingestionDefinitionWireValue, err := ingestionPipelineDefinitionToWire(v.IngestionDefinition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.IngestionDefinition", err) + } + gatewayDefinitionWireValue, err := ingestionGatewayPipelineDefinitionToWire(v.GatewayDefinition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.GatewayDefinition", err) + } + triggerWireValue, err := pipelineTriggerToWire(v.Trigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.Trigger", err) + } + filtersWireValue, err := filtersToWire(v.Filters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.Filters", err) + } + notificationsWireValue, err := convertSlice(v.Notifications, notificationsToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.Notifications", err) + } + deploymentWireValue, err := pipelineDeploymentToWire(v.Deployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.Deployment", err) + } + restartWindowWireValue, err := restartWindowToWire(v.RestartWindow) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.RestartWindow", err) + } + eventLogWireValue, err := eventLogSpecToWire(v.EventLog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.EventLog", err) + } + environmentWireValue, err := pipelinesEnvironmentToWire(v.Environment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditPipelineRequest.Environment", err) + } + return &editPipelineRequestWire{ + PipelineId: v.PipelineId, + AllowDuplicateNames: v.AllowDuplicateNames, + ExpectedLastModified: v.ExpectedLastModified, + RunAs: runAsWireValue, + Parameters: v.Parameters, + Id: v.Id, + Name: v.Name, + Storage: v.Storage, + Configuration: v.Configuration, + Clusters: clustersWireValue, + Libraries: librariesWireValue, + IngestionDefinition: ingestionDefinitionWireValue, + GatewayDefinition: gatewayDefinitionWireValue, + Trigger: triggerWireValue, + Target: v.Target, + Schema: v.Schema, + Filters: filtersWireValue, + Continuous: v.Continuous, + Development: v.Development, + Photon: v.Photon, + Edition: v.Edition, + Channel: v.Channel, + Catalog: v.Catalog, + Notifications: notificationsWireValue, + Serverless: v.Serverless, + Deployment: deploymentWireValue, + RestartWindow: restartWindowWireValue, + BudgetPolicyId: v.BudgetPolicyId, + Tags: v.Tags, + EventLog: eventLogWireValue, + RootPath: v.RootPath, + Environment: environmentWireValue, + UsagePolicyId: v.UsagePolicyId, + ServerlessComputeId: v.ServerlessComputeId, + }, nil +} + +type errorDetailWire struct { + Exceptions []serializedExceptionWire `json:"exceptions,omitempty"` + Fatal *bool `json:"fatal,omitempty"` +} + +func errorDetailFromWire(w *errorDetailWire) (*ErrorDetail, error) { + if w == nil { + return nil, nil + } + exceptionsPublicValue, err := convertSlice(w.Exceptions, serializedExceptionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ErrorDetail.Exceptions", err) + } + return &ErrorDetail{ + Exceptions: exceptionsPublicValue, + Fatal: w.Fatal, + }, nil +} + +type eventLogSpecWire struct { + Name *string `json:"name,omitempty"` + Schema *string `json:"schema,omitempty"` + Catalog *string `json:"catalog,omitempty"` +} + +func eventLogSpecToWire(v *EventLogSpec) (*eventLogSpecWire, error) { + if v == nil { + return nil, nil + } + return &eventLogSpecWire{ + Name: v.Name, + Schema: v.Schema, + Catalog: v.Catalog, + }, nil +} + +func eventLogSpecFromWire(w *eventLogSpecWire) (*EventLogSpec, error) { + if w == nil { + return nil, nil + } + return &EventLogSpec{ + Name: w.Name, + Schema: w.Schema, + Catalog: w.Catalog, + }, nil +} + +type fileFilterWire struct { + PathFilter *string `json:"path_filter,omitempty"` + ModifiedBefore *string `json:"modified_before,omitempty"` + ModifiedAfter *string `json:"modified_after,omitempty"` +} + +func fileFilterToWire(v *FileFilter) (*fileFilterWire, error) { + if v == nil { + return nil, nil + } + var filterPathFilterWire *string + var filterModifiedBeforeWire *string + var filterModifiedAfterWire *string + switch value := v.Filter.(type) { + case nil: + case *FileFilter_Filter_PathFilter: + if value != nil { + filterPathFilterWire = new(value.PathFilter) + } + case *FileFilter_Filter_ModifiedBefore: + if value != nil { + filterModifiedBeforeWire = new(value.ModifiedBefore) + } + case *FileFilter_Filter_ModifiedAfter: + if value != nil { + filterModifiedAfterWire = new(value.ModifiedAfter) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "FileFilter.Filter", value) + } + return &fileFilterWire{ + PathFilter: filterPathFilterWire, + ModifiedBefore: filterModifiedBeforeWire, + ModifiedAfter: filterModifiedAfterWire, + }, nil +} + +func fileFilterFromWire(w *fileFilterWire) (*FileFilter, error) { + if w == nil { + return nil, nil + } + filterMembers := 0 + if w.PathFilter != nil { + filterMembers++ + } + if w.ModifiedBefore != nil { + filterMembers++ + } + if w.ModifiedAfter != nil { + filterMembers++ + } + if filterMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "FileFilter.Filter") + } + var filterSelection isFileFilter_Filter + switch { + case w.PathFilter != nil: + filterSelection = &FileFilter_Filter_PathFilter{PathFilter: *w.PathFilter} + case w.ModifiedBefore != nil: + filterSelection = &FileFilter_Filter_ModifiedBefore{ModifiedBefore: *w.ModifiedBefore} + case w.ModifiedAfter != nil: + filterSelection = &FileFilter_Filter_ModifiedAfter{ModifiedAfter: *w.ModifiedAfter} + } + return &FileFilter{ + Filter: filterSelection, + }, nil +} + +type fileIngestionOptionsWire struct { + Format FileIngestionOptions_FileFormat `json:"format,omitempty"` + FileFilters []fileFilterWire `json:"file_filters,omitempty"` + InferColumnTypes *bool `json:"infer_column_types,omitempty"` + SchemaEvolutionMode FileIngestionOptions_SchemaEvolutionMode `json:"schema_evolution_mode,omitempty"` + SchemaHints *string `json:"schema_hints,omitempty"` + IgnoreCorruptFiles *bool `json:"ignore_corrupt_files,omitempty"` + CorruptRecordColumn *string `json:"corrupt_record_column,omitempty"` + RescuedDataColumn *string `json:"rescued_data_column,omitempty"` + SingleVariantColumn *string `json:"single_variant_column,omitempty"` + ReaderCaseSensitive *bool `json:"reader_case_sensitive,omitempty"` + FormatOptions map[string]string `json:"format_options,omitempty"` +} + +func fileIngestionOptionsToWire(v *FileIngestionOptions) (*fileIngestionOptionsWire, error) { + if v == nil { + return nil, nil + } + fileFiltersWireValue, err := convertSlice(v.FileFilters, fileFilterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileIngestionOptions.FileFilters", err) + } + return &fileIngestionOptionsWire{ + Format: v.Format, + FileFilters: fileFiltersWireValue, + InferColumnTypes: v.InferColumnTypes, + SchemaEvolutionMode: v.SchemaEvolutionMode, + SchemaHints: v.SchemaHints, + IgnoreCorruptFiles: v.IgnoreCorruptFiles, + CorruptRecordColumn: v.CorruptRecordColumn, + RescuedDataColumn: v.RescuedDataColumn, + SingleVariantColumn: v.SingleVariantColumn, + ReaderCaseSensitive: v.ReaderCaseSensitive, + FormatOptions: v.FormatOptions, + }, nil +} + +func fileIngestionOptionsFromWire(w *fileIngestionOptionsWire) (*FileIngestionOptions, error) { + if w == nil { + return nil, nil + } + fileFiltersPublicValue, err := convertSlice(w.FileFilters, fileFilterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileIngestionOptions.FileFilters", err) + } + return &FileIngestionOptions{ + Format: w.Format, + FileFilters: fileFiltersPublicValue, + InferColumnTypes: w.InferColumnTypes, + SchemaEvolutionMode: w.SchemaEvolutionMode, + SchemaHints: w.SchemaHints, + IgnoreCorruptFiles: w.IgnoreCorruptFiles, + CorruptRecordColumn: w.CorruptRecordColumn, + RescuedDataColumn: w.RescuedDataColumn, + SingleVariantColumn: w.SingleVariantColumn, + ReaderCaseSensitive: w.ReaderCaseSensitive, + FormatOptions: w.FormatOptions, + }, nil +} + +type filtersWire struct { + Include []string `json:"include,omitempty"` + Exclude []string `json:"exclude,omitempty"` +} + +func filtersToWire(v *Filters) (*filtersWire, error) { + if v == nil { + return nil, nil + } + return &filtersWire{ + Include: v.Include, + Exclude: v.Exclude, + }, nil +} + +func filtersFromWire(w *filtersWire) (*Filters, error) { + if w == nil { + return nil, nil + } + return &Filters{ + Include: w.Include, + Exclude: w.Exclude, + }, nil +} + +type getPipelineResponseWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + Spec *pipelineSpecWire `json:"spec,omitempty"` + State PipelineState_PipelineState `json:"state,omitempty"` + Cause *string `json:"cause,omitempty"` + ClusterId *string `json:"cluster_id,omitempty"` + Name *string `json:"name,omitempty"` + Health PipelineHealthStatus `json:"health,omitempty"` + CreatorUserName *string `json:"creator_user_name,omitempty"` + LatestUpdates []updateStateInfoWire `json:"latest_updates,omitempty"` + LastModified *int64 `json:"last_modified,omitempty"` + RunAsUserName *string `json:"run_as_user_name,omitempty"` + EffectiveBudgetPolicyId *string `json:"effective_budget_policy_id,omitempty"` + EffectivePublishingMode PublishingMode `json:"effective_publishing_mode,omitempty"` + RunAs *pipelinesJobRunAsWire `json:"run_as,omitempty"` + Parameters map[string]string `json:"parameters,omitempty"` + EffectiveServerlessComputeId *string `json:"effective_serverless_compute_id,omitempty"` +} + +func getPipelineResponseFromWire(w *getPipelineResponseWire) (*GetPipelineResponse, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := pipelineSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPipelineResponse.Spec", err) + } + latestUpdatesPublicValue, err := convertSlice(w.LatestUpdates, updateStateInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPipelineResponse.LatestUpdates", err) + } + runAsPublicValue, err := pipelinesJobRunAsFromWire(w.RunAs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPipelineResponse.RunAs", err) + } + return &GetPipelineResponse{ + PipelineId: w.PipelineId, + Spec: specPublicValue, + State: w.State, + Cause: w.Cause, + ClusterId: w.ClusterId, + Name: w.Name, + Health: w.Health, + CreatorUserName: w.CreatorUserName, + LatestUpdates: latestUpdatesPublicValue, + LastModified: w.LastModified, + RunAsUserName: w.RunAsUserName, + EffectiveBudgetPolicyId: w.EffectiveBudgetPolicyId, + EffectivePublishingMode: w.EffectivePublishingMode, + RunAs: runAsPublicValue, + Parameters: w.Parameters, + EffectiveServerlessComputeId: w.EffectiveServerlessComputeId, + }, nil +} + +type getUpdateResponseWire struct { + Update *updateInfoWire `json:"update,omitempty"` +} + +func getUpdateResponseFromWire(w *getUpdateResponseWire) (*GetUpdateResponse, error) { + if w == nil { + return nil, nil + } + updatePublicValue, err := updateInfoFromWire(w.Update) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetUpdateResponse.Update", err) + } + return &GetUpdateResponse{ + Update: updatePublicValue, + }, nil +} + +type googleAdsConfigWire struct { + ManagerAccountId *string `json:"manager_account_id,omitempty"` +} + +func googleAdsConfigToWire(v *GoogleAdsConfig) (*googleAdsConfigWire, error) { + if v == nil { + return nil, nil + } + return &googleAdsConfigWire{ + ManagerAccountId: v.ManagerAccountId, + }, nil +} + +func googleAdsConfigFromWire(w *googleAdsConfigWire) (*GoogleAdsConfig, error) { + if w == nil { + return nil, nil + } + return &GoogleAdsConfig{ + ManagerAccountId: w.ManagerAccountId, + }, nil +} + +type googleAdsCustomReportOptionsWire struct { + Resource *string `json:"resource,omitempty"` + ResourceFields []string `json:"resource_fields,omitempty"` + Segments []string `json:"segments,omitempty"` + Metrics []string `json:"metrics,omitempty"` +} + +func googleAdsCustomReportOptionsToWire(v *GoogleAdsCustomReportOptions) (*googleAdsCustomReportOptionsWire, error) { + if v == nil { + return nil, nil + } + return &googleAdsCustomReportOptionsWire{ + Resource: v.Resource, + ResourceFields: v.ResourceFields, + Segments: v.Segments, + Metrics: v.Metrics, + }, nil +} + +func googleAdsCustomReportOptionsFromWire(w *googleAdsCustomReportOptionsWire) (*GoogleAdsCustomReportOptions, error) { + if w == nil { + return nil, nil + } + return &GoogleAdsCustomReportOptions{ + Resource: w.Resource, + ResourceFields: w.ResourceFields, + Segments: w.Segments, + Metrics: w.Metrics, + }, nil +} + +type googleAdsOptionsWire struct { + ManagerAccountId *string `json:"manager_account_id,omitempty"` + LookbackWindowDays *int `json:"lookback_window_days,omitempty"` + SyncStartDate *string `json:"sync_start_date,omitempty"` + CustomReportOptions *googleAdsCustomReportOptionsWire `json:"custom_report_options,omitempty"` +} + +func googleAdsOptionsToWire(v *GoogleAdsOptions) (*googleAdsOptionsWire, error) { + if v == nil { + return nil, nil + } + customReportOptionsWireValue, err := googleAdsCustomReportOptionsToWire(v.CustomReportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GoogleAdsOptions.CustomReportOptions", err) + } + return &googleAdsOptionsWire{ + ManagerAccountId: v.ManagerAccountId, + LookbackWindowDays: v.LookbackWindowDays, + SyncStartDate: v.SyncStartDate, + CustomReportOptions: customReportOptionsWireValue, + }, nil +} + +func googleAdsOptionsFromWire(w *googleAdsOptionsWire) (*GoogleAdsOptions, error) { + if w == nil { + return nil, nil + } + customReportOptionsPublicValue, err := googleAdsCustomReportOptionsFromWire(w.CustomReportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GoogleAdsOptions.CustomReportOptions", err) + } + return &GoogleAdsOptions{ + ManagerAccountId: w.ManagerAccountId, + LookbackWindowDays: w.LookbackWindowDays, + SyncStartDate: w.SyncStartDate, + CustomReportOptions: customReportOptionsPublicValue, + }, nil +} + +type googleDriveOptionsWire struct { + Url *string `json:"url,omitempty"` + EntityType GoogleDriveOptions_GoogleDriveEntityType `json:"entity_type,omitempty"` + FileIngestionOptions *fileIngestionOptionsWire `json:"file_ingestion_options,omitempty"` +} + +func googleDriveOptionsToWire(v *GoogleDriveOptions) (*googleDriveOptionsWire, error) { + if v == nil { + return nil, nil + } + fileIngestionOptionsWireValue, err := fileIngestionOptionsToWire(v.FileIngestionOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GoogleDriveOptions.FileIngestionOptions", err) + } + return &googleDriveOptionsWire{ + Url: v.Url, + EntityType: v.EntityType, + FileIngestionOptions: fileIngestionOptionsWireValue, + }, nil +} + +func googleDriveOptionsFromWire(w *googleDriveOptionsWire) (*GoogleDriveOptions, error) { + if w == nil { + return nil, nil + } + fileIngestionOptionsPublicValue, err := fileIngestionOptionsFromWire(w.FileIngestionOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GoogleDriveOptions.FileIngestionOptions", err) + } + return &GoogleDriveOptions{ + Url: w.Url, + EntityType: w.EntityType, + FileIngestionOptions: fileIngestionOptionsPublicValue, + }, nil +} + +type ingestionGatewayPipelineDefinitionWire struct { + ConnectionName *string `json:"connection_name,omitempty"` + ConnectionId *string `json:"connection_id,omitempty"` + GatewayStorageCatalog *string `json:"gateway_storage_catalog,omitempty"` + GatewayStorageSchema *string `json:"gateway_storage_schema,omitempty"` + GatewayStorageName *string `json:"gateway_storage_name,omitempty"` + ConnectionParameters *connectionParametersWire `json:"connection_parameters,omitempty"` +} + +func ingestionGatewayPipelineDefinitionToWire(v *IngestionGatewayPipelineDefinition) (*ingestionGatewayPipelineDefinitionWire, error) { + if v == nil { + return nil, nil + } + connectionParametersWireValue, err := connectionParametersToWire(v.ConnectionParameters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionGatewayPipelineDefinition.ConnectionParameters", err) + } + return &ingestionGatewayPipelineDefinitionWire{ + ConnectionName: v.ConnectionName, + ConnectionId: v.ConnectionId, + GatewayStorageCatalog: v.GatewayStorageCatalog, + GatewayStorageSchema: v.GatewayStorageSchema, + GatewayStorageName: v.GatewayStorageName, + ConnectionParameters: connectionParametersWireValue, + }, nil +} + +func ingestionGatewayPipelineDefinitionFromWire(w *ingestionGatewayPipelineDefinitionWire) (*IngestionGatewayPipelineDefinition, error) { + if w == nil { + return nil, nil + } + connectionParametersPublicValue, err := connectionParametersFromWire(w.ConnectionParameters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionGatewayPipelineDefinition.ConnectionParameters", err) + } + return &IngestionGatewayPipelineDefinition{ + ConnectionName: w.ConnectionName, + ConnectionId: w.ConnectionId, + GatewayStorageCatalog: w.GatewayStorageCatalog, + GatewayStorageSchema: w.GatewayStorageSchema, + GatewayStorageName: w.GatewayStorageName, + ConnectionParameters: connectionParametersPublicValue, + }, nil +} + +type ingestionPipelineDefinitionWire struct { + ConnectionName *string `json:"connection_name,omitempty"` + IngestionGatewayId *string `json:"ingestion_gateway_id,omitempty"` + IngestFromUcForeignCatalog *bool `json:"ingest_from_uc_foreign_catalog,omitempty"` + Objects []ingestionPipelineDefinition_IngestionConfigWire `json:"objects,omitempty"` + SourceType IngestionSourceType `json:"source_type,omitempty"` + TableConfiguration *ingestionPipelineDefinition_TableSpecificConfigWire `json:"table_configuration,omitempty"` + NetsuiteJarPath *string `json:"netsuite_jar_path,omitempty"` + SourceConfigurations []sourceConfigWire `json:"source_configurations,omitempty"` + FullRefreshWindow *operationTimeWindowWire `json:"full_refresh_window,omitempty"` + ConnectorType ConnectorType `json:"connector_type,omitempty"` + DataStagingOptions *dataStagingOptionsWire `json:"data_staging_options,omitempty"` +} + +func ingestionPipelineDefinitionToWire(v *IngestionPipelineDefinition) (*ingestionPipelineDefinitionWire, error) { + if v == nil { + return nil, nil + } + objectsWireValue, err := convertSlice(v.Objects, ingestionPipelineDefinition_IngestionConfigToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition.Objects", err) + } + tableConfigurationWireValue, err := ingestionPipelineDefinition_TableSpecificConfigToWire(v.TableConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition.TableConfiguration", err) + } + sourceConfigurationsWireValue, err := convertSlice(v.SourceConfigurations, sourceConfigToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition.SourceConfigurations", err) + } + fullRefreshWindowWireValue, err := operationTimeWindowToWire(v.FullRefreshWindow) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition.FullRefreshWindow", err) + } + dataStagingOptionsWireValue, err := dataStagingOptionsToWire(v.DataStagingOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition.DataStagingOptions", err) + } + var sourceConnectionNameWire *string + var sourceIngestionGatewayIdWire *string + var sourceIngestFromUcForeignCatalogWire *bool + switch value := v.Source.(type) { + case nil: + case *IngestionPipelineDefinition_Source_ConnectionName: + if value != nil { + sourceConnectionNameWire = new(value.ConnectionName) + } + case *IngestionPipelineDefinition_Source_IngestionGatewayId: + if value != nil { + sourceIngestionGatewayIdWire = new(value.IngestionGatewayId) + } + case *IngestionPipelineDefinition_Source_IngestFromUcForeignCatalog: + if value != nil { + sourceIngestFromUcForeignCatalogWire = new(value.IngestFromUcForeignCatalog) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "IngestionPipelineDefinition.Source", value) + } + return &ingestionPipelineDefinitionWire{ + ConnectionName: sourceConnectionNameWire, + IngestionGatewayId: sourceIngestionGatewayIdWire, + IngestFromUcForeignCatalog: sourceIngestFromUcForeignCatalogWire, + Objects: objectsWireValue, + SourceType: v.SourceType, + TableConfiguration: tableConfigurationWireValue, + NetsuiteJarPath: v.NetsuiteJarPath, + SourceConfigurations: sourceConfigurationsWireValue, + FullRefreshWindow: fullRefreshWindowWireValue, + ConnectorType: v.ConnectorType, + DataStagingOptions: dataStagingOptionsWireValue, + }, nil +} + +func ingestionPipelineDefinitionFromWire(w *ingestionPipelineDefinitionWire) (*IngestionPipelineDefinition, error) { + if w == nil { + return nil, nil + } + sourceMembers := 0 + if w.ConnectionName != nil { + sourceMembers++ + } + if w.IngestionGatewayId != nil { + sourceMembers++ + } + if w.IngestFromUcForeignCatalog != nil { + sourceMembers++ + } + if sourceMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "IngestionPipelineDefinition.Source") + } + objectsPublicValue, err := convertSlice(w.Objects, ingestionPipelineDefinition_IngestionConfigFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition.Objects", err) + } + tableConfigurationPublicValue, err := ingestionPipelineDefinition_TableSpecificConfigFromWire(w.TableConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition.TableConfiguration", err) + } + sourceConfigurationsPublicValue, err := convertSlice(w.SourceConfigurations, sourceConfigFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition.SourceConfigurations", err) + } + fullRefreshWindowPublicValue, err := operationTimeWindowFromWire(w.FullRefreshWindow) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition.FullRefreshWindow", err) + } + dataStagingOptionsPublicValue, err := dataStagingOptionsFromWire(w.DataStagingOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition.DataStagingOptions", err) + } + var sourceSelection isIngestionPipelineDefinition_Source + switch { + case w.ConnectionName != nil: + sourceSelection = &IngestionPipelineDefinition_Source_ConnectionName{ConnectionName: *w.ConnectionName} + case w.IngestionGatewayId != nil: + sourceSelection = &IngestionPipelineDefinition_Source_IngestionGatewayId{IngestionGatewayId: *w.IngestionGatewayId} + case w.IngestFromUcForeignCatalog != nil: + sourceSelection = &IngestionPipelineDefinition_Source_IngestFromUcForeignCatalog{IngestFromUcForeignCatalog: *w.IngestFromUcForeignCatalog} + } + return &IngestionPipelineDefinition{ + Objects: objectsPublicValue, + SourceType: w.SourceType, + TableConfiguration: tableConfigurationPublicValue, + NetsuiteJarPath: w.NetsuiteJarPath, + SourceConfigurations: sourceConfigurationsPublicValue, + FullRefreshWindow: fullRefreshWindowPublicValue, + ConnectorType: w.ConnectorType, + DataStagingOptions: dataStagingOptionsPublicValue, + Source: sourceSelection, + }, nil +} + +type ingestionPipelineDefinition_FanoutOptionsWire struct { + FanoutBy *string `json:"fanout_by,omitempty"` + Transforms []transformerWire `json:"transforms,omitempty"` +} + +func ingestionPipelineDefinition_FanoutOptionsToWire(v *IngestionPipelineDefinition_FanoutOptions) (*ingestionPipelineDefinition_FanoutOptionsWire, error) { + if v == nil { + return nil, nil + } + transformsWireValue, err := convertSlice(v.Transforms, transformerToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_FanoutOptions.Transforms", err) + } + return &ingestionPipelineDefinition_FanoutOptionsWire{ + FanoutBy: v.FanoutBy, + Transforms: transformsWireValue, + }, nil +} + +func ingestionPipelineDefinition_FanoutOptionsFromWire(w *ingestionPipelineDefinition_FanoutOptionsWire) (*IngestionPipelineDefinition_FanoutOptions, error) { + if w == nil { + return nil, nil + } + transformsPublicValue, err := convertSlice(w.Transforms, transformerFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_FanoutOptions.Transforms", err) + } + return &IngestionPipelineDefinition_FanoutOptions{ + FanoutBy: w.FanoutBy, + Transforms: transformsPublicValue, + }, nil +} + +type ingestionPipelineDefinition_IngestionConfigWire struct { + Schema *ingestionPipelineDefinition_SchemaSpecWire `json:"schema,omitempty"` + Table *ingestionPipelineDefinition_TableSpecWire `json:"table,omitempty"` + Report *ingestionPipelineDefinition_ReportSpecWire `json:"report,omitempty"` +} + +func ingestionPipelineDefinition_IngestionConfigToWire(v *IngestionPipelineDefinition_IngestionConfig) (*ingestionPipelineDefinition_IngestionConfigWire, error) { + if v == nil { + return nil, nil + } + var sourceTablesSchemaWire *ingestionPipelineDefinition_SchemaSpecWire + var sourceTablesTableWire *ingestionPipelineDefinition_TableSpecWire + var sourceTablesReportWire *ingestionPipelineDefinition_ReportSpecWire + switch value := v.SourceTables.(type) { + case nil: + case *IngestionPipelineDefinition_IngestionConfig_SourceTables_Schema: + if value != nil { + sourceTablesSchemaConverted, err := ingestionPipelineDefinition_SchemaSpecToWire(&value.Schema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_IngestionConfig.SourceTables.Schema", err) + } + sourceTablesSchemaWire = sourceTablesSchemaConverted + } + case *IngestionPipelineDefinition_IngestionConfig_SourceTables_Table: + if value != nil { + sourceTablesTableConverted, err := ingestionPipelineDefinition_TableSpecToWire(&value.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_IngestionConfig.SourceTables.Table", err) + } + sourceTablesTableWire = sourceTablesTableConverted + } + case *IngestionPipelineDefinition_IngestionConfig_SourceTables_Report: + if value != nil { + sourceTablesReportConverted, err := ingestionPipelineDefinition_ReportSpecToWire(&value.Report) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_IngestionConfig.SourceTables.Report", err) + } + sourceTablesReportWire = sourceTablesReportConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "IngestionPipelineDefinition_IngestionConfig.SourceTables", value) + } + return &ingestionPipelineDefinition_IngestionConfigWire{ + Schema: sourceTablesSchemaWire, + Table: sourceTablesTableWire, + Report: sourceTablesReportWire, + }, nil +} + +func ingestionPipelineDefinition_IngestionConfigFromWire(w *ingestionPipelineDefinition_IngestionConfigWire) (*IngestionPipelineDefinition_IngestionConfig, error) { + if w == nil { + return nil, nil + } + sourceTablesMembers := 0 + if w.Schema != nil { + sourceTablesMembers++ + } + if w.Table != nil { + sourceTablesMembers++ + } + if w.Report != nil { + sourceTablesMembers++ + } + if sourceTablesMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "IngestionPipelineDefinition_IngestionConfig.SourceTables") + } + var sourceTablesSelection isIngestionPipelineDefinition_IngestionConfig_SourceTables + switch { + case w.Schema != nil: + sourceTablesSchemaConverted, err := ingestionPipelineDefinition_SchemaSpecFromWire(w.Schema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_IngestionConfig.SourceTables.Schema", err) + } + sourceTablesSelection = &IngestionPipelineDefinition_IngestionConfig_SourceTables_Schema{Schema: *sourceTablesSchemaConverted} + case w.Table != nil: + sourceTablesTableConverted, err := ingestionPipelineDefinition_TableSpecFromWire(w.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_IngestionConfig.SourceTables.Table", err) + } + sourceTablesSelection = &IngestionPipelineDefinition_IngestionConfig_SourceTables_Table{Table: *sourceTablesTableConverted} + case w.Report != nil: + sourceTablesReportConverted, err := ingestionPipelineDefinition_ReportSpecFromWire(w.Report) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_IngestionConfig.SourceTables.Report", err) + } + sourceTablesSelection = &IngestionPipelineDefinition_IngestionConfig_SourceTables_Report{Report: *sourceTablesReportConverted} + } + return &IngestionPipelineDefinition_IngestionConfig{ + SourceTables: sourceTablesSelection, + }, nil +} + +type ingestionPipelineDefinition_ReportSpecWire struct { + SourceUrl *string `json:"source_url,omitempty"` + DestinationCatalog *string `json:"destination_catalog,omitempty"` + DestinationSchema *string `json:"destination_schema,omitempty"` + DestinationTable *string `json:"destination_table,omitempty"` + TableConfiguration *ingestionPipelineDefinition_TableSpecificConfigWire `json:"table_configuration,omitempty"` +} + +func ingestionPipelineDefinition_ReportSpecToWire(v *IngestionPipelineDefinition_ReportSpec) (*ingestionPipelineDefinition_ReportSpecWire, error) { + if v == nil { + return nil, nil + } + tableConfigurationWireValue, err := ingestionPipelineDefinition_TableSpecificConfigToWire(v.TableConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_ReportSpec.TableConfiguration", err) + } + return &ingestionPipelineDefinition_ReportSpecWire{ + SourceUrl: v.SourceUrl, + DestinationCatalog: v.DestinationCatalog, + DestinationSchema: v.DestinationSchema, + DestinationTable: v.DestinationTable, + TableConfiguration: tableConfigurationWireValue, + }, nil +} + +func ingestionPipelineDefinition_ReportSpecFromWire(w *ingestionPipelineDefinition_ReportSpecWire) (*IngestionPipelineDefinition_ReportSpec, error) { + if w == nil { + return nil, nil + } + tableConfigurationPublicValue, err := ingestionPipelineDefinition_TableSpecificConfigFromWire(w.TableConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_ReportSpec.TableConfiguration", err) + } + return &IngestionPipelineDefinition_ReportSpec{ + SourceUrl: w.SourceUrl, + DestinationCatalog: w.DestinationCatalog, + DestinationSchema: w.DestinationSchema, + DestinationTable: w.DestinationTable, + TableConfiguration: tableConfigurationPublicValue, + }, nil +} + +type ingestionPipelineDefinition_SchemaSpecWire struct { + SourceCatalog *string `json:"source_catalog,omitempty"` + SourceSchema *string `json:"source_schema,omitempty"` + DestinationCatalog *string `json:"destination_catalog,omitempty"` + DestinationSchema *string `json:"destination_schema,omitempty"` + TableConfiguration *ingestionPipelineDefinition_TableSpecificConfigWire `json:"table_configuration,omitempty"` + ConnectorOptions *connectorOptionsWire `json:"connector_options,omitempty"` + FanoutOptions *ingestionPipelineDefinition_FanoutOptionsWire `json:"fanout_options,omitempty"` +} + +func ingestionPipelineDefinition_SchemaSpecToWire(v *IngestionPipelineDefinition_SchemaSpec) (*ingestionPipelineDefinition_SchemaSpecWire, error) { + if v == nil { + return nil, nil + } + tableConfigurationWireValue, err := ingestionPipelineDefinition_TableSpecificConfigToWire(v.TableConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_SchemaSpec.TableConfiguration", err) + } + connectorOptionsWireValue, err := connectorOptionsToWire(v.ConnectorOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_SchemaSpec.ConnectorOptions", err) + } + fanoutOptionsWireValue, err := ingestionPipelineDefinition_FanoutOptionsToWire(v.FanoutOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_SchemaSpec.FanoutOptions", err) + } + return &ingestionPipelineDefinition_SchemaSpecWire{ + SourceCatalog: v.SourceCatalog, + SourceSchema: v.SourceSchema, + DestinationCatalog: v.DestinationCatalog, + DestinationSchema: v.DestinationSchema, + TableConfiguration: tableConfigurationWireValue, + ConnectorOptions: connectorOptionsWireValue, + FanoutOptions: fanoutOptionsWireValue, + }, nil +} + +func ingestionPipelineDefinition_SchemaSpecFromWire(w *ingestionPipelineDefinition_SchemaSpecWire) (*IngestionPipelineDefinition_SchemaSpec, error) { + if w == nil { + return nil, nil + } + tableConfigurationPublicValue, err := ingestionPipelineDefinition_TableSpecificConfigFromWire(w.TableConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_SchemaSpec.TableConfiguration", err) + } + connectorOptionsPublicValue, err := connectorOptionsFromWire(w.ConnectorOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_SchemaSpec.ConnectorOptions", err) + } + fanoutOptionsPublicValue, err := ingestionPipelineDefinition_FanoutOptionsFromWire(w.FanoutOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_SchemaSpec.FanoutOptions", err) + } + return &IngestionPipelineDefinition_SchemaSpec{ + SourceCatalog: w.SourceCatalog, + SourceSchema: w.SourceSchema, + DestinationCatalog: w.DestinationCatalog, + DestinationSchema: w.DestinationSchema, + TableConfiguration: tableConfigurationPublicValue, + ConnectorOptions: connectorOptionsPublicValue, + FanoutOptions: fanoutOptionsPublicValue, + }, nil +} + +type ingestionPipelineDefinition_TableSpecWire struct { + SourceCatalog *string `json:"source_catalog,omitempty"` + SourceSchema *string `json:"source_schema,omitempty"` + SourceTable *string `json:"source_table,omitempty"` + DestinationCatalog *string `json:"destination_catalog,omitempty"` + DestinationSchema *string `json:"destination_schema,omitempty"` + DestinationTable *string `json:"destination_table,omitempty"` + TableConfiguration *ingestionPipelineDefinition_TableSpecificConfigWire `json:"table_configuration,omitempty"` + ConnectorOptions *connectorOptionsWire `json:"connector_options,omitempty"` +} + +func ingestionPipelineDefinition_TableSpecToWire(v *IngestionPipelineDefinition_TableSpec) (*ingestionPipelineDefinition_TableSpecWire, error) { + if v == nil { + return nil, nil + } + tableConfigurationWireValue, err := ingestionPipelineDefinition_TableSpecificConfigToWire(v.TableConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_TableSpec.TableConfiguration", err) + } + connectorOptionsWireValue, err := connectorOptionsToWire(v.ConnectorOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_TableSpec.ConnectorOptions", err) + } + return &ingestionPipelineDefinition_TableSpecWire{ + SourceCatalog: v.SourceCatalog, + SourceSchema: v.SourceSchema, + SourceTable: v.SourceTable, + DestinationCatalog: v.DestinationCatalog, + DestinationSchema: v.DestinationSchema, + DestinationTable: v.DestinationTable, + TableConfiguration: tableConfigurationWireValue, + ConnectorOptions: connectorOptionsWireValue, + }, nil +} + +func ingestionPipelineDefinition_TableSpecFromWire(w *ingestionPipelineDefinition_TableSpecWire) (*IngestionPipelineDefinition_TableSpec, error) { + if w == nil { + return nil, nil + } + tableConfigurationPublicValue, err := ingestionPipelineDefinition_TableSpecificConfigFromWire(w.TableConfiguration) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_TableSpec.TableConfiguration", err) + } + connectorOptionsPublicValue, err := connectorOptionsFromWire(w.ConnectorOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_TableSpec.ConnectorOptions", err) + } + return &IngestionPipelineDefinition_TableSpec{ + SourceCatalog: w.SourceCatalog, + SourceSchema: w.SourceSchema, + SourceTable: w.SourceTable, + DestinationCatalog: w.DestinationCatalog, + DestinationSchema: w.DestinationSchema, + DestinationTable: w.DestinationTable, + TableConfiguration: tableConfigurationPublicValue, + ConnectorOptions: connectorOptionsPublicValue, + }, nil +} + +type ingestionPipelineDefinition_TableSpecificConfigWire struct { + ScdType ScdType_ScdType `json:"scd_type,omitempty"` + PrimaryKeys []string `json:"primary_keys,omitempty"` + SequenceBy []string `json:"sequence_by,omitempty"` + IncludeColumns []string `json:"include_columns,omitempty"` + ExcludeColumns []string `json:"exclude_columns,omitempty"` + SalesforceIncludeFormulaFields *bool `json:"salesforce_include_formula_fields,omitempty"` + WorkdayReportParameters *ingestionPipelineDefinition_WorkdayReportParametersWire `json:"workday_report_parameters,omitempty"` + RowFilter *string `json:"row_filter,omitempty"` + QueryBasedConnectorConfig *ingestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfigWire `json:"query_based_connector_config,omitempty"` + AutoFullRefreshPolicy *autoFullRefreshPolicyWire `json:"auto_full_refresh_policy,omitempty"` + TableProperties map[string]string `json:"table_properties,omitempty"` + EnableAutoClustering *bool `json:"enable_auto_clustering,omitempty"` + ClusteringColumns []string `json:"clustering_columns,omitempty"` + SourceMetadataColumn *string `json:"source_metadata_column,omitempty"` +} + +func ingestionPipelineDefinition_TableSpecificConfigToWire(v *IngestionPipelineDefinition_TableSpecificConfig) (*ingestionPipelineDefinition_TableSpecificConfigWire, error) { + if v == nil { + return nil, nil + } + workdayReportParametersWireValue, err := ingestionPipelineDefinition_WorkdayReportParametersToWire(v.WorkdayReportParameters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_TableSpecificConfig.WorkdayReportParameters", err) + } + queryBasedConnectorConfigWireValue, err := ingestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfigToWire(v.QueryBasedConnectorConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_TableSpecificConfig.QueryBasedConnectorConfig", err) + } + autoFullRefreshPolicyWireValue, err := autoFullRefreshPolicyToWire(v.AutoFullRefreshPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_TableSpecificConfig.AutoFullRefreshPolicy", err) + } + return &ingestionPipelineDefinition_TableSpecificConfigWire{ + ScdType: v.ScdType, + PrimaryKeys: v.PrimaryKeys, + SequenceBy: v.SequenceBy, + IncludeColumns: v.IncludeColumns, + ExcludeColumns: v.ExcludeColumns, + SalesforceIncludeFormulaFields: v.SalesforceIncludeFormulaFields, + WorkdayReportParameters: workdayReportParametersWireValue, + RowFilter: v.RowFilter, + QueryBasedConnectorConfig: queryBasedConnectorConfigWireValue, + AutoFullRefreshPolicy: autoFullRefreshPolicyWireValue, + TableProperties: v.TableProperties, + EnableAutoClustering: v.EnableAutoClustering, + ClusteringColumns: v.ClusteringColumns, + SourceMetadataColumn: v.SourceMetadataColumn, + }, nil +} + +func ingestionPipelineDefinition_TableSpecificConfigFromWire(w *ingestionPipelineDefinition_TableSpecificConfigWire) (*IngestionPipelineDefinition_TableSpecificConfig, error) { + if w == nil { + return nil, nil + } + workdayReportParametersPublicValue, err := ingestionPipelineDefinition_WorkdayReportParametersFromWire(w.WorkdayReportParameters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_TableSpecificConfig.WorkdayReportParameters", err) + } + queryBasedConnectorConfigPublicValue, err := ingestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfigFromWire(w.QueryBasedConnectorConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_TableSpecificConfig.QueryBasedConnectorConfig", err) + } + autoFullRefreshPolicyPublicValue, err := autoFullRefreshPolicyFromWire(w.AutoFullRefreshPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_TableSpecificConfig.AutoFullRefreshPolicy", err) + } + return &IngestionPipelineDefinition_TableSpecificConfig{ + ScdType: w.ScdType, + PrimaryKeys: w.PrimaryKeys, + SequenceBy: w.SequenceBy, + IncludeColumns: w.IncludeColumns, + ExcludeColumns: w.ExcludeColumns, + SalesforceIncludeFormulaFields: w.SalesforceIncludeFormulaFields, + WorkdayReportParameters: workdayReportParametersPublicValue, + RowFilter: w.RowFilter, + QueryBasedConnectorConfig: queryBasedConnectorConfigPublicValue, + AutoFullRefreshPolicy: autoFullRefreshPolicyPublicValue, + TableProperties: w.TableProperties, + EnableAutoClustering: w.EnableAutoClustering, + ClusteringColumns: w.ClusteringColumns, + SourceMetadataColumn: w.SourceMetadataColumn, + }, nil +} + +type ingestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfigWire struct { + CursorColumns []string `json:"cursor_columns,omitempty"` + DeletionCondition *string `json:"deletion_condition,omitempty"` + HardDeletionSyncMinIntervalInSeconds *int64 `json:"hard_deletion_sync_min_interval_in_seconds,omitempty"` +} + +func ingestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfigToWire(v *IngestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfig) (*ingestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfigWire, error) { + if v == nil { + return nil, nil + } + return &ingestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfigWire{ + CursorColumns: v.CursorColumns, + DeletionCondition: v.DeletionCondition, + HardDeletionSyncMinIntervalInSeconds: v.HardDeletionSyncMinIntervalInSeconds, + }, nil +} + +func ingestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfigFromWire(w *ingestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfigWire) (*IngestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfig, error) { + if w == nil { + return nil, nil + } + return &IngestionPipelineDefinition_TableSpecificConfig_QueryBasedConnectorConfig{ + CursorColumns: w.CursorColumns, + DeletionCondition: w.DeletionCondition, + HardDeletionSyncMinIntervalInSeconds: w.HardDeletionSyncMinIntervalInSeconds, + }, nil +} + +type ingestionPipelineDefinition_WorkdayReportParametersWire struct { + Incremental *bool `json:"incremental,omitempty"` + ReportParameters []ingestionPipelineDefinition_WorkdayReportParameters_QueryKeyValueWire `json:"report_parameters,omitempty"` + Parameters map[string]string `json:"parameters,omitempty"` +} + +func ingestionPipelineDefinition_WorkdayReportParametersToWire(v *IngestionPipelineDefinition_WorkdayReportParameters) (*ingestionPipelineDefinition_WorkdayReportParametersWire, error) { + if v == nil { + return nil, nil + } + reportParametersWireValue, err := convertSlice(v.ReportParameters, ingestionPipelineDefinition_WorkdayReportParameters_QueryKeyValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_WorkdayReportParameters.ReportParameters", err) + } + return &ingestionPipelineDefinition_WorkdayReportParametersWire{ + Incremental: v.Incremental, + ReportParameters: reportParametersWireValue, + Parameters: v.Parameters, + }, nil +} + +func ingestionPipelineDefinition_WorkdayReportParametersFromWire(w *ingestionPipelineDefinition_WorkdayReportParametersWire) (*IngestionPipelineDefinition_WorkdayReportParameters, error) { + if w == nil { + return nil, nil + } + reportParametersPublicValue, err := convertSlice(w.ReportParameters, ingestionPipelineDefinition_WorkdayReportParameters_QueryKeyValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "IngestionPipelineDefinition_WorkdayReportParameters.ReportParameters", err) + } + return &IngestionPipelineDefinition_WorkdayReportParameters{ + Incremental: w.Incremental, + ReportParameters: reportParametersPublicValue, + Parameters: w.Parameters, + }, nil +} + +type ingestionPipelineDefinition_WorkdayReportParameters_QueryKeyValueWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func ingestionPipelineDefinition_WorkdayReportParameters_QueryKeyValueToWire(v *IngestionPipelineDefinition_WorkdayReportParameters_QueryKeyValue) (*ingestionPipelineDefinition_WorkdayReportParameters_QueryKeyValueWire, error) { + if v == nil { + return nil, nil + } + return &ingestionPipelineDefinition_WorkdayReportParameters_QueryKeyValueWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func ingestionPipelineDefinition_WorkdayReportParameters_QueryKeyValueFromWire(w *ingestionPipelineDefinition_WorkdayReportParameters_QueryKeyValueWire) (*IngestionPipelineDefinition_WorkdayReportParameters_QueryKeyValue, error) { + if w == nil { + return nil, nil + } + return &IngestionPipelineDefinition_WorkdayReportParameters_QueryKeyValue{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type jiraConnectorOptionsWire struct { + IncludeJiraSpaces []string `json:"include_jira_spaces,omitempty"` +} + +func jiraConnectorOptionsToWire(v *JiraConnectorOptions) (*jiraConnectorOptionsWire, error) { + if v == nil { + return nil, nil + } + return &jiraConnectorOptionsWire{ + IncludeJiraSpaces: v.IncludeJiraSpaces, + }, nil +} + +func jiraConnectorOptionsFromWire(w *jiraConnectorOptionsWire) (*JiraConnectorOptions, error) { + if w == nil { + return nil, nil + } + return &JiraConnectorOptions{ + IncludeJiraSpaces: w.IncludeJiraSpaces, + }, nil +} + +type jsonTransformerOptionsWire struct { + AsVariant *bool `json:"as_variant,omitempty"` + Schema *string `json:"schema,omitempty"` + SchemaFilePath *string `json:"schema_file_path,omitempty"` + SchemaEvolutionMode FileIngestionOptions_SchemaEvolutionMode `json:"schema_evolution_mode,omitempty"` + SchemaHints *string `json:"schema_hints,omitempty"` +} + +func jsonTransformerOptionsToWire(v *JsonTransformerOptions) (*jsonTransformerOptionsWire, error) { + if v == nil { + return nil, nil + } + return &jsonTransformerOptionsWire{ + AsVariant: v.AsVariant, + Schema: v.Schema, + SchemaFilePath: v.SchemaFilePath, + SchemaEvolutionMode: v.SchemaEvolutionMode, + SchemaHints: v.SchemaHints, + }, nil +} + +func jsonTransformerOptionsFromWire(w *jsonTransformerOptionsWire) (*JsonTransformerOptions, error) { + if w == nil { + return nil, nil + } + return &JsonTransformerOptions{ + AsVariant: w.AsVariant, + Schema: w.Schema, + SchemaFilePath: w.SchemaFilePath, + SchemaEvolutionMode: w.SchemaEvolutionMode, + SchemaHints: w.SchemaHints, + }, nil +} + +type kafkaOptionsWire struct { + Topics []string `json:"topics,omitempty"` + TopicPattern *string `json:"topic_pattern,omitempty"` + KeyTransformer *transformerWire `json:"key_transformer,omitempty"` + ValueTransformer *transformerWire `json:"value_transformer,omitempty"` + StartingOffset *string `json:"starting_offset,omitempty"` + MaxOffsetsPerTrigger *int64 `json:"max_offsets_per_trigger,omitempty"` + ClientConfig map[string]string `json:"client_config,omitempty"` +} + +func kafkaOptionsToWire(v *KafkaOptions) (*kafkaOptionsWire, error) { + if v == nil { + return nil, nil + } + keyTransformerWireValue, err := transformerToWire(v.KeyTransformer) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaOptions.KeyTransformer", err) + } + valueTransformerWireValue, err := transformerToWire(v.ValueTransformer) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaOptions.ValueTransformer", err) + } + return &kafkaOptionsWire{ + Topics: v.Topics, + TopicPattern: v.TopicPattern, + KeyTransformer: keyTransformerWireValue, + ValueTransformer: valueTransformerWireValue, + StartingOffset: v.StartingOffset, + MaxOffsetsPerTrigger: v.MaxOffsetsPerTrigger, + ClientConfig: v.ClientConfig, + }, nil +} + +func kafkaOptionsFromWire(w *kafkaOptionsWire) (*KafkaOptions, error) { + if w == nil { + return nil, nil + } + keyTransformerPublicValue, err := transformerFromWire(w.KeyTransformer) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaOptions.KeyTransformer", err) + } + valueTransformerPublicValue, err := transformerFromWire(w.ValueTransformer) + if err != nil { + return nil, fmt.Errorf("%s: %w", "KafkaOptions.ValueTransformer", err) + } + return &KafkaOptions{ + Topics: w.Topics, + TopicPattern: w.TopicPattern, + KeyTransformer: keyTransformerPublicValue, + ValueTransformer: valueTransformerPublicValue, + StartingOffset: w.StartingOffset, + MaxOffsetsPerTrigger: w.MaxOffsetsPerTrigger, + ClientConfig: w.ClientConfig, + }, nil +} + +type linkedInAdsOptionsWire struct { + SyncStartDate *string `json:"sync_start_date,omitempty"` + LookbackWindowDays *int `json:"lookback_window_days,omitempty"` + CustomReportOptions *linkedInAdsOptions_LinkedInAdsCustomReportOptionsWire `json:"custom_report_options,omitempty"` +} + +func linkedInAdsOptionsToWire(v *LinkedInAdsOptions) (*linkedInAdsOptionsWire, error) { + if v == nil { + return nil, nil + } + customReportOptionsWireValue, err := linkedInAdsOptions_LinkedInAdsCustomReportOptionsToWire(v.CustomReportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LinkedInAdsOptions.CustomReportOptions", err) + } + return &linkedInAdsOptionsWire{ + SyncStartDate: v.SyncStartDate, + LookbackWindowDays: v.LookbackWindowDays, + CustomReportOptions: customReportOptionsWireValue, + }, nil +} + +func linkedInAdsOptionsFromWire(w *linkedInAdsOptionsWire) (*LinkedInAdsOptions, error) { + if w == nil { + return nil, nil + } + customReportOptionsPublicValue, err := linkedInAdsOptions_LinkedInAdsCustomReportOptionsFromWire(w.CustomReportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "LinkedInAdsOptions.CustomReportOptions", err) + } + return &LinkedInAdsOptions{ + SyncStartDate: w.SyncStartDate, + LookbackWindowDays: w.LookbackWindowDays, + CustomReportOptions: customReportOptionsPublicValue, + }, nil +} + +type linkedInAdsOptions_LinkedInAdsCustomReportOptionsWire struct { + Finder LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsFinder `json:"finder,omitempty"` + EntityGranularity []LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsEntityGranularity `json:"entity_granularity,omitempty"` + TimeGranularity LinkedInAdsOptions_LinkedInAdsCustomReportOptions_LinkedInAdsTimeGranularity `json:"time_granularity,omitempty"` + Metrics []string `json:"metrics,omitempty"` +} + +func linkedInAdsOptions_LinkedInAdsCustomReportOptionsToWire(v *LinkedInAdsOptions_LinkedInAdsCustomReportOptions) (*linkedInAdsOptions_LinkedInAdsCustomReportOptionsWire, error) { + if v == nil { + return nil, nil + } + return &linkedInAdsOptions_LinkedInAdsCustomReportOptionsWire{ + Finder: v.Finder, + EntityGranularity: v.EntityGranularity, + TimeGranularity: v.TimeGranularity, + Metrics: v.Metrics, + }, nil +} + +func linkedInAdsOptions_LinkedInAdsCustomReportOptionsFromWire(w *linkedInAdsOptions_LinkedInAdsCustomReportOptionsWire) (*LinkedInAdsOptions_LinkedInAdsCustomReportOptions, error) { + if w == nil { + return nil, nil + } + return &LinkedInAdsOptions_LinkedInAdsCustomReportOptions{ + Finder: w.Finder, + EntityGranularity: w.EntityGranularity, + TimeGranularity: w.TimeGranularity, + Metrics: w.Metrics, + }, nil +} + +type listPipelineEventsRequestWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + OrderBy []string `json:"order_by,omitempty"` + Filter *string `json:"filter,omitempty"` +} + +func listPipelineEventsRequestToWire(v *ListPipelineEventsRequest) (*listPipelineEventsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listPipelineEventsRequestWire{ + PipelineId: v.PipelineId, + PageToken: v.PageToken, + MaxResults: v.MaxResults, + OrderBy: v.OrderBy, + Filter: v.Filter, + }, nil +} + +type listPipelineEventsResponseWire struct { + Events []pipelineEventWire `json:"events,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` + PrevPageToken *string `json:"prev_page_token,omitempty"` +} + +func listPipelineEventsResponseFromWire(w *listPipelineEventsResponseWire) (*ListPipelineEventsResponse, error) { + if w == nil { + return nil, nil + } + eventsPublicValue, err := convertSlice(w.Events, pipelineEventFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPipelineEventsResponse.Events", err) + } + return &ListPipelineEventsResponse{ + Events: eventsPublicValue, + NextPageToken: w.NextPageToken, + PrevPageToken: w.PrevPageToken, + }, nil +} + +type listPipelinesRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + OrderBy []string `json:"order_by,omitempty"` + Filter *string `json:"filter,omitempty"` +} + +func listPipelinesRequestToWire(v *ListPipelinesRequest) (*listPipelinesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listPipelinesRequestWire{ + PageToken: v.PageToken, + MaxResults: v.MaxResults, + OrderBy: v.OrderBy, + Filter: v.Filter, + }, nil +} + +type listPipelinesResponseWire struct { + Statuses []pipelineStateInfoWire `json:"statuses,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listPipelinesResponseFromWire(w *listPipelinesResponseWire) (*ListPipelinesResponse, error) { + if w == nil { + return nil, nil + } + statusesPublicValue, err := convertSlice(w.Statuses, pipelineStateInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPipelinesResponse.Statuses", err) + } + return &ListPipelinesResponse{ + Statuses: statusesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listUpdatesRequestWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + UntilUpdateId *string `json:"until_update_id,omitempty"` +} + +func listUpdatesRequestToWire(v *ListUpdatesRequest) (*listUpdatesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listUpdatesRequestWire{ + PipelineId: v.PipelineId, + PageToken: v.PageToken, + MaxResults: v.MaxResults, + UntilUpdateId: v.UntilUpdateId, + }, nil +} + +type listUpdatesResponseWire struct { + Updates []updateInfoWire `json:"updates,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` + PrevPageToken *string `json:"prev_page_token,omitempty"` +} + +func listUpdatesResponseFromWire(w *listUpdatesResponseWire) (*ListUpdatesResponse, error) { + if w == nil { + return nil, nil + } + updatesPublicValue, err := convertSlice(w.Updates, updateInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListUpdatesResponse.Updates", err) + } + return &ListUpdatesResponse{ + Updates: updatesPublicValue, + NextPageToken: w.NextPageToken, + PrevPageToken: w.PrevPageToken, + }, nil +} + +type manualTriggerWire struct { +} + +func manualTriggerToWire(v *ManualTrigger) (*manualTriggerWire, error) { + if v == nil { + return nil, nil + } + return &manualTriggerWire{}, nil +} + +func manualTriggerFromWire(w *manualTriggerWire) (*ManualTrigger, error) { + if w == nil { + return nil, nil + } + return &ManualTrigger{}, nil +} + +type marketoOptionsWire struct { + SyncStartDate *string `json:"sync_start_date,omitempty"` +} + +func marketoOptionsToWire(v *MarketoOptions) (*marketoOptionsWire, error) { + if v == nil { + return nil, nil + } + return &marketoOptionsWire{ + SyncStartDate: v.SyncStartDate, + }, nil +} + +func marketoOptionsFromWire(w *marketoOptionsWire) (*MarketoOptions, error) { + if w == nil { + return nil, nil + } + return &MarketoOptions{ + SyncStartDate: w.SyncStartDate, + }, nil +} + +type metaMarketingOptionsWire struct { + Level *string `json:"level,omitempty"` + Breakdowns []string `json:"breakdowns,omitempty"` + ActionBreakdowns []string `json:"action_breakdowns,omitempty"` + ActionReportTime *string `json:"action_report_time,omitempty"` + StartDate *string `json:"start_date,omitempty"` + CustomInsightsLookbackWindow *int `json:"custom_insights_lookback_window,omitempty"` + TimeIncrement *string `json:"time_increment,omitempty"` + ActionAttributionWindows []string `json:"action_attribution_windows,omitempty"` + CustomReportOptions *metaMarketingOptions_MetaMarketingCustomReportOptionsWire `json:"custom_report_options,omitempty"` +} + +func metaMarketingOptionsToWire(v *MetaMarketingOptions) (*metaMarketingOptionsWire, error) { + if v == nil { + return nil, nil + } + customReportOptionsWireValue, err := metaMarketingOptions_MetaMarketingCustomReportOptionsToWire(v.CustomReportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MetaMarketingOptions.CustomReportOptions", err) + } + return &metaMarketingOptionsWire{ + Level: v.Level, + Breakdowns: v.Breakdowns, + ActionBreakdowns: v.ActionBreakdowns, + ActionReportTime: v.ActionReportTime, + StartDate: v.StartDate, + CustomInsightsLookbackWindow: v.CustomInsightsLookbackWindow, + TimeIncrement: v.TimeIncrement, + ActionAttributionWindows: v.ActionAttributionWindows, + CustomReportOptions: customReportOptionsWireValue, + }, nil +} + +func metaMarketingOptionsFromWire(w *metaMarketingOptionsWire) (*MetaMarketingOptions, error) { + if w == nil { + return nil, nil + } + customReportOptionsPublicValue, err := metaMarketingOptions_MetaMarketingCustomReportOptionsFromWire(w.CustomReportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MetaMarketingOptions.CustomReportOptions", err) + } + return &MetaMarketingOptions{ + Level: w.Level, + Breakdowns: w.Breakdowns, + ActionBreakdowns: w.ActionBreakdowns, + ActionReportTime: w.ActionReportTime, + StartDate: w.StartDate, + CustomInsightsLookbackWindow: w.CustomInsightsLookbackWindow, + TimeIncrement: w.TimeIncrement, + ActionAttributionWindows: w.ActionAttributionWindows, + CustomReportOptions: customReportOptionsPublicValue, + }, nil +} + +type metaMarketingOptions_MetaMarketingCustomReportOptionsWire struct { + Level *string `json:"level,omitempty"` + Breakdowns []string `json:"breakdowns,omitempty"` + ActionBreakdowns []string `json:"action_breakdowns,omitempty"` + ActionReportTime *string `json:"action_report_time,omitempty"` + TimeIncrement *string `json:"time_increment,omitempty"` + ActionAttributionWindows []string `json:"action_attribution_windows,omitempty"` +} + +func metaMarketingOptions_MetaMarketingCustomReportOptionsToWire(v *MetaMarketingOptions_MetaMarketingCustomReportOptions) (*metaMarketingOptions_MetaMarketingCustomReportOptionsWire, error) { + if v == nil { + return nil, nil + } + return &metaMarketingOptions_MetaMarketingCustomReportOptionsWire{ + Level: v.Level, + Breakdowns: v.Breakdowns, + ActionBreakdowns: v.ActionBreakdowns, + ActionReportTime: v.ActionReportTime, + TimeIncrement: v.TimeIncrement, + ActionAttributionWindows: v.ActionAttributionWindows, + }, nil +} + +func metaMarketingOptions_MetaMarketingCustomReportOptionsFromWire(w *metaMarketingOptions_MetaMarketingCustomReportOptionsWire) (*MetaMarketingOptions_MetaMarketingCustomReportOptions, error) { + if w == nil { + return nil, nil + } + return &MetaMarketingOptions_MetaMarketingCustomReportOptions{ + Level: w.Level, + Breakdowns: w.Breakdowns, + ActionBreakdowns: w.ActionBreakdowns, + ActionReportTime: w.ActionReportTime, + TimeIncrement: w.TimeIncrement, + ActionAttributionWindows: w.ActionAttributionWindows, + }, nil +} + +type notebookLibraryWire struct { + Path *string `json:"path,omitempty"` +} + +func notebookLibraryToWire(v *NotebookLibrary) (*notebookLibraryWire, error) { + if v == nil { + return nil, nil + } + return ¬ebookLibraryWire{ + Path: v.Path, + }, nil +} + +func notebookLibraryFromWire(w *notebookLibraryWire) (*NotebookLibrary, error) { + if w == nil { + return nil, nil + } + return &NotebookLibrary{ + Path: w.Path, + }, nil +} + +type notificationsWire struct { + EmailRecipients []string `json:"email_recipients,omitempty"` + Alerts []string `json:"alerts,omitempty"` +} + +func notificationsToWire(v *Notifications) (*notificationsWire, error) { + if v == nil { + return nil, nil + } + return ¬ificationsWire{ + EmailRecipients: v.EmailRecipients, + Alerts: v.Alerts, + }, nil +} + +func notificationsFromWire(w *notificationsWire) (*Notifications, error) { + if w == nil { + return nil, nil + } + return &Notifications{ + EmailRecipients: w.EmailRecipients, + Alerts: w.Alerts, + }, nil +} + +type operationTimeWindowWire struct { + StartHour *int `json:"start_hour,omitempty"` + DaysOfWeek []DayOfWeek `json:"days_of_week,omitempty"` + TimeZoneId *string `json:"time_zone_id,omitempty"` +} + +func operationTimeWindowToWire(v *OperationTimeWindow) (*operationTimeWindowWire, error) { + if v == nil { + return nil, nil + } + return &operationTimeWindowWire{ + StartHour: v.StartHour, + DaysOfWeek: v.DaysOfWeek, + TimeZoneId: v.TimeZoneId, + }, nil +} + +func operationTimeWindowFromWire(w *operationTimeWindowWire) (*OperationTimeWindow, error) { + if w == nil { + return nil, nil + } + return &OperationTimeWindow{ + StartHour: w.StartHour, + DaysOfWeek: w.DaysOfWeek, + TimeZoneId: w.TimeZoneId, + }, nil +} + +type originWire struct { + Cloud *string `json:"cloud,omitempty"` + Region *string `json:"region,omitempty"` + OrgId *int64 `json:"org_id,omitempty"` + PipelineId *string `json:"pipeline_id,omitempty"` + PipelineName *string `json:"pipeline_name,omitempty"` + ClusterId *string `json:"cluster_id,omitempty"` + UpdateId *string `json:"update_id,omitempty"` + MaintenanceId *string `json:"maintenance_id,omitempty"` + TableId *string `json:"table_id,omitempty"` + DatasetName *string `json:"dataset_name,omitempty"` + FlowId *string `json:"flow_id,omitempty"` + FlowName *string `json:"flow_name,omitempty"` + BatchId *int64 `json:"batch_id,omitempty"` + RequestId *string `json:"request_id,omitempty"` + UcResourceId *string `json:"uc_resource_id,omitempty"` + Host *string `json:"host,omitempty"` + MaterializationName *string `json:"materialization_name,omitempty"` + IngestionSourceConnectionName *string `json:"ingestion_source_connection_name,omitempty"` + IngestionSourceCatalogName *string `json:"ingestion_source_catalog_name,omitempty"` + IngestionSourceSchemaName *string `json:"ingestion_source_schema_name,omitempty"` + IngestionSourceTableName *string `json:"ingestion_source_table_name,omitempty"` + IngestionSourceTableVersion *string `json:"ingestion_source_table_version,omitempty"` +} + +func originFromWire(w *originWire) (*Origin, error) { + if w == nil { + return nil, nil + } + return &Origin{ + Cloud: w.Cloud, + Region: w.Region, + OrgId: w.OrgId, + PipelineId: w.PipelineId, + PipelineName: w.PipelineName, + ClusterId: w.ClusterId, + UpdateId: w.UpdateId, + MaintenanceId: w.MaintenanceId, + TableId: w.TableId, + DatasetName: w.DatasetName, + FlowId: w.FlowId, + FlowName: w.FlowName, + BatchId: w.BatchId, + RequestId: w.RequestId, + UcResourceId: w.UcResourceId, + Host: w.Host, + MaterializationName: w.MaterializationName, + IngestionSourceConnectionName: w.IngestionSourceConnectionName, + IngestionSourceCatalogName: w.IngestionSourceCatalogName, + IngestionSourceSchemaName: w.IngestionSourceSchemaName, + IngestionSourceTableName: w.IngestionSourceTableName, + IngestionSourceTableVersion: w.IngestionSourceTableVersion, + }, nil +} + +type outlookOptionsWire struct { + FolderFilter []string `json:"folder_filter,omitempty"` + SenderFilter []string `json:"sender_filter,omitempty"` + SubjectFilter []string `json:"subject_filter,omitempty"` + StartDate *string `json:"start_date,omitempty"` + BodyFormat OutlookBodyFormat `json:"body_format,omitempty"` + AttachmentMode OutlookAttachmentMode `json:"attachment_mode,omitempty"` + IncludeMailboxes []string `json:"include_mailboxes,omitempty"` + IncludeFolders []string `json:"include_folders,omitempty"` + IncludeSenders []string `json:"include_senders,omitempty"` + IncludeSubjects []string `json:"include_subjects,omitempty"` +} + +func outlookOptionsToWire(v *OutlookOptions) (*outlookOptionsWire, error) { + if v == nil { + return nil, nil + } + return &outlookOptionsWire{ + FolderFilter: v.FolderFilter, + SenderFilter: v.SenderFilter, + SubjectFilter: v.SubjectFilter, + StartDate: v.StartDate, + BodyFormat: v.BodyFormat, + AttachmentMode: v.AttachmentMode, + IncludeMailboxes: v.IncludeMailboxes, + IncludeFolders: v.IncludeFolders, + IncludeSenders: v.IncludeSenders, + IncludeSubjects: v.IncludeSubjects, + }, nil +} + +func outlookOptionsFromWire(w *outlookOptionsWire) (*OutlookOptions, error) { + if w == nil { + return nil, nil + } + return &OutlookOptions{ + FolderFilter: w.FolderFilter, + SenderFilter: w.SenderFilter, + SubjectFilter: w.SubjectFilter, + StartDate: w.StartDate, + BodyFormat: w.BodyFormat, + AttachmentMode: w.AttachmentMode, + IncludeMailboxes: w.IncludeMailboxes, + IncludeFolders: w.IncludeFolders, + IncludeSenders: w.IncludeSenders, + IncludeSubjects: w.IncludeSubjects, + }, nil +} + +type pathPatternWire struct { + Include *string `json:"include,omitempty"` +} + +func pathPatternToWire(v *PathPattern) (*pathPatternWire, error) { + if v == nil { + return nil, nil + } + return &pathPatternWire{ + Include: v.Include, + }, nil +} + +func pathPatternFromWire(w *pathPatternWire) (*PathPattern, error) { + if w == nil { + return nil, nil + } + return &PathPattern{ + Include: w.Include, + }, nil +} + +type pipelineClusterWire struct { + Label *string `json:"label,omitempty"` + ApplyPolicyDefaultValues *bool `json:"apply_policy_default_values,omitempty"` + SparkConf map[string]string `json:"spark_conf,omitempty"` + AwsAttributes *pipelinesAwsAttributesWire `json:"aws_attributes,omitempty"` + AzureAttributes *pipelinesAzureAttributesWire `json:"azure_attributes,omitempty"` + GcpAttributes *pipelinesGcpAttributesWire `json:"gcp_attributes,omitempty"` + NodeTypeId *string `json:"node_type_id,omitempty"` + DriverNodeTypeId *string `json:"driver_node_type_id,omitempty"` + SshPublicKeys []string `json:"ssh_public_keys,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + ClusterLogConf *pipelinesClusterLogConfWire `json:"cluster_log_conf,omitempty"` + SparkEnvVars map[string]string `json:"spark_env_vars,omitempty"` + InitScripts []pipelinesInitScriptInfoWire `json:"init_scripts,omitempty"` + InstancePoolId *string `json:"instance_pool_id,omitempty"` + PolicyId *string `json:"policy_id,omitempty"` + EnableLocalDiskEncryption *bool `json:"enable_local_disk_encryption,omitempty"` + DriverInstancePoolId *string `json:"driver_instance_pool_id,omitempty"` + NumWorkers *int `json:"num_workers,omitempty"` + Autoscale *pipelinesAutoScaleWire `json:"autoscale,omitempty"` +} + +func pipelineClusterToWire(v *PipelineCluster) (*pipelineClusterWire, error) { + if v == nil { + return nil, nil + } + awsAttributesWireValue, err := pipelinesAwsAttributesToWire(v.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.AwsAttributes", err) + } + azureAttributesWireValue, err := pipelinesAzureAttributesToWire(v.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.AzureAttributes", err) + } + gcpAttributesWireValue, err := pipelinesGcpAttributesToWire(v.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.GcpAttributes", err) + } + clusterLogConfWireValue, err := pipelinesClusterLogConfToWire(v.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.ClusterLogConf", err) + } + initScriptsWireValue, err := convertSlice(v.InitScripts, pipelinesInitScriptInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.InitScripts", err) + } + var sizeNumWorkersWire *int + var sizeAutoscaleWire *pipelinesAutoScaleWire + switch value := v.Size.(type) { + case nil: + case *PipelineCluster_Size_NumWorkers: + if value != nil { + sizeNumWorkersWire = new(value.NumWorkers) + } + case *PipelineCluster_Size_Autoscale: + if value != nil { + sizeAutoscaleConverted, err := pipelinesAutoScaleToWire(&value.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.Size.Autoscale", err) + } + sizeAutoscaleWire = sizeAutoscaleConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "PipelineCluster.Size", value) + } + return &pipelineClusterWire{ + Label: v.Label, + ApplyPolicyDefaultValues: v.ApplyPolicyDefaultValues, + SparkConf: v.SparkConf, + AwsAttributes: awsAttributesWireValue, + AzureAttributes: azureAttributesWireValue, + GcpAttributes: gcpAttributesWireValue, + NodeTypeId: v.NodeTypeId, + DriverNodeTypeId: v.DriverNodeTypeId, + SshPublicKeys: v.SshPublicKeys, + CustomTags: v.CustomTags, + ClusterLogConf: clusterLogConfWireValue, + SparkEnvVars: v.SparkEnvVars, + InitScripts: initScriptsWireValue, + InstancePoolId: v.InstancePoolId, + PolicyId: v.PolicyId, + EnableLocalDiskEncryption: v.EnableLocalDiskEncryption, + DriverInstancePoolId: v.DriverInstancePoolId, + NumWorkers: sizeNumWorkersWire, + Autoscale: sizeAutoscaleWire, + }, nil +} + +func pipelineClusterFromWire(w *pipelineClusterWire) (*PipelineCluster, error) { + if w == nil { + return nil, nil + } + sizeMembers := 0 + if w.NumWorkers != nil { + sizeMembers++ + } + if w.Autoscale != nil { + sizeMembers++ + } + if sizeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PipelineCluster.Size") + } + awsAttributesPublicValue, err := pipelinesAwsAttributesFromWire(w.AwsAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.AwsAttributes", err) + } + azureAttributesPublicValue, err := pipelinesAzureAttributesFromWire(w.AzureAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.AzureAttributes", err) + } + gcpAttributesPublicValue, err := pipelinesGcpAttributesFromWire(w.GcpAttributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.GcpAttributes", err) + } + clusterLogConfPublicValue, err := pipelinesClusterLogConfFromWire(w.ClusterLogConf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.ClusterLogConf", err) + } + initScriptsPublicValue, err := convertSlice(w.InitScripts, pipelinesInitScriptInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.InitScripts", err) + } + var sizeSelection isPipelineCluster_Size + switch { + case w.NumWorkers != nil: + sizeSelection = &PipelineCluster_Size_NumWorkers{NumWorkers: *w.NumWorkers} + case w.Autoscale != nil: + sizeAutoscaleConverted, err := pipelinesAutoScaleFromWire(w.Autoscale) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineCluster.Size.Autoscale", err) + } + sizeSelection = &PipelineCluster_Size_Autoscale{Autoscale: *sizeAutoscaleConverted} + } + return &PipelineCluster{ + Label: w.Label, + ApplyPolicyDefaultValues: w.ApplyPolicyDefaultValues, + SparkConf: w.SparkConf, + AwsAttributes: awsAttributesPublicValue, + AzureAttributes: azureAttributesPublicValue, + GcpAttributes: gcpAttributesPublicValue, + NodeTypeId: w.NodeTypeId, + DriverNodeTypeId: w.DriverNodeTypeId, + SshPublicKeys: w.SshPublicKeys, + CustomTags: w.CustomTags, + ClusterLogConf: clusterLogConfPublicValue, + SparkEnvVars: w.SparkEnvVars, + InitScripts: initScriptsPublicValue, + InstancePoolId: w.InstancePoolId, + PolicyId: w.PolicyId, + EnableLocalDiskEncryption: w.EnableLocalDiskEncryption, + DriverInstancePoolId: w.DriverInstancePoolId, + Size: sizeSelection, + }, nil +} + +type pipelineDeploymentWire struct { + Kind DeploymentKind `json:"kind,omitempty"` + MetadataFilePath *string `json:"metadata_file_path,omitempty"` + DeploymentId *string `json:"deployment_id,omitempty"` + VersionId *string `json:"version_id,omitempty"` +} + +func pipelineDeploymentToWire(v *PipelineDeployment) (*pipelineDeploymentWire, error) { + if v == nil { + return nil, nil + } + return &pipelineDeploymentWire{ + Kind: v.Kind, + MetadataFilePath: v.MetadataFilePath, + DeploymentId: v.DeploymentId, + VersionId: v.VersionId, + }, nil +} + +func pipelineDeploymentFromWire(w *pipelineDeploymentWire) (*PipelineDeployment, error) { + if w == nil { + return nil, nil + } + return &PipelineDeployment{ + Kind: w.Kind, + MetadataFilePath: w.MetadataFilePath, + DeploymentId: w.DeploymentId, + VersionId: w.VersionId, + }, nil +} + +type pipelineEventWire struct { + Id *string `json:"id,omitempty"` + Sequence *sequencingWire `json:"sequence,omitempty"` + Origin *originWire `json:"origin,omitempty"` + Timestamp *string `json:"timestamp,omitempty"` + Message *string `json:"message,omitempty"` + Level EventLevel `json:"level,omitempty"` + Error *errorDetailWire `json:"error,omitempty"` + EventType *string `json:"event_type,omitempty"` + MaturityLevel MaturityLevel `json:"maturity_level,omitempty"` + Truncation *truncationWire `json:"truncation,omitempty"` +} + +func pipelineEventFromWire(w *pipelineEventWire) (*PipelineEvent, error) { + if w == nil { + return nil, nil + } + sequencePublicValue, err := sequencingFromWire(w.Sequence) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineEvent.Sequence", err) + } + originPublicValue, err := originFromWire(w.Origin) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineEvent.Origin", err) + } + errorPublicValue, err := errorDetailFromWire(w.Error) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineEvent.Error", err) + } + truncationPublicValue, err := truncationFromWire(w.Truncation) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineEvent.Truncation", err) + } + return &PipelineEvent{ + Id: w.Id, + Sequence: sequencePublicValue, + Origin: originPublicValue, + Timestamp: w.Timestamp, + Message: w.Message, + Level: w.Level, + Error: errorPublicValue, + EventType: w.EventType, + MaturityLevel: w.MaturityLevel, + Truncation: truncationPublicValue, + }, nil +} + +type pipelineLibraryWire struct { + Jar *string `json:"jar,omitempty"` + Maven *pipelinesMavenLibraryWire `json:"maven,omitempty"` + Whl *string `json:"whl,omitempty"` + Notebook *notebookLibraryWire `json:"notebook,omitempty"` + File *notebookLibraryWire `json:"file,omitempty"` + Glob *pathPatternWire `json:"glob,omitempty"` +} + +func pipelineLibraryToWire(v *PipelineLibrary) (*pipelineLibraryWire, error) { + if v == nil { + return nil, nil + } + var libJarWire *string + var libMavenWire *pipelinesMavenLibraryWire + var libWhlWire *string + var libNotebookWire *notebookLibraryWire + var libFileWire *notebookLibraryWire + var libGlobWire *pathPatternWire + switch value := v.Lib.(type) { + case nil: + case *PipelineLibrary_Lib_Jar: + if value != nil { + libJarWire = new(value.Jar) + } + case *PipelineLibrary_Lib_Maven: + if value != nil { + libMavenConverted, err := pipelinesMavenLibraryToWire(&value.Maven) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineLibrary.Lib.Maven", err) + } + libMavenWire = libMavenConverted + } + case *PipelineLibrary_Lib_Whl: + if value != nil { + libWhlWire = new(value.Whl) + } + case *PipelineLibrary_Lib_Notebook: + if value != nil { + libNotebookConverted, err := notebookLibraryToWire(&value.Notebook) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineLibrary.Lib.Notebook", err) + } + libNotebookWire = libNotebookConverted + } + case *PipelineLibrary_Lib_File: + if value != nil { + libFileConverted, err := notebookLibraryToWire(&value.File) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineLibrary.Lib.File", err) + } + libFileWire = libFileConverted + } + case *PipelineLibrary_Lib_Glob: + if value != nil { + libGlobConverted, err := pathPatternToWire(&value.Glob) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineLibrary.Lib.Glob", err) + } + libGlobWire = libGlobConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "PipelineLibrary.Lib", value) + } + return &pipelineLibraryWire{ + Jar: libJarWire, + Maven: libMavenWire, + Whl: libWhlWire, + Notebook: libNotebookWire, + File: libFileWire, + Glob: libGlobWire, + }, nil +} + +func pipelineLibraryFromWire(w *pipelineLibraryWire) (*PipelineLibrary, error) { + if w == nil { + return nil, nil + } + libMembers := 0 + if w.Jar != nil { + libMembers++ + } + if w.Maven != nil { + libMembers++ + } + if w.Whl != nil { + libMembers++ + } + if w.Notebook != nil { + libMembers++ + } + if w.File != nil { + libMembers++ + } + if w.Glob != nil { + libMembers++ + } + if libMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PipelineLibrary.Lib") + } + var libSelection isPipelineLibrary_Lib + switch { + case w.Jar != nil: + libSelection = &PipelineLibrary_Lib_Jar{Jar: *w.Jar} + case w.Maven != nil: + libMavenConverted, err := pipelinesMavenLibraryFromWire(w.Maven) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineLibrary.Lib.Maven", err) + } + libSelection = &PipelineLibrary_Lib_Maven{Maven: *libMavenConverted} + case w.Whl != nil: + libSelection = &PipelineLibrary_Lib_Whl{Whl: *w.Whl} + case w.Notebook != nil: + libNotebookConverted, err := notebookLibraryFromWire(w.Notebook) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineLibrary.Lib.Notebook", err) + } + libSelection = &PipelineLibrary_Lib_Notebook{Notebook: *libNotebookConverted} + case w.File != nil: + libFileConverted, err := notebookLibraryFromWire(w.File) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineLibrary.Lib.File", err) + } + libSelection = &PipelineLibrary_Lib_File{File: *libFileConverted} + case w.Glob != nil: + libGlobConverted, err := pathPatternFromWire(w.Glob) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineLibrary.Lib.Glob", err) + } + libSelection = &PipelineLibrary_Lib_Glob{Glob: *libGlobConverted} + } + return &PipelineLibrary{ + Lib: libSelection, + }, nil +} + +type pipelineSpecWire struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Storage *string `json:"storage,omitempty"` + Configuration map[string]string `json:"configuration,omitempty"` + Clusters []pipelineClusterWire `json:"clusters,omitempty"` + Libraries []pipelineLibraryWire `json:"libraries,omitempty"` + IngestionDefinition *ingestionPipelineDefinitionWire `json:"ingestion_definition,omitempty"` + GatewayDefinition *ingestionGatewayPipelineDefinitionWire `json:"gateway_definition,omitempty"` + Trigger *pipelineTriggerWire `json:"trigger,omitempty"` + Target *string `json:"target,omitempty"` + Schema *string `json:"schema,omitempty"` + Filters *filtersWire `json:"filters,omitempty"` + Continuous *bool `json:"continuous,omitempty"` + Development *bool `json:"development,omitempty"` + Photon *bool `json:"photon,omitempty"` + Edition *string `json:"edition,omitempty"` + Channel *string `json:"channel,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Notifications []notificationsWire `json:"notifications,omitempty"` + Serverless *bool `json:"serverless,omitempty"` + Deployment *pipelineDeploymentWire `json:"deployment,omitempty"` + RestartWindow *restartWindowWire `json:"restart_window,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + Tags map[string]string `json:"tags,omitempty"` + EventLog *eventLogSpecWire `json:"event_log,omitempty"` + RootPath *string `json:"root_path,omitempty"` + Environment *pipelinesEnvironmentWire `json:"environment,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + ServerlessComputeId *string `json:"serverless_compute_id,omitempty"` +} + +func pipelineSpecFromWire(w *pipelineSpecWire) (*PipelineSpec, error) { + if w == nil { + return nil, nil + } + clustersPublicValue, err := convertSlice(w.Clusters, pipelineClusterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.Clusters", err) + } + librariesPublicValue, err := convertSlice(w.Libraries, pipelineLibraryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.Libraries", err) + } + ingestionDefinitionPublicValue, err := ingestionPipelineDefinitionFromWire(w.IngestionDefinition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.IngestionDefinition", err) + } + gatewayDefinitionPublicValue, err := ingestionGatewayPipelineDefinitionFromWire(w.GatewayDefinition) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.GatewayDefinition", err) + } + triggerPublicValue, err := pipelineTriggerFromWire(w.Trigger) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.Trigger", err) + } + filtersPublicValue, err := filtersFromWire(w.Filters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.Filters", err) + } + notificationsPublicValue, err := convertSlice(w.Notifications, notificationsFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.Notifications", err) + } + deploymentPublicValue, err := pipelineDeploymentFromWire(w.Deployment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.Deployment", err) + } + restartWindowPublicValue, err := restartWindowFromWire(w.RestartWindow) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.RestartWindow", err) + } + eventLogPublicValue, err := eventLogSpecFromWire(w.EventLog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.EventLog", err) + } + environmentPublicValue, err := pipelinesEnvironmentFromWire(w.Environment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineSpec.Environment", err) + } + return &PipelineSpec{ + Id: w.Id, + Name: w.Name, + Storage: w.Storage, + Configuration: w.Configuration, + Clusters: clustersPublicValue, + Libraries: librariesPublicValue, + IngestionDefinition: ingestionDefinitionPublicValue, + GatewayDefinition: gatewayDefinitionPublicValue, + Trigger: triggerPublicValue, + Target: w.Target, + Schema: w.Schema, + Filters: filtersPublicValue, + Continuous: w.Continuous, + Development: w.Development, + Photon: w.Photon, + Edition: w.Edition, + Channel: w.Channel, + Catalog: w.Catalog, + Notifications: notificationsPublicValue, + Serverless: w.Serverless, + Deployment: deploymentPublicValue, + RestartWindow: restartWindowPublicValue, + BudgetPolicyId: w.BudgetPolicyId, + Tags: w.Tags, + EventLog: eventLogPublicValue, + RootPath: w.RootPath, + Environment: environmentPublicValue, + UsagePolicyId: w.UsagePolicyId, + ServerlessComputeId: w.ServerlessComputeId, + }, nil +} + +type pipelineStateInfoWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + State PipelineState_PipelineState `json:"state,omitempty"` + ClusterId *string `json:"cluster_id,omitempty"` + Name *string `json:"name,omitempty"` + LatestUpdates []updateStateInfoWire `json:"latest_updates,omitempty"` + CreatorUserName *string `json:"creator_user_name,omitempty"` + RunAsUserName *string `json:"run_as_user_name,omitempty"` + Health PipelineHealthStatus `json:"health,omitempty"` +} + +func pipelineStateInfoFromWire(w *pipelineStateInfoWire) (*PipelineStateInfo, error) { + if w == nil { + return nil, nil + } + latestUpdatesPublicValue, err := convertSlice(w.LatestUpdates, updateStateInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineStateInfo.LatestUpdates", err) + } + return &PipelineStateInfo{ + PipelineId: w.PipelineId, + State: w.State, + ClusterId: w.ClusterId, + Name: w.Name, + LatestUpdates: latestUpdatesPublicValue, + CreatorUserName: w.CreatorUserName, + RunAsUserName: w.RunAsUserName, + Health: w.Health, + }, nil +} + +type pipelineTriggerWire struct { + Manual *manualTriggerWire `json:"manual,omitempty"` + Cron *cronTriggerWire `json:"cron,omitempty"` +} + +func pipelineTriggerToWire(v *PipelineTrigger) (*pipelineTriggerWire, error) { + if v == nil { + return nil, nil + } + var triggerManualWire *manualTriggerWire + var triggerCronWire *cronTriggerWire + switch value := v.Trigger.(type) { + case nil: + case *PipelineTrigger_Trigger_Manual: + if value != nil { + triggerManualConverted, err := manualTriggerToWire(&value.Manual) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineTrigger.Trigger.Manual", err) + } + triggerManualWire = triggerManualConverted + } + case *PipelineTrigger_Trigger_Cron: + if value != nil { + triggerCronConverted, err := cronTriggerToWire(&value.Cron) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineTrigger.Trigger.Cron", err) + } + triggerCronWire = triggerCronConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "PipelineTrigger.Trigger", value) + } + return &pipelineTriggerWire{ + Manual: triggerManualWire, + Cron: triggerCronWire, + }, nil +} + +func pipelineTriggerFromWire(w *pipelineTriggerWire) (*PipelineTrigger, error) { + if w == nil { + return nil, nil + } + triggerMembers := 0 + if w.Manual != nil { + triggerMembers++ + } + if w.Cron != nil { + triggerMembers++ + } + if triggerMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PipelineTrigger.Trigger") + } + var triggerSelection isPipelineTrigger_Trigger + switch { + case w.Manual != nil: + triggerManualConverted, err := manualTriggerFromWire(w.Manual) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineTrigger.Trigger.Manual", err) + } + triggerSelection = &PipelineTrigger_Trigger_Manual{Manual: *triggerManualConverted} + case w.Cron != nil: + triggerCronConverted, err := cronTriggerFromWire(w.Cron) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelineTrigger.Trigger.Cron", err) + } + triggerSelection = &PipelineTrigger_Trigger_Cron{Cron: *triggerCronConverted} + } + return &PipelineTrigger{ + Trigger: triggerSelection, + }, nil +} + +type pipelinesAutoScaleWire struct { + MinWorkers *int `json:"min_workers,omitempty"` + MaxWorkers *int `json:"max_workers,omitempty"` + Mode *string `json:"mode,omitempty"` +} + +func pipelinesAutoScaleToWire(v *PipelinesAutoScale) (*pipelinesAutoScaleWire, error) { + if v == nil { + return nil, nil + } + return &pipelinesAutoScaleWire{ + MinWorkers: v.MinWorkers, + MaxWorkers: v.MaxWorkers, + Mode: v.Mode, + }, nil +} + +func pipelinesAutoScaleFromWire(w *pipelinesAutoScaleWire) (*PipelinesAutoScale, error) { + if w == nil { + return nil, nil + } + return &PipelinesAutoScale{ + MinWorkers: w.MinWorkers, + MaxWorkers: w.MaxWorkers, + Mode: w.Mode, + }, nil +} + +type pipelinesAwsAttributesWire struct { + FirstOnDemand *int `json:"first_on_demand,omitempty"` + Availability PipelinesAwsAvailability `json:"availability,omitempty"` + ZoneId *string `json:"zone_id,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + SpotBidPricePercent *int `json:"spot_bid_price_percent,omitempty"` + EbsVolumeType PipelinesEbsVolumeType `json:"ebs_volume_type,omitempty"` + EbsVolumeCount *int `json:"ebs_volume_count,omitempty"` + EbsVolumeSize *int `json:"ebs_volume_size,omitempty"` + EbsVolumeIops *int `json:"ebs_volume_iops,omitempty"` + EbsVolumeThroughput *int `json:"ebs_volume_throughput,omitempty"` +} + +func pipelinesAwsAttributesToWire(v *PipelinesAwsAttributes) (*pipelinesAwsAttributesWire, error) { + if v == nil { + return nil, nil + } + return &pipelinesAwsAttributesWire{ + FirstOnDemand: v.FirstOnDemand, + Availability: v.Availability, + ZoneId: v.ZoneId, + InstanceProfileArn: v.InstanceProfileArn, + SpotBidPricePercent: v.SpotBidPricePercent, + EbsVolumeType: v.EbsVolumeType, + EbsVolumeCount: v.EbsVolumeCount, + EbsVolumeSize: v.EbsVolumeSize, + EbsVolumeIops: v.EbsVolumeIops, + EbsVolumeThroughput: v.EbsVolumeThroughput, + }, nil +} + +func pipelinesAwsAttributesFromWire(w *pipelinesAwsAttributesWire) (*PipelinesAwsAttributes, error) { + if w == nil { + return nil, nil + } + return &PipelinesAwsAttributes{ + FirstOnDemand: w.FirstOnDemand, + Availability: w.Availability, + ZoneId: w.ZoneId, + InstanceProfileArn: w.InstanceProfileArn, + SpotBidPricePercent: w.SpotBidPricePercent, + EbsVolumeType: w.EbsVolumeType, + EbsVolumeCount: w.EbsVolumeCount, + EbsVolumeSize: w.EbsVolumeSize, + EbsVolumeIops: w.EbsVolumeIops, + EbsVolumeThroughput: w.EbsVolumeThroughput, + }, nil +} + +type pipelinesAzureAttributesWire struct { + FirstOnDemand *int `json:"first_on_demand,omitempty"` + Availability PipelinesAzureAvailability `json:"availability,omitempty"` + SpotBidMaxPrice *float64 `json:"spot_bid_max_price,omitempty"` +} + +func pipelinesAzureAttributesToWire(v *PipelinesAzureAttributes) (*pipelinesAzureAttributesWire, error) { + if v == nil { + return nil, nil + } + return &pipelinesAzureAttributesWire{ + FirstOnDemand: v.FirstOnDemand, + Availability: v.Availability, + SpotBidMaxPrice: v.SpotBidMaxPrice, + }, nil +} + +func pipelinesAzureAttributesFromWire(w *pipelinesAzureAttributesWire) (*PipelinesAzureAttributes, error) { + if w == nil { + return nil, nil + } + return &PipelinesAzureAttributes{ + FirstOnDemand: w.FirstOnDemand, + Availability: w.Availability, + SpotBidMaxPrice: w.SpotBidMaxPrice, + }, nil +} + +type pipelinesClusterLogConfWire struct { + Dbfs *pipelinesDbfsStorageInfoWire `json:"dbfs,omitempty"` +} + +func pipelinesClusterLogConfToWire(v *PipelinesClusterLogConf) (*pipelinesClusterLogConfWire, error) { + if v == nil { + return nil, nil + } + var storageInfoDbfsWire *pipelinesDbfsStorageInfoWire + switch value := v.StorageInfo.(type) { + case nil: + case *PipelinesClusterLogConf_StorageInfo_Dbfs: + if value != nil { + storageInfoDbfsConverted, err := pipelinesDbfsStorageInfoToWire(&value.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelinesClusterLogConf.StorageInfo.Dbfs", err) + } + storageInfoDbfsWire = storageInfoDbfsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "PipelinesClusterLogConf.StorageInfo", value) + } + return &pipelinesClusterLogConfWire{ + Dbfs: storageInfoDbfsWire, + }, nil +} + +func pipelinesClusterLogConfFromWire(w *pipelinesClusterLogConfWire) (*PipelinesClusterLogConf, error) { + if w == nil { + return nil, nil + } + storageInfoMembers := 0 + if w.Dbfs != nil { + storageInfoMembers++ + } + if storageInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PipelinesClusterLogConf.StorageInfo") + } + var storageInfoSelection isPipelinesClusterLogConf_StorageInfo + switch { + case w.Dbfs != nil: + storageInfoDbfsConverted, err := pipelinesDbfsStorageInfoFromWire(w.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelinesClusterLogConf.StorageInfo.Dbfs", err) + } + storageInfoSelection = &PipelinesClusterLogConf_StorageInfo_Dbfs{Dbfs: *storageInfoDbfsConverted} + } + return &PipelinesClusterLogConf{ + StorageInfo: storageInfoSelection, + }, nil +} + +type pipelinesDbfsStorageInfoWire struct { + Destination *string `json:"destination,omitempty"` +} + +func pipelinesDbfsStorageInfoToWire(v *PipelinesDbfsStorageInfo) (*pipelinesDbfsStorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &pipelinesDbfsStorageInfoWire{ + Destination: v.Destination, + }, nil +} + +func pipelinesDbfsStorageInfoFromWire(w *pipelinesDbfsStorageInfoWire) (*PipelinesDbfsStorageInfo, error) { + if w == nil { + return nil, nil + } + return &PipelinesDbfsStorageInfo{ + Destination: w.Destination, + }, nil +} + +type pipelinesEnvironmentWire struct { + Dependencies []string `json:"dependencies,omitempty"` + EnvironmentVersion *string `json:"environment_version,omitempty"` +} + +func pipelinesEnvironmentToWire(v *PipelinesEnvironment) (*pipelinesEnvironmentWire, error) { + if v == nil { + return nil, nil + } + return &pipelinesEnvironmentWire{ + Dependencies: v.Dependencies, + EnvironmentVersion: v.EnvironmentVersion, + }, nil +} + +func pipelinesEnvironmentFromWire(w *pipelinesEnvironmentWire) (*PipelinesEnvironment, error) { + if w == nil { + return nil, nil + } + return &PipelinesEnvironment{ + Dependencies: w.Dependencies, + EnvironmentVersion: w.EnvironmentVersion, + }, nil +} + +type pipelinesGcpAttributesWire struct { + GoogleServiceAccount *string `json:"google_service_account,omitempty"` + BootDiskSize *int `json:"boot_disk_size,omitempty"` + Availability PipelinesGcpAvailability `json:"availability,omitempty"` + ZoneId *string `json:"zone_id,omitempty"` + LocalSsdCount *int `json:"local_ssd_count,omitempty"` +} + +func pipelinesGcpAttributesToWire(v *PipelinesGcpAttributes) (*pipelinesGcpAttributesWire, error) { + if v == nil { + return nil, nil + } + return &pipelinesGcpAttributesWire{ + GoogleServiceAccount: v.GoogleServiceAccount, + BootDiskSize: v.BootDiskSize, + Availability: v.Availability, + ZoneId: v.ZoneId, + LocalSsdCount: v.LocalSsdCount, + }, nil +} + +func pipelinesGcpAttributesFromWire(w *pipelinesGcpAttributesWire) (*PipelinesGcpAttributes, error) { + if w == nil { + return nil, nil + } + return &PipelinesGcpAttributes{ + GoogleServiceAccount: w.GoogleServiceAccount, + BootDiskSize: w.BootDiskSize, + Availability: w.Availability, + ZoneId: w.ZoneId, + LocalSsdCount: w.LocalSsdCount, + }, nil +} + +type pipelinesInitScriptInfoWire struct { + Dbfs *pipelinesDbfsStorageInfoWire `json:"dbfs,omitempty"` + S3 *pipelinesS3StorageInfoWire `json:"s3,omitempty"` +} + +func pipelinesInitScriptInfoToWire(v *PipelinesInitScriptInfo) (*pipelinesInitScriptInfoWire, error) { + if v == nil { + return nil, nil + } + var storageInfoDbfsWire *pipelinesDbfsStorageInfoWire + var storageInfoS3Wire *pipelinesS3StorageInfoWire + switch value := v.StorageInfo.(type) { + case nil: + case *PipelinesInitScriptInfo_StorageInfo_Dbfs: + if value != nil { + storageInfoDbfsConverted, err := pipelinesDbfsStorageInfoToWire(&value.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelinesInitScriptInfo.StorageInfo.Dbfs", err) + } + storageInfoDbfsWire = storageInfoDbfsConverted + } + case *PipelinesInitScriptInfo_StorageInfo_S3: + if value != nil { + storageInfoS3Converted, err := pipelinesS3StorageInfoToWire(&value.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelinesInitScriptInfo.StorageInfo.S3", err) + } + storageInfoS3Wire = storageInfoS3Converted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "PipelinesInitScriptInfo.StorageInfo", value) + } + return &pipelinesInitScriptInfoWire{ + Dbfs: storageInfoDbfsWire, + S3: storageInfoS3Wire, + }, nil +} + +func pipelinesInitScriptInfoFromWire(w *pipelinesInitScriptInfoWire) (*PipelinesInitScriptInfo, error) { + if w == nil { + return nil, nil + } + storageInfoMembers := 0 + if w.Dbfs != nil { + storageInfoMembers++ + } + if w.S3 != nil { + storageInfoMembers++ + } + if storageInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PipelinesInitScriptInfo.StorageInfo") + } + var storageInfoSelection isPipelinesInitScriptInfo_StorageInfo + switch { + case w.Dbfs != nil: + storageInfoDbfsConverted, err := pipelinesDbfsStorageInfoFromWire(w.Dbfs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelinesInitScriptInfo.StorageInfo.Dbfs", err) + } + storageInfoSelection = &PipelinesInitScriptInfo_StorageInfo_Dbfs{Dbfs: *storageInfoDbfsConverted} + case w.S3 != nil: + storageInfoS3Converted, err := pipelinesS3StorageInfoFromWire(w.S3) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PipelinesInitScriptInfo.StorageInfo.S3", err) + } + storageInfoSelection = &PipelinesInitScriptInfo_StorageInfo_S3{S3: *storageInfoS3Converted} + } + return &PipelinesInitScriptInfo{ + StorageInfo: storageInfoSelection, + }, nil +} + +type pipelinesJobRunAsWire struct { + UserName *string `json:"user_name,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` +} + +func pipelinesJobRunAsToWire(v *PipelinesJobRunAs) (*pipelinesJobRunAsWire, error) { + if v == nil { + return nil, nil + } + var identityUserNameWire *string + var identityServicePrincipalNameWire *string + switch value := v.Identity.(type) { + case nil: + case *PipelinesJobRunAs_Identity_UserName: + if value != nil { + identityUserNameWire = new(value.UserName) + } + case *PipelinesJobRunAs_Identity_ServicePrincipalName: + if value != nil { + identityServicePrincipalNameWire = new(value.ServicePrincipalName) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "PipelinesJobRunAs.Identity", value) + } + return &pipelinesJobRunAsWire{ + UserName: identityUserNameWire, + ServicePrincipalName: identityServicePrincipalNameWire, + }, nil +} + +func pipelinesJobRunAsFromWire(w *pipelinesJobRunAsWire) (*PipelinesJobRunAs, error) { + if w == nil { + return nil, nil + } + identityMembers := 0 + if w.UserName != nil { + identityMembers++ + } + if w.ServicePrincipalName != nil { + identityMembers++ + } + if identityMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PipelinesJobRunAs.Identity") + } + var identitySelection isPipelinesJobRunAs_Identity + switch { + case w.UserName != nil: + identitySelection = &PipelinesJobRunAs_Identity_UserName{UserName: *w.UserName} + case w.ServicePrincipalName != nil: + identitySelection = &PipelinesJobRunAs_Identity_ServicePrincipalName{ServicePrincipalName: *w.ServicePrincipalName} + } + return &PipelinesJobRunAs{ + Identity: identitySelection, + }, nil +} + +type pipelinesMavenLibraryWire struct { + Coordinates *string `json:"coordinates,omitempty"` + Repo *string `json:"repo,omitempty"` + Exclusions []string `json:"exclusions,omitempty"` +} + +func pipelinesMavenLibraryToWire(v *PipelinesMavenLibrary) (*pipelinesMavenLibraryWire, error) { + if v == nil { + return nil, nil + } + return &pipelinesMavenLibraryWire{ + Coordinates: v.Coordinates, + Repo: v.Repo, + Exclusions: v.Exclusions, + }, nil +} + +func pipelinesMavenLibraryFromWire(w *pipelinesMavenLibraryWire) (*PipelinesMavenLibrary, error) { + if w == nil { + return nil, nil + } + return &PipelinesMavenLibrary{ + Coordinates: w.Coordinates, + Repo: w.Repo, + Exclusions: w.Exclusions, + }, nil +} + +type pipelinesS3StorageInfoWire struct { + Destination *string `json:"destination,omitempty"` + Region *string `json:"region,omitempty"` + Endpoint *string `json:"endpoint,omitempty"` + EnableEncryption *bool `json:"enable_encryption,omitempty"` + EncryptionType *string `json:"encryption_type,omitempty"` + KmsKey *string `json:"kms_key,omitempty"` + CannedAcl *string `json:"canned_acl,omitempty"` +} + +func pipelinesS3StorageInfoToWire(v *PipelinesS3StorageInfo) (*pipelinesS3StorageInfoWire, error) { + if v == nil { + return nil, nil + } + return &pipelinesS3StorageInfoWire{ + Destination: v.Destination, + Region: v.Region, + Endpoint: v.Endpoint, + EnableEncryption: v.EnableEncryption, + EncryptionType: v.EncryptionType, + KmsKey: v.KmsKey, + CannedAcl: v.CannedAcl, + }, nil +} + +func pipelinesS3StorageInfoFromWire(w *pipelinesS3StorageInfoWire) (*PipelinesS3StorageInfo, error) { + if w == nil { + return nil, nil + } + return &PipelinesS3StorageInfo{ + Destination: w.Destination, + Region: w.Region, + Endpoint: w.Endpoint, + EnableEncryption: w.EnableEncryption, + EncryptionType: w.EncryptionType, + KmsKey: w.KmsKey, + CannedAcl: w.CannedAcl, + }, nil +} + +type postgresCatalogConfigWire struct { + SlotConfig *postgresSlotConfigWire `json:"slot_config,omitempty"` +} + +func postgresCatalogConfigToWire(v *PostgresCatalogConfig) (*postgresCatalogConfigWire, error) { + if v == nil { + return nil, nil + } + slotConfigWireValue, err := postgresSlotConfigToWire(v.SlotConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PostgresCatalogConfig.SlotConfig", err) + } + return &postgresCatalogConfigWire{ + SlotConfig: slotConfigWireValue, + }, nil +} + +func postgresCatalogConfigFromWire(w *postgresCatalogConfigWire) (*PostgresCatalogConfig, error) { + if w == nil { + return nil, nil + } + slotConfigPublicValue, err := postgresSlotConfigFromWire(w.SlotConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PostgresCatalogConfig.SlotConfig", err) + } + return &PostgresCatalogConfig{ + SlotConfig: slotConfigPublicValue, + }, nil +} + +type postgresSlotConfigWire struct { + SlotName *string `json:"slot_name,omitempty"` + PublicationName *string `json:"publication_name,omitempty"` +} + +func postgresSlotConfigToWire(v *PostgresSlotConfig) (*postgresSlotConfigWire, error) { + if v == nil { + return nil, nil + } + return &postgresSlotConfigWire{ + SlotName: v.SlotName, + PublicationName: v.PublicationName, + }, nil +} + +func postgresSlotConfigFromWire(w *postgresSlotConfigWire) (*PostgresSlotConfig, error) { + if w == nil { + return nil, nil + } + return &PostgresSlotConfig{ + SlotName: w.SlotName, + PublicationName: w.PublicationName, + }, nil +} + +type redditAdsOptionsWire struct { + SyncStartDate *string `json:"sync_start_date,omitempty"` + LookbackWindowDays *int `json:"lookback_window_days,omitempty"` + CustomReportOptions *redditAdsOptions_RedditAdsCustomReportOptionsWire `json:"custom_report_options,omitempty"` +} + +func redditAdsOptionsToWire(v *RedditAdsOptions) (*redditAdsOptionsWire, error) { + if v == nil { + return nil, nil + } + customReportOptionsWireValue, err := redditAdsOptions_RedditAdsCustomReportOptionsToWire(v.CustomReportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RedditAdsOptions.CustomReportOptions", err) + } + return &redditAdsOptionsWire{ + SyncStartDate: v.SyncStartDate, + LookbackWindowDays: v.LookbackWindowDays, + CustomReportOptions: customReportOptionsWireValue, + }, nil +} + +func redditAdsOptionsFromWire(w *redditAdsOptionsWire) (*RedditAdsOptions, error) { + if w == nil { + return nil, nil + } + customReportOptionsPublicValue, err := redditAdsOptions_RedditAdsCustomReportOptionsFromWire(w.CustomReportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RedditAdsOptions.CustomReportOptions", err) + } + return &RedditAdsOptions{ + SyncStartDate: w.SyncStartDate, + LookbackWindowDays: w.LookbackWindowDays, + CustomReportOptions: customReportOptionsPublicValue, + }, nil +} + +type redditAdsOptions_RedditAdsCustomReportOptionsWire struct { + Fields []string `json:"fields,omitempty"` + Breakdowns []string `json:"breakdowns,omitempty"` +} + +func redditAdsOptions_RedditAdsCustomReportOptionsToWire(v *RedditAdsOptions_RedditAdsCustomReportOptions) (*redditAdsOptions_RedditAdsCustomReportOptionsWire, error) { + if v == nil { + return nil, nil + } + return &redditAdsOptions_RedditAdsCustomReportOptionsWire{ + Fields: v.Fields, + Breakdowns: v.Breakdowns, + }, nil +} + +func redditAdsOptions_RedditAdsCustomReportOptionsFromWire(w *redditAdsOptions_RedditAdsCustomReportOptionsWire) (*RedditAdsOptions_RedditAdsCustomReportOptions, error) { + if w == nil { + return nil, nil + } + return &RedditAdsOptions_RedditAdsCustomReportOptions{ + Fields: w.Fields, + Breakdowns: w.Breakdowns, + }, nil +} + +type replaceWhereOverrideWire struct { + FlowName *string `json:"flow_name,omitempty"` + PredicateOverride *string `json:"predicate_override,omitempty"` +} + +func replaceWhereOverrideToWire(v *ReplaceWhereOverride) (*replaceWhereOverrideWire, error) { + if v == nil { + return nil, nil + } + return &replaceWhereOverrideWire{ + FlowName: v.FlowName, + PredicateOverride: v.PredicateOverride, + }, nil +} + +type restartWindowWire struct { + StartHour *int `json:"start_hour,omitempty"` + DaysOfWeek []DayOfWeek `json:"days_of_week,omitempty"` + TimeZoneId *string `json:"time_zone_id,omitempty"` +} + +func restartWindowToWire(v *RestartWindow) (*restartWindowWire, error) { + if v == nil { + return nil, nil + } + return &restartWindowWire{ + StartHour: v.StartHour, + DaysOfWeek: v.DaysOfWeek, + TimeZoneId: v.TimeZoneId, + }, nil +} + +func restartWindowFromWire(w *restartWindowWire) (*RestartWindow, error) { + if w == nil { + return nil, nil + } + return &RestartWindow{ + StartHour: w.StartHour, + DaysOfWeek: w.DaysOfWeek, + TimeZoneId: w.TimeZoneId, + }, nil +} + +type rewindDatasetSpecWire struct { + Identifier *string `json:"identifier,omitempty"` + Cascade *bool `json:"cascade,omitempty"` + ResetCheckpoints *bool `json:"reset_checkpoints,omitempty"` +} + +func rewindDatasetSpecToWire(v *RewindDatasetSpec) (*rewindDatasetSpecWire, error) { + if v == nil { + return nil, nil + } + return &rewindDatasetSpecWire{ + Identifier: v.Identifier, + Cascade: v.Cascade, + ResetCheckpoints: v.ResetCheckpoints, + }, nil +} + +type rewindSpecWire struct { + RewindTimestamp *string `json:"rewind_timestamp,omitempty"` + DryRun *bool `json:"dry_run,omitempty"` + Datasets []rewindDatasetSpecWire `json:"datasets,omitempty"` +} + +func rewindSpecToWire(v *RewindSpec) (*rewindSpecWire, error) { + if v == nil { + return nil, nil + } + datasetsWireValue, err := convertSlice(v.Datasets, rewindDatasetSpecToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RewindSpec.Datasets", err) + } + return &rewindSpecWire{ + RewindTimestamp: v.RewindTimestamp, + DryRun: v.DryRun, + Datasets: datasetsWireValue, + }, nil +} + +type sequencingWire struct { + DataPlaneId *dataPlaneIdWire `json:"data_plane_id,omitempty"` + ControlPlaneSeqNo *int64 `json:"control_plane_seq_no,omitempty"` +} + +func sequencingFromWire(w *sequencingWire) (*Sequencing, error) { + if w == nil { + return nil, nil + } + dataPlaneIdPublicValue, err := dataPlaneIdFromWire(w.DataPlaneId) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Sequencing.DataPlaneId", err) + } + return &Sequencing{ + DataPlaneId: dataPlaneIdPublicValue, + ControlPlaneSeqNo: w.ControlPlaneSeqNo, + }, nil +} + +type serializedExceptionWire struct { + ClassName *string `json:"class_name,omitempty"` + Message *string `json:"message,omitempty"` + Stack []stackFrameWire `json:"stack,omitempty"` +} + +func serializedExceptionFromWire(w *serializedExceptionWire) (*SerializedException, error) { + if w == nil { + return nil, nil + } + stackPublicValue, err := convertSlice(w.Stack, stackFrameFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SerializedException.Stack", err) + } + return &SerializedException{ + ClassName: w.ClassName, + Message: w.Message, + Stack: stackPublicValue, + }, nil +} + +type sharepointOptionsWire struct { + Url *string `json:"url,omitempty"` + EntityType SharepointOptions_SharepointEntityType `json:"entity_type,omitempty"` + FileIngestionOptions *fileIngestionOptionsWire `json:"file_ingestion_options,omitempty"` +} + +func sharepointOptionsToWire(v *SharepointOptions) (*sharepointOptionsWire, error) { + if v == nil { + return nil, nil + } + fileIngestionOptionsWireValue, err := fileIngestionOptionsToWire(v.FileIngestionOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SharepointOptions.FileIngestionOptions", err) + } + return &sharepointOptionsWire{ + Url: v.Url, + EntityType: v.EntityType, + FileIngestionOptions: fileIngestionOptionsWireValue, + }, nil +} + +func sharepointOptionsFromWire(w *sharepointOptionsWire) (*SharepointOptions, error) { + if w == nil { + return nil, nil + } + fileIngestionOptionsPublicValue, err := fileIngestionOptionsFromWire(w.FileIngestionOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SharepointOptions.FileIngestionOptions", err) + } + return &SharepointOptions{ + Url: w.Url, + EntityType: w.EntityType, + FileIngestionOptions: fileIngestionOptionsPublicValue, + }, nil +} + +type smartsheetOptionsWire struct { + EnforceSchema *bool `json:"enforce_schema,omitempty"` +} + +func smartsheetOptionsToWire(v *SmartsheetOptions) (*smartsheetOptionsWire, error) { + if v == nil { + return nil, nil + } + return &smartsheetOptionsWire{ + EnforceSchema: v.EnforceSchema, + }, nil +} + +func smartsheetOptionsFromWire(w *smartsheetOptionsWire) (*SmartsheetOptions, error) { + if w == nil { + return nil, nil + } + return &SmartsheetOptions{ + EnforceSchema: w.EnforceSchema, + }, nil +} + +type sourceCatalogConfigWire struct { + SourceCatalog *string `json:"source_catalog,omitempty"` + Postgres *postgresCatalogConfigWire `json:"postgres,omitempty"` +} + +func sourceCatalogConfigToWire(v *SourceCatalogConfig) (*sourceCatalogConfigWire, error) { + if v == nil { + return nil, nil + } + var optionsPostgresWire *postgresCatalogConfigWire + switch value := v.Options.(type) { + case nil: + case *SourceCatalogConfig_Options_Postgres: + if value != nil { + optionsPostgresConverted, err := postgresCatalogConfigToWire(&value.Postgres) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SourceCatalogConfig.Options.Postgres", err) + } + optionsPostgresWire = optionsPostgresConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SourceCatalogConfig.Options", value) + } + return &sourceCatalogConfigWire{ + SourceCatalog: v.SourceCatalog, + Postgres: optionsPostgresWire, + }, nil +} + +func sourceCatalogConfigFromWire(w *sourceCatalogConfigWire) (*SourceCatalogConfig, error) { + if w == nil { + return nil, nil + } + optionsMembers := 0 + if w.Postgres != nil { + optionsMembers++ + } + if optionsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SourceCatalogConfig.Options") + } + var optionsSelection isSourceCatalogConfig_Options + switch { + case w.Postgres != nil: + optionsPostgresConverted, err := postgresCatalogConfigFromWire(w.Postgres) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SourceCatalogConfig.Options.Postgres", err) + } + optionsSelection = &SourceCatalogConfig_Options_Postgres{Postgres: *optionsPostgresConverted} + } + return &SourceCatalogConfig{ + SourceCatalog: w.SourceCatalog, + Options: optionsSelection, + }, nil +} + +type sourceConfigWire struct { + Catalog *sourceCatalogConfigWire `json:"catalog,omitempty"` + GoogleAdsConfig *googleAdsConfigWire `json:"google_ads_config,omitempty"` + ApiSourceConnectorConfig *apiSourceConnectorConfigWire `json:"api_source_connector_config,omitempty"` +} + +func sourceConfigToWire(v *SourceConfig) (*sourceConfigWire, error) { + if v == nil { + return nil, nil + } + catalogWireValue, err := sourceCatalogConfigToWire(v.Catalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SourceConfig.Catalog", err) + } + var connectorConfigGoogleAdsConfigWire *googleAdsConfigWire + var connectorConfigApiSourceConnectorConfigWire *apiSourceConnectorConfigWire + switch value := v.ConnectorConfig.(type) { + case nil: + case *SourceConfig_ConnectorConfig_GoogleAdsConfig: + if value != nil { + connectorConfigGoogleAdsConfigConverted, err := googleAdsConfigToWire(&value.GoogleAdsConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SourceConfig.ConnectorConfig.GoogleAdsConfig", err) + } + connectorConfigGoogleAdsConfigWire = connectorConfigGoogleAdsConfigConverted + } + case *SourceConfig_ConnectorConfig_ApiSourceConnectorConfig: + if value != nil { + connectorConfigApiSourceConnectorConfigConverted, err := apiSourceConnectorConfigToWire(&value.ApiSourceConnectorConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SourceConfig.ConnectorConfig.ApiSourceConnectorConfig", err) + } + connectorConfigApiSourceConnectorConfigWire = connectorConfigApiSourceConnectorConfigConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SourceConfig.ConnectorConfig", value) + } + return &sourceConfigWire{ + Catalog: catalogWireValue, + GoogleAdsConfig: connectorConfigGoogleAdsConfigWire, + ApiSourceConnectorConfig: connectorConfigApiSourceConnectorConfigWire, + }, nil +} + +func sourceConfigFromWire(w *sourceConfigWire) (*SourceConfig, error) { + if w == nil { + return nil, nil + } + connectorConfigMembers := 0 + if w.GoogleAdsConfig != nil { + connectorConfigMembers++ + } + if w.ApiSourceConnectorConfig != nil { + connectorConfigMembers++ + } + if connectorConfigMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SourceConfig.ConnectorConfig") + } + catalogPublicValue, err := sourceCatalogConfigFromWire(w.Catalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SourceConfig.Catalog", err) + } + var connectorConfigSelection isSourceConfig_ConnectorConfig + switch { + case w.GoogleAdsConfig != nil: + connectorConfigGoogleAdsConfigConverted, err := googleAdsConfigFromWire(w.GoogleAdsConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SourceConfig.ConnectorConfig.GoogleAdsConfig", err) + } + connectorConfigSelection = &SourceConfig_ConnectorConfig_GoogleAdsConfig{GoogleAdsConfig: *connectorConfigGoogleAdsConfigConverted} + case w.ApiSourceConnectorConfig != nil: + connectorConfigApiSourceConnectorConfigConverted, err := apiSourceConnectorConfigFromWire(w.ApiSourceConnectorConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SourceConfig.ConnectorConfig.ApiSourceConnectorConfig", err) + } + connectorConfigSelection = &SourceConfig_ConnectorConfig_ApiSourceConnectorConfig{ApiSourceConnectorConfig: *connectorConfigApiSourceConnectorConfigConverted} + } + return &SourceConfig{ + Catalog: catalogPublicValue, + ConnectorConfig: connectorConfigSelection, + }, nil +} + +type stackFrameWire struct { + DeclaringClass *string `json:"declaring_class,omitempty"` + MethodName *string `json:"method_name,omitempty"` + FileName *string `json:"file_name,omitempty"` + LineNumber *int `json:"line_number,omitempty"` +} + +func stackFrameFromWire(w *stackFrameWire) (*StackFrame, error) { + if w == nil { + return nil, nil + } + return &StackFrame{ + DeclaringClass: w.DeclaringClass, + MethodName: w.MethodName, + FileName: w.FileName, + LineNumber: w.LineNumber, + }, nil +} + +type startUpdateRequestWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + FullRefresh *bool `json:"full_refresh,omitempty"` + Cause UpdateCause `json:"cause,omitempty"` + RefreshSelection []string `json:"refresh_selection,omitempty"` + FullRefreshSelection []string `json:"full_refresh_selection,omitempty"` + ResetCheckpointSelection []string `json:"reset_checkpoint_selection,omitempty"` + ValidateOnly *bool `json:"validate_only,omitempty"` + RewindSpec *rewindSpecWire `json:"rewind_spec,omitempty"` + Parameters map[string]string `json:"parameters,omitempty"` + ReplaceWhereOverrides []replaceWhereOverrideWire `json:"replace_where_overrides,omitempty"` +} + +func startUpdateRequestToWire(v *StartUpdateRequest) (*startUpdateRequestWire, error) { + if v == nil { + return nil, nil + } + rewindSpecWireValue, err := rewindSpecToWire(v.RewindSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StartUpdateRequest.RewindSpec", err) + } + replaceWhereOverridesWireValue, err := convertSlice(v.ReplaceWhereOverrides, replaceWhereOverrideToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StartUpdateRequest.ReplaceWhereOverrides", err) + } + return &startUpdateRequestWire{ + PipelineId: v.PipelineId, + FullRefresh: v.FullRefresh, + Cause: v.Cause, + RefreshSelection: v.RefreshSelection, + FullRefreshSelection: v.FullRefreshSelection, + ResetCheckpointSelection: v.ResetCheckpointSelection, + ValidateOnly: v.ValidateOnly, + RewindSpec: rewindSpecWireValue, + Parameters: v.Parameters, + ReplaceWhereOverrides: replaceWhereOverridesWireValue, + }, nil +} + +type startUpdateResponseWire struct { + UpdateId *string `json:"update_id,omitempty"` +} + +func startUpdateResponseFromWire(w *startUpdateResponseWire) (*StartUpdateResponse, error) { + if w == nil { + return nil, nil + } + return &StartUpdateResponse{ + UpdateId: w.UpdateId, + }, nil +} + +type stopPipelineRequestWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` +} + +func stopPipelineRequestToWire(v *StopPipelineRequest) (*stopPipelineRequestWire, error) { + if v == nil { + return nil, nil + } + return &stopPipelineRequestWire{ + PipelineId: v.PipelineId, + }, nil +} + +type tikTokAdsOptionsWire struct { + LookbackWindowDays *int `json:"lookback_window_days,omitempty"` + SyncStartDate *string `json:"sync_start_date,omitempty"` + Dimensions []string `json:"dimensions,omitempty"` + Metrics []string `json:"metrics,omitempty"` + ReportType TikTokAdsOptions_TikTokReportType `json:"report_type,omitempty"` + DataLevel TikTokAdsOptions_TikTokDataLevel `json:"data_level,omitempty"` + QueryLifetime *bool `json:"query_lifetime,omitempty"` + CustomReportOptions *tikTokAdsOptions_TikTokAdsCustomReportOptionsWire `json:"custom_report_options,omitempty"` +} + +func tikTokAdsOptionsToWire(v *TikTokAdsOptions) (*tikTokAdsOptionsWire, error) { + if v == nil { + return nil, nil + } + customReportOptionsWireValue, err := tikTokAdsOptions_TikTokAdsCustomReportOptionsToWire(v.CustomReportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TikTokAdsOptions.CustomReportOptions", err) + } + return &tikTokAdsOptionsWire{ + LookbackWindowDays: v.LookbackWindowDays, + SyncStartDate: v.SyncStartDate, + Dimensions: v.Dimensions, + Metrics: v.Metrics, + ReportType: v.ReportType, + DataLevel: v.DataLevel, + QueryLifetime: v.QueryLifetime, + CustomReportOptions: customReportOptionsWireValue, + }, nil +} + +func tikTokAdsOptionsFromWire(w *tikTokAdsOptionsWire) (*TikTokAdsOptions, error) { + if w == nil { + return nil, nil + } + customReportOptionsPublicValue, err := tikTokAdsOptions_TikTokAdsCustomReportOptionsFromWire(w.CustomReportOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TikTokAdsOptions.CustomReportOptions", err) + } + return &TikTokAdsOptions{ + LookbackWindowDays: w.LookbackWindowDays, + SyncStartDate: w.SyncStartDate, + Dimensions: w.Dimensions, + Metrics: w.Metrics, + ReportType: w.ReportType, + DataLevel: w.DataLevel, + QueryLifetime: w.QueryLifetime, + CustomReportOptions: customReportOptionsPublicValue, + }, nil +} + +type tikTokAdsOptions_TikTokAdsCustomReportOptionsWire struct { + Dimensions []string `json:"dimensions,omitempty"` + Metrics []string `json:"metrics,omitempty"` + ReportType TikTokAdsOptions_TikTokReportType `json:"report_type,omitempty"` + DataLevel TikTokAdsOptions_TikTokDataLevel `json:"data_level,omitempty"` + QueryLifetime *bool `json:"query_lifetime,omitempty"` +} + +func tikTokAdsOptions_TikTokAdsCustomReportOptionsToWire(v *TikTokAdsOptions_TikTokAdsCustomReportOptions) (*tikTokAdsOptions_TikTokAdsCustomReportOptionsWire, error) { + if v == nil { + return nil, nil + } + return &tikTokAdsOptions_TikTokAdsCustomReportOptionsWire{ + Dimensions: v.Dimensions, + Metrics: v.Metrics, + ReportType: v.ReportType, + DataLevel: v.DataLevel, + QueryLifetime: v.QueryLifetime, + }, nil +} + +func tikTokAdsOptions_TikTokAdsCustomReportOptionsFromWire(w *tikTokAdsOptions_TikTokAdsCustomReportOptionsWire) (*TikTokAdsOptions_TikTokAdsCustomReportOptions, error) { + if w == nil { + return nil, nil + } + return &TikTokAdsOptions_TikTokAdsCustomReportOptions{ + Dimensions: w.Dimensions, + Metrics: w.Metrics, + ReportType: w.ReportType, + DataLevel: w.DataLevel, + QueryLifetime: w.QueryLifetime, + }, nil +} + +type transformerWire struct { + Format Transformer_Format `json:"format,omitempty"` + JsonOptions *jsonTransformerOptionsWire `json:"json_options,omitempty"` + InputColumn *string `json:"input_column,omitempty"` + OutputColumn *string `json:"output_column,omitempty"` +} + +func transformerToWire(v *Transformer) (*transformerWire, error) { + if v == nil { + return nil, nil + } + var configJsonOptionsWire *jsonTransformerOptionsWire + switch value := v.Config.(type) { + case nil: + case *Transformer_Config_JsonOptions: + if value != nil { + configJsonOptionsConverted, err := jsonTransformerOptionsToWire(&value.JsonOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Transformer.Config.JsonOptions", err) + } + configJsonOptionsWire = configJsonOptionsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Transformer.Config", value) + } + return &transformerWire{ + Format: v.Format, + JsonOptions: configJsonOptionsWire, + InputColumn: v.InputColumn, + OutputColumn: v.OutputColumn, + }, nil +} + +func transformerFromWire(w *transformerWire) (*Transformer, error) { + if w == nil { + return nil, nil + } + configMembers := 0 + if w.JsonOptions != nil { + configMembers++ + } + if configMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Transformer.Config") + } + var configSelection isTransformer_Config + switch { + case w.JsonOptions != nil: + configJsonOptionsConverted, err := jsonTransformerOptionsFromWire(w.JsonOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Transformer.Config.JsonOptions", err) + } + configSelection = &Transformer_Config_JsonOptions{JsonOptions: *configJsonOptionsConverted} + } + return &Transformer{ + Format: w.Format, + InputColumn: w.InputColumn, + OutputColumn: w.OutputColumn, + Config: configSelection, + }, nil +} + +type truncationWire struct { + TruncatedFields []truncation_TruncationDetailWire `json:"truncated_fields,omitempty"` +} + +func truncationFromWire(w *truncationWire) (*Truncation, error) { + if w == nil { + return nil, nil + } + truncatedFieldsPublicValue, err := convertSlice(w.TruncatedFields, truncation_TruncationDetailFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Truncation.TruncatedFields", err) + } + return &Truncation{ + TruncatedFields: truncatedFieldsPublicValue, + }, nil +} + +type truncation_TruncationDetailWire struct { + FieldName *string `json:"field_name,omitempty"` +} + +func truncation_TruncationDetailFromWire(w *truncation_TruncationDetailWire) (*Truncation_TruncationDetail, error) { + if w == nil { + return nil, nil + } + return &Truncation_TruncationDetail{ + FieldName: w.FieldName, + }, nil +} + +type updateInfoWire struct { + PipelineId *string `json:"pipeline_id,omitempty"` + UpdateId *string `json:"update_id,omitempty"` + Config *pipelineSpecWire `json:"config,omitempty"` + Cause UpdateCause `json:"cause,omitempty"` + State UpdateState `json:"state,omitempty"` + ClusterId *string `json:"cluster_id,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + FullRefresh *bool `json:"full_refresh,omitempty"` + RefreshSelection []string `json:"refresh_selection,omitempty"` + FullRefreshSelection []string `json:"full_refresh_selection,omitempty"` + ValidateOnly *bool `json:"validate_only,omitempty"` + Mode UpdateMode `json:"mode,omitempty"` + Parameters map[string]string `json:"parameters,omitempty"` +} + +func updateInfoFromWire(w *updateInfoWire) (*UpdateInfo, error) { + if w == nil { + return nil, nil + } + configPublicValue, err := pipelineSpecFromWire(w.Config) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateInfo.Config", err) + } + return &UpdateInfo{ + PipelineId: w.PipelineId, + UpdateId: w.UpdateId, + Config: configPublicValue, + Cause: w.Cause, + State: w.State, + ClusterId: w.ClusterId, + CreationTime: w.CreationTime, + FullRefresh: w.FullRefresh, + RefreshSelection: w.RefreshSelection, + FullRefreshSelection: w.FullRefreshSelection, + ValidateOnly: w.ValidateOnly, + Mode: w.Mode, + Parameters: w.Parameters, + }, nil +} + +type updateStateInfoWire struct { + UpdateId *string `json:"update_id,omitempty"` + State UpdateState `json:"state,omitempty"` + CreationTime *string `json:"creation_time,omitempty"` +} + +func updateStateInfoFromWire(w *updateStateInfoWire) (*UpdateStateInfo, error) { + if w == nil { + return nil, nil + } + return &UpdateStateInfo{ + UpdateId: w.UpdateId, + State: w.State, + CreationTime: w.CreationTime, + }, nil +} + +type zendeskSupportOptionsWire struct { + StartDate *string `json:"start_date,omitempty"` +} + +func zendeskSupportOptionsToWire(v *ZendeskSupportOptions) (*zendeskSupportOptionsWire, error) { + if v == nil { + return nil, nil + } + return &zendeskSupportOptionsWire{ + StartDate: v.StartDate, + }, nil +} + +func zendeskSupportOptionsFromWire(w *zendeskSupportOptionsWire) (*ZendeskSupportOptions, error) { + if w == nil { + return nil, nil + } + return &ZendeskSupportOptions{ + StartDate: w.StartDate, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/policyfamilies/.package.json b/policyfamilies/.package.json new file mode 100644 index 0000000..99b7402 --- /dev/null +++ b/policyfamilies/.package.json @@ -0,0 +1,3 @@ +{ + "package": "policyfamilies" +} diff --git a/policyfamilies/CHANGELOG.md b/policyfamilies/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/policyfamilies/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/policyfamilies/README.md b/policyfamilies/README.md new file mode 100644 index 0000000..eccdc9f --- /dev/null +++ b/policyfamilies/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/policyfamilies + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/policyfamilies@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/policyfamilies/v2" + +client, err := policyfamilies.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/policyfamilies/go.mod b/policyfamilies/go.mod new file mode 100644 index 0000000..4cac7d2 --- /dev/null +++ b/policyfamilies/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/policyfamilies + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/policyfamilies/internal/version.go b/policyfamilies/internal/version.go new file mode 100644 index 0000000..af6b259 --- /dev/null +++ b/policyfamilies/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-policyfamilies" + +const Version = "0.0.1-dev.1" diff --git a/policyfamilies/v2/client.go b/policyfamilies/v2/client.go new file mode 100755 index 0000000..22fd427 --- /dev/null +++ b/policyfamilies/v2/client.go @@ -0,0 +1,254 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package policyfamilies + +import ( + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/policyfamilies/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Retrieve the information for an policy family based on its identifier and +// version +func (c *internalClient) GetPolicyFamily(ctx context.Context, req *GetPolicyFamilyRequest, opts ...call.Option) (*PolicyFamily, error) { + wireReq, err := getPolicyFamilyRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/policy-families/") + pb.singleSegment(*req.PolicyFamilyId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "version", wireReq.Version); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PolicyFamily + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp policyFamilyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = policyFamilyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns the list of policy definition types available to use at their latest +// version. This API is paginated. +func (c *internalClient) ListPolicyFamilies(ctx context.Context, req *ListPolicyFamiliesRequest, opts ...call.Option) (*ListPolicyFamiliesResponse, error) { + wireReq, err := listPolicyFamiliesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/policy-families" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPolicyFamiliesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listPolicyFamiliesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listPolicyFamiliesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListPolicyFamiliesIter returns an iterator that iterates +// over the results of ListPolicyFamilies. +// +// For example: +// +// for item, err := range c.ListPolicyFamiliesIter(ctx, &ListPolicyFamiliesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListPolicyFamilies call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListPolicyFamilies directly. +func (c *internalClient) ListPolicyFamiliesIter(ctx context.Context, req *ListPolicyFamiliesRequest, opts ...call.Option) iter.Seq2[*PolicyFamily, error] { + return func(yield func(*PolicyFamily, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListPolicyFamiliesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListPolicyFamilies(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.PolicyFamilies { + if !yield(&resp.PolicyFamilies[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} diff --git a/policyfamilies/v2/genhelper.go b/policyfamilies/v2/genhelper.go new file mode 100755 index 0000000..3f90050 --- /dev/null +++ b/policyfamilies/v2/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package policyfamilies + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/policyfamilies/v2/model.go b/policyfamilies/v2/model.go new file mode 100755 index 0000000..d273333 --- /dev/null +++ b/policyfamilies/v2/model.go @@ -0,0 +1,41 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package policyfamilies + +// Returns the details of a policy family at a specific version. +type GetPolicyFamilyRequest struct { + // The family ID about which to retrieve information. + PolicyFamilyId *string + // The version number for the family to fetch. Defaults to the latest version. + Version *int64 +} + +// Returns the list of policy families available to use at their latest version. +type ListPolicyFamiliesRequest struct { + // Maximum number of policy families to return. + MaxResults *int64 + // A token that can be used to get the next page of results. + PageToken *string +} + +type ListPolicyFamiliesResponse struct { + // List of policy families. + PolicyFamilies []PolicyFamily + // A token that can be used to get the next page of results. If not present, + // there are no more results to show. + NextPageToken *string +} + +type PolicyFamily struct { + // Unique identifier for the policy family. + PolicyFamilyId *string + // Name of the policy family. + Name *string + // Human-readable description of the purpose of the policy family. + Description *string + // Policy definition document expressed in [Databricks Cluster Policy Definition + // Language]. + // + // [Databricks Cluster Policy Definition Language]: https://docs.databricks.com/administration-guide/clusters/policy-definition.html + Definition *string +} diff --git a/policyfamilies/v2/wire.go b/policyfamilies/v2/wire.go new file mode 100755 index 0000000..238bf84 --- /dev/null +++ b/policyfamilies/v2/wire.go @@ -0,0 +1,90 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package policyfamilies + +import ( + "fmt" +) + +type getPolicyFamilyRequestWire struct { + PolicyFamilyId *string `json:"policy_family_id,omitempty"` + Version *int64 `json:"version,omitempty"` +} + +func getPolicyFamilyRequestToWire(v *GetPolicyFamilyRequest) (*getPolicyFamilyRequestWire, error) { + if v == nil { + return nil, nil + } + return &getPolicyFamilyRequestWire{ + PolicyFamilyId: v.PolicyFamilyId, + Version: v.Version, + }, nil +} + +type listPolicyFamiliesRequestWire struct { + MaxResults *int64 `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listPolicyFamiliesRequestToWire(v *ListPolicyFamiliesRequest) (*listPolicyFamiliesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listPolicyFamiliesRequestWire{ + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listPolicyFamiliesResponseWire struct { + PolicyFamilies []policyFamilyWire `json:"policy_families,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listPolicyFamiliesResponseFromWire(w *listPolicyFamiliesResponseWire) (*ListPolicyFamiliesResponse, error) { + if w == nil { + return nil, nil + } + policyFamiliesPublicValue, err := convertSlice(w.PolicyFamilies, policyFamilyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPolicyFamiliesResponse.PolicyFamilies", err) + } + return &ListPolicyFamiliesResponse{ + PolicyFamilies: policyFamiliesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type policyFamilyWire struct { + PolicyFamilyId *string `json:"policy_family_id,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + Definition *string `json:"definition,omitempty"` +} + +func policyFamilyFromWire(w *policyFamilyWire) (*PolicyFamily, error) { + if w == nil { + return nil, nil + } + return &PolicyFamily{ + PolicyFamilyId: w.PolicyFamilyId, + Name: w.Name, + Description: w.Description, + Definition: w.Definition, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/postgres/.package.json b/postgres/.package.json new file mode 100644 index 0000000..7fd6178 --- /dev/null +++ b/postgres/.package.json @@ -0,0 +1,3 @@ +{ + "package": "postgres" +} diff --git a/postgres/CHANGELOG.md b/postgres/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/postgres/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/postgres/README.md b/postgres/README.md new file mode 100644 index 0000000..6058de3 --- /dev/null +++ b/postgres/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/postgres + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/postgres@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/postgres/v1" + +client, err := postgres.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/postgres/go.mod b/postgres/go.mod new file mode 100644 index 0000000..56beb6e --- /dev/null +++ b/postgres/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/postgres + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/postgres/internal/version.go b/postgres/internal/version.go new file mode 100644 index 0000000..f225935 --- /dev/null +++ b/postgres/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-postgres" + +const Version = "0.0.1-dev.1" diff --git a/postgres/v1/client.go b/postgres/v1/client.go new file mode 100755 index 0000000..9cac693 --- /dev/null +++ b/postgres/v1/client.go @@ -0,0 +1,5911 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package postgres + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" + "github.com/databricks/sdk-go/postgres/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new database branch in the project. +func (c *internalClient) createBranchBase(ctx context.Context, req *CreateBranchRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createBranchRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Branch) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/branches") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "branch_id", wireReq.BranchId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "replace_existing", wireReq.ReplaceExisting); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new database branch in the project. +func (c *internalClient) CreateBranch(ctx context.Context, req *CreateBranchRequest, opts ...call.Option) (*CreateBranchOperation, error) { + operation, err := c.createBranchBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateBranchOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// CreateBranchOperation tracks the state of the long-running operation started by CreateBranch. +type CreateBranchOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateBranchOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateBranchOperation) Metadata() (*BranchOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata branchOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := branchOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateBranchOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateBranchOperation) Wait(ctx context.Context, opts ...lro.Option) (*Branch, error) { + var result *Branch + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response branchWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = branchFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Register a Postgres database in the Unity Catalog. +func (c *internalClient) createCatalogBase(ctx context.Context, req *CreateCatalogRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createCatalogRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Catalog) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/postgres/catalogs" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "catalog_id", wireReq.CatalogId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Register a Postgres database in the Unity Catalog. +func (c *internalClient) CreateCatalog(ctx context.Context, req *CreateCatalogRequest, opts ...call.Option) (*CreateCatalogOperation, error) { + operation, err := c.createCatalogBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateCatalogOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// CreateCatalogOperation tracks the state of the long-running operation started by CreateCatalog. +type CreateCatalogOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateCatalogOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateCatalogOperation) Metadata() (*CatalogOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata catalogOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := catalogOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateCatalogOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateCatalogOperation) Wait(ctx context.Context, opts ...lro.Option) (*Catalog, error) { + var result *Catalog + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response catalogWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = catalogFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Create a CDF configuration that materializes the change data feed for all +// tables in a Postgres schema as open-format Delta tables in Unity Catalog. +// Once created, each table's change history is continuously written to its +// corresponding Lakehouse table. +func (c *internalClient) createCdfConfigBase(ctx context.Context, req *CreateCdfConfigRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createCdfConfigRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.CdfConfig) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/cdf-configs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "cdf_config_id", wireReq.CdfConfigId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a CDF configuration that materializes the change data feed for all +// tables in a Postgres schema as open-format Delta tables in Unity Catalog. +// Once created, each table's change history is continuously written to its +// corresponding Lakehouse table. +func (c *internalClient) CreateCdfConfig(ctx context.Context, req *CreateCdfConfigRequest, opts ...call.Option) (*CreateCdfConfigOperation, error) { + operation, err := c.createCdfConfigBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateCdfConfigOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// CreateCdfConfigOperation tracks the state of the long-running operation started by CreateCdfConfig. +type CreateCdfConfigOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateCdfConfigOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateCdfConfigOperation) Metadata() (*CdfConfigOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata cdfConfigOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := cdfConfigOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateCdfConfigOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateCdfConfigOperation) Wait(ctx context.Context, opts ...lro.Option) (*CdfConfig, error) { + var result *CdfConfig + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response cdfConfigWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = cdfConfigFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Enable Data API for a database. +func (c *internalClient) createDataApiBase(ctx context.Context, req *CreateDataApiRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createDataApiRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.DataApi) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/data-api") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Enable Data API for a database. +func (c *internalClient) CreateDataApi(ctx context.Context, req *CreateDataApiRequest, opts ...call.Option) (*CreateDataApiOperation, error) { + operation, err := c.createDataApiBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateDataApiOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// CreateDataApiOperation tracks the state of the long-running operation started by CreateDataApi. +type CreateDataApiOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateDataApiOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateDataApiOperation) Metadata() (*DataApiOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata dataApiOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := dataApiOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateDataApiOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateDataApiOperation) Wait(ctx context.Context, opts ...lro.Option) (*DataApi, error) { + var result *DataApi + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response dataApiWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = dataApiFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Create a Database. +// +// Creates a database in the specified branch. A branch can have multiple +// databases. +func (c *internalClient) createDatabaseBase(ctx context.Context, req *CreateDatabaseRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createDatabaseRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Database) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/databases") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "database_id", wireReq.DatabaseId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "replace_existing", wireReq.ReplaceExisting); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a Database. +// +// Creates a database in the specified branch. A branch can have multiple +// databases. +func (c *internalClient) CreateDatabase(ctx context.Context, req *CreateDatabaseRequest, opts ...call.Option) (*CreateDatabaseOperation, error) { + operation, err := c.createDatabaseBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateDatabaseOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// CreateDatabaseOperation tracks the state of the long-running operation started by CreateDatabase. +type CreateDatabaseOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateDatabaseOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateDatabaseOperation) Metadata() (*DatabaseOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata databaseOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := databaseOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateDatabaseOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateDatabaseOperation) Wait(ctx context.Context, opts ...lro.Option) (*Database, error) { + var result *Database + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response databaseWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = databaseFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Creates a new compute endpoint in the branch. +func (c *internalClient) createEndpointBase(ctx context.Context, req *CreateEndpointRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createEndpointRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Endpoint) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/endpoints") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "endpoint_id", wireReq.EndpointId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "replace_existing", wireReq.ReplaceExisting); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new compute endpoint in the branch. +func (c *internalClient) CreateEndpoint(ctx context.Context, req *CreateEndpointRequest, opts ...call.Option) (*CreateEndpointOperation, error) { + operation, err := c.createEndpointBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateEndpointOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// CreateEndpointOperation tracks the state of the long-running operation started by CreateEndpoint. +type CreateEndpointOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateEndpointOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateEndpointOperation) Metadata() (*EndpointOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata endpointOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := endpointOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateEndpointOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateEndpointOperation) Wait(ctx context.Context, opts ...lro.Option) (*Endpoint, error) { + var result *Endpoint + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response endpointWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = endpointFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Creates a new Lakebase Autoscaling Postgres database project, which contains +// branches and compute endpoints. +func (c *internalClient) createProjectBase(ctx context.Context, req *CreateProjectRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createProjectRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Project) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/postgres/projects" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "project_id", wireReq.ProjectId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new Lakebase Autoscaling Postgres database project, which contains +// branches and compute endpoints. +func (c *internalClient) CreateProject(ctx context.Context, req *CreateProjectRequest, opts ...call.Option) (*CreateProjectOperation, error) { + operation, err := c.createProjectBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateProjectOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// CreateProjectOperation tracks the state of the long-running operation started by CreateProject. +type CreateProjectOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateProjectOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateProjectOperation) Metadata() (*ProjectOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata projectOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := projectOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateProjectOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateProjectOperation) Wait(ctx context.Context, opts ...lro.Option) (*Project, error) { + var result *Project + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response projectWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = projectFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Creates a new Postgres role in the branch. +func (c *internalClient) createRoleBase(ctx context.Context, req *CreateRoleRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createRoleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Role) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/roles") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "role_id", wireReq.RoleId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "replace_existing", wireReq.ReplaceExisting); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new Postgres role in the branch. +func (c *internalClient) CreateRole(ctx context.Context, req *CreateRoleRequest, opts ...call.Option) (*CreateRoleOperation, error) { + operation, err := c.createRoleBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateRoleOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// CreateRoleOperation tracks the state of the long-running operation started by CreateRole. +type CreateRoleOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateRoleOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateRoleOperation) Metadata() (*RoleOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata roleOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := roleOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateRoleOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateRoleOperation) Wait(ctx context.Context, opts ...lro.Option) (*Role, error) { + var result *Role + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response roleWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = roleFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Create a Synced Table. +func (c *internalClient) createSyncedTableBase(ctx context.Context, req *CreateSyncedTableRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := createSyncedTableRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.SyncedTable) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/postgres/synced_tables" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "synced_table_id", wireReq.SyncedTableId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a Synced Table. +func (c *internalClient) CreateSyncedTable(ctx context.Context, req *CreateSyncedTableRequest, opts ...call.Option) (*CreateSyncedTableOperation, error) { + operation, err := c.createSyncedTableBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &CreateSyncedTableOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// CreateSyncedTableOperation tracks the state of the long-running operation started by CreateSyncedTable. +type CreateSyncedTableOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *CreateSyncedTableOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *CreateSyncedTableOperation) Metadata() (*SyncedTableOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata syncedTableOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := syncedTableOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *CreateSyncedTableOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *CreateSyncedTableOperation) Wait(ctx context.Context, opts ...lro.Option) (*SyncedTable, error) { + var result *SyncedTable + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response syncedTableWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = syncedTableFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Deletes the specified database branch. +func (c *internalClient) deleteBranchBase(ctx context.Context, req *DeleteBranchRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := deleteBranchRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "purge", wireReq.Purge); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the specified database branch. +func (c *internalClient) DeleteBranch(ctx context.Context, req *DeleteBranchRequest, opts ...call.Option) (*DeleteBranchOperation, error) { + operation, err := c.deleteBranchBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &DeleteBranchOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// DeleteBranchOperation tracks the state of the long-running operation started by DeleteBranch. +type DeleteBranchOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *DeleteBranchOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *DeleteBranchOperation) Metadata() (*BranchOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata branchOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := branchOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *DeleteBranchOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *DeleteBranchOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Delete a Database Catalog. +func (c *internalClient) deleteCatalogBase(ctx context.Context, req *DeleteCatalogRequest, opts ...call.Option) (*Operation, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a Database Catalog. +func (c *internalClient) DeleteCatalog(ctx context.Context, req *DeleteCatalogRequest, opts ...call.Option) (*DeleteCatalogOperation, error) { + operation, err := c.deleteCatalogBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &DeleteCatalogOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// DeleteCatalogOperation tracks the state of the long-running operation started by DeleteCatalog. +type DeleteCatalogOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *DeleteCatalogOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *DeleteCatalogOperation) Metadata() (*CatalogOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata catalogOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := catalogOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *DeleteCatalogOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *DeleteCatalogOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Delete a CDF configuration and stop materializing the change data feed. When +// force=true, also drops the Delta tables in Unity Catalog. When force=false +// (default), the existing tables are preserved at their last state. +func (c *internalClient) deleteCdfConfigBase(ctx context.Context, req *DeleteCdfConfigRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := deleteCdfConfigRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a CDF configuration and stop materializing the change data feed. When +// force=true, also drops the Delta tables in Unity Catalog. When force=false +// (default), the existing tables are preserved at their last state. +func (c *internalClient) DeleteCdfConfig(ctx context.Context, req *DeleteCdfConfigRequest, opts ...call.Option) (*DeleteCdfConfigOperation, error) { + operation, err := c.deleteCdfConfigBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &DeleteCdfConfigOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// DeleteCdfConfigOperation tracks the state of the long-running operation started by DeleteCdfConfig. +type DeleteCdfConfigOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *DeleteCdfConfigOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *DeleteCdfConfigOperation) Metadata() (*CdfConfigOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata cdfConfigOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := cdfConfigOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *DeleteCdfConfigOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *DeleteCdfConfigOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Disable Data API for a database. +func (c *internalClient) deleteDataApiBase(ctx context.Context, req *DeleteDataApiRequest, opts ...call.Option) (*Operation, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Disable Data API for a database. +func (c *internalClient) DeleteDataApi(ctx context.Context, req *DeleteDataApiRequest, opts ...call.Option) (*DeleteDataApiOperation, error) { + operation, err := c.deleteDataApiBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &DeleteDataApiOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// DeleteDataApiOperation tracks the state of the long-running operation started by DeleteDataApi. +type DeleteDataApiOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *DeleteDataApiOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *DeleteDataApiOperation) Metadata() (*DataApiOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata dataApiOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := dataApiOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *DeleteDataApiOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *DeleteDataApiOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Delete a Database. +func (c *internalClient) deleteDatabaseBase(ctx context.Context, req *DeleteDatabaseRequest, opts ...call.Option) (*Operation, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a Database. +func (c *internalClient) DeleteDatabase(ctx context.Context, req *DeleteDatabaseRequest, opts ...call.Option) (*DeleteDatabaseOperation, error) { + operation, err := c.deleteDatabaseBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &DeleteDatabaseOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// DeleteDatabaseOperation tracks the state of the long-running operation started by DeleteDatabase. +type DeleteDatabaseOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *DeleteDatabaseOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *DeleteDatabaseOperation) Metadata() (*DatabaseOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata databaseOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := databaseOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *DeleteDatabaseOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *DeleteDatabaseOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Deletes the specified compute endpoint. +func (c *internalClient) deleteEndpointBase(ctx context.Context, req *DeleteEndpointRequest, opts ...call.Option) (*Operation, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the specified compute endpoint. +func (c *internalClient) DeleteEndpoint(ctx context.Context, req *DeleteEndpointRequest, opts ...call.Option) (*DeleteEndpointOperation, error) { + operation, err := c.deleteEndpointBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &DeleteEndpointOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// DeleteEndpointOperation tracks the state of the long-running operation started by DeleteEndpoint. +type DeleteEndpointOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *DeleteEndpointOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *DeleteEndpointOperation) Metadata() (*EndpointOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata endpointOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := endpointOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *DeleteEndpointOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *DeleteEndpointOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Deletes the specified database project. +func (c *internalClient) deleteProjectBase(ctx context.Context, req *DeleteProjectRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := deleteProjectRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "purge", wireReq.Purge); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the specified database project. +func (c *internalClient) DeleteProject(ctx context.Context, req *DeleteProjectRequest, opts ...call.Option) (*DeleteProjectOperation, error) { + operation, err := c.deleteProjectBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &DeleteProjectOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// DeleteProjectOperation tracks the state of the long-running operation started by DeleteProject. +type DeleteProjectOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *DeleteProjectOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *DeleteProjectOperation) Metadata() (*ProjectOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata projectOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := projectOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *DeleteProjectOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *DeleteProjectOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Deletes the specified Postgres role. +func (c *internalClient) deleteRoleBase(ctx context.Context, req *DeleteRoleRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := deleteRoleRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "reassign_owned_to", wireReq.ReassignOwnedTo); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the specified Postgres role. +func (c *internalClient) DeleteRole(ctx context.Context, req *DeleteRoleRequest, opts ...call.Option) (*DeleteRoleOperation, error) { + operation, err := c.deleteRoleBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &DeleteRoleOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// DeleteRoleOperation tracks the state of the long-running operation started by DeleteRole. +type DeleteRoleOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *DeleteRoleOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *DeleteRoleOperation) Metadata() (*RoleOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata roleOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := roleOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *DeleteRoleOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *DeleteRoleOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Delete a Synced Table. +func (c *internalClient) deleteSyncedTableBase(ctx context.Context, req *DeleteSyncedTableRequest, opts ...call.Option) (*Operation, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a Synced Table. +func (c *internalClient) DeleteSyncedTable(ctx context.Context, req *DeleteSyncedTableRequest, opts ...call.Option) (*DeleteSyncedTableOperation, error) { + operation, err := c.deleteSyncedTableBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &DeleteSyncedTableOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// DeleteSyncedTableOperation tracks the state of the long-running operation started by DeleteSyncedTable. +type DeleteSyncedTableOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *DeleteSyncedTableOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *DeleteSyncedTableOperation) Metadata() (*SyncedTableOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata syncedTableOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := syncedTableOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *DeleteSyncedTableOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *DeleteSyncedTableOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Generate OAuth credentials for a Postgres database. +func (c *internalClient) GenerateDatabaseCredential(ctx context.Context, req *GenerateDatabaseCredentialRequest, opts ...call.Option) (*DatabaseCredential, error) { + wireReq, err := generateDatabaseCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/postgres/credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DatabaseCredential + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseCredentialWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseCredentialFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves information about the specified database branch. +func (c *internalClient) GetBranch(ctx context.Context, req *GetBranchRequest, opts ...call.Option) (*Branch, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Branch + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp branchWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = branchFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a Database Catalog. +func (c *internalClient) GetCatalog(ctx context.Context, req *GetCatalogRequest, opts ...call.Option) (*Catalog, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Catalog + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp catalogWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = catalogFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a single Lakebase CDF configuration, including the source Postgres +// schema, target Unity Catalog schema, and the identity under which writes are +// authorized. +func (c *internalClient) GetCdfConfig(ctx context.Context, req *GetCdfConfigRequest, opts ...call.Option) (*CdfConfig, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CdfConfig + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cdfConfigWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cdfConfigFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get the CDF status of a single table within a Lakebase CDF configuration, +// including its current state and the last committed position in the feed. +func (c *internalClient) GetCdfStatus(ctx context.Context, req *GetCdfStatusRequest, opts ...call.Option) (*CdfStatus, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CdfStatus + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp cdfStatusWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = cdfStatusFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get Data API configuration for a database. +func (c *internalClient) GetDataApi(ctx context.Context, req *GetDataApiRequest, opts ...call.Option) (*DataApi, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DataApi + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp dataApiWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = dataApiFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a Database. +func (c *internalClient) GetDatabase(ctx context.Context, req *GetDatabaseRequest, opts ...call.Option) (*Database, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Database + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp databaseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = databaseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves information about the specified compute endpoint, including its +// connection details and operational state. +func (c *internalClient) GetEndpoint(ctx context.Context, req *GetEndpointRequest, opts ...call.Option) (*Endpoint, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Endpoint + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp endpointWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = endpointFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves the status of a long-running operation. +func (c *internalClient) getOperation(ctx context.Context, req *GetOperationRequest, opts ...call.Option) (*Operation, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves information about the specified database project. +func (c *internalClient) GetProject(ctx context.Context, req *GetProjectRequest, opts ...call.Option) (*Project, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Project + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp projectWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = projectFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieves information about the specified Postgres role, including its +// authentication method and permissions. +func (c *internalClient) GetRole(ctx context.Context, req *GetRoleRequest, opts ...call.Option) (*Role, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Role + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp roleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = roleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a Synced Table. +func (c *internalClient) GetSyncedTable(ctx context.Context, req *GetSyncedTableRequest, opts ...call.Option) (*SyncedTable, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SyncedTable + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp syncedTableWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = syncedTableFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns a paginated list of database branches in the project. +func (c *internalClient) ListBranches(ctx context.Context, req *ListBranchesRequest, opts ...call.Option) (*ListBranchesResponse, error) { + wireReq, err := listBranchesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/branches") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "show_deleted", wireReq.ShowDeleted); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListBranchesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listBranchesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listBranchesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListBranchesIter returns an iterator that iterates +// over the results of ListBranches. +// +// For example: +// +// for item, err := range c.ListBranchesIter(ctx, &ListBranchesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListBranches call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListBranches directly. +func (c *internalClient) ListBranchesIter(ctx context.Context, req *ListBranchesRequest, opts ...call.Option) iter.Seq2[*Branch, error] { + return func(yield func(*Branch, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListBranchesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListBranches(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Branches { + if !yield(&resp.Branches[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List all CDF configurations for a Lakebase database. Each configuration maps +// a Postgres schema to a Unity Catalog schema where the change data feed is +// materialized. +func (c *internalClient) ListCdfConfigs(ctx context.Context, req *ListCdfConfigsRequest, opts ...call.Option) (*ListCdfConfigsResponse, error) { + wireReq, err := listCdfConfigsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/cdf-configs") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCdfConfigsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCdfConfigsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCdfConfigsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCdfConfigsIter returns an iterator that iterates +// over the results of ListCdfConfigs. +// +// For example: +// +// for item, err := range c.ListCdfConfigsIter(ctx, &ListCdfConfigsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCdfConfigs call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCdfConfigs directly. +func (c *internalClient) ListCdfConfigsIter(ctx context.Context, req *ListCdfConfigsRequest, opts ...call.Option) iter.Seq2[*CdfConfig, error] { + return func(yield func(*CdfConfig, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCdfConfigsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCdfConfigs(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.CdfConfigs { + if !yield(&resp.CdfConfigs[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List the per-table CDF statuses within a Lakebase CDF configuration. Each +// status shows whether a table's change data feed is snapshotting, streaming, +// or skipped. +func (c *internalClient) ListCdfStatuses(ctx context.Context, req *ListCdfStatusesRequest, opts ...call.Option) (*ListCdfStatusesResponse, error) { + wireReq, err := listCdfStatusesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/cdf-statuses") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCdfStatusesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCdfStatusesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCdfStatusesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCdfStatusesIter returns an iterator that iterates +// over the results of ListCdfStatuses. +// +// For example: +// +// for item, err := range c.ListCdfStatusesIter(ctx, &ListCdfStatusesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCdfStatuses call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCdfStatuses directly. +func (c *internalClient) ListCdfStatusesIter(ctx context.Context, req *ListCdfStatusesRequest, opts ...call.Option) iter.Seq2[*CdfStatus, error] { + return func(yield func(*CdfStatus, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCdfStatusesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCdfStatuses(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.CdfStatuses { + if !yield(&resp.CdfStatuses[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List Databases. +func (c *internalClient) ListDatabases(ctx context.Context, req *ListDatabasesRequest, opts ...call.Option) (*ListDatabasesResponse, error) { + wireReq, err := listDatabasesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/databases") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListDatabasesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listDatabasesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listDatabasesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListDatabasesIter returns an iterator that iterates +// over the results of ListDatabases. +// +// For example: +// +// for item, err := range c.ListDatabasesIter(ctx, &ListDatabasesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListDatabases call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListDatabases directly. +func (c *internalClient) ListDatabasesIter(ctx context.Context, req *ListDatabasesRequest, opts ...call.Option) iter.Seq2[*Database, error] { + return func(yield func(*Database, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListDatabasesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListDatabases(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Databases { + if !yield(&resp.Databases[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Returns a paginated list of compute endpoints in the branch. +func (c *internalClient) ListEndpoints(ctx context.Context, req *ListEndpointsRequest, opts ...call.Option) (*ListEndpointsResponse, error) { + wireReq, err := listEndpointsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/endpoints") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListEndpointsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listEndpointsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listEndpointsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListEndpointsIter returns an iterator that iterates +// over the results of ListEndpoints. +// +// For example: +// +// for item, err := range c.ListEndpointsIter(ctx, &ListEndpointsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListEndpoints call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListEndpoints directly. +func (c *internalClient) ListEndpointsIter(ctx context.Context, req *ListEndpointsRequest, opts ...call.Option) iter.Seq2[*Endpoint, error] { + return func(yield func(*Endpoint, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListEndpointsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListEndpoints(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Endpoints { + if !yield(&resp.Endpoints[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Returns a paginated list of database projects in the workspace that the user +// has permission to access. +func (c *internalClient) ListProjects(ctx context.Context, req *ListProjectsRequest, opts ...call.Option) (*ListProjectsResponse, error) { + wireReq, err := listProjectsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/postgres/projects" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "show_deleted", wireReq.ShowDeleted); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListProjectsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listProjectsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listProjectsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListProjectsIter returns an iterator that iterates +// over the results of ListProjects. +// +// For example: +// +// for item, err := range c.ListProjectsIter(ctx, &ListProjectsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListProjects call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListProjects directly. +func (c *internalClient) ListProjectsIter(ctx context.Context, req *ListProjectsRequest, opts ...call.Option) iter.Seq2[*Project, error] { + return func(yield func(*Project, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListProjectsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListProjects(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Projects { + if !yield(&resp.Projects[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Returns a paginated list of Postgres roles in the branch. +func (c *internalClient) ListRoles(ctx context.Context, req *ListRolesRequest, opts ...call.Option) (*ListRolesResponse, error) { + wireReq, err := listRolesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Parent) + pb.literal("/roles") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListRolesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listRolesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listRolesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListRolesIter returns an iterator that iterates +// over the results of ListRoles. +// +// For example: +// +// for item, err := range c.ListRolesIter(ctx, &ListRolesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListRoles call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListRoles directly. +func (c *internalClient) ListRolesIter(ctx context.Context, req *ListRolesRequest, opts ...call.Option) iter.Seq2[*Role, error] { + return func(yield func(*Role, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListRolesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListRoles(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Roles { + if !yield(&resp.Roles[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Undeletes the specified database branch. +func (c *internalClient) undeleteBranchBase(ctx context.Context, req *UndeleteBranchRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := undeleteBranchRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + pb.literal("/undelete") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Undeletes the specified database branch. +func (c *internalClient) UndeleteBranch(ctx context.Context, req *UndeleteBranchRequest, opts ...call.Option) (*UndeleteBranchOperation, error) { + operation, err := c.undeleteBranchBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &UndeleteBranchOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// UndeleteBranchOperation tracks the state of the long-running operation started by UndeleteBranch. +type UndeleteBranchOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *UndeleteBranchOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *UndeleteBranchOperation) Metadata() (*BranchOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata branchOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := branchOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *UndeleteBranchOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *UndeleteBranchOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Undeletes a soft-deleted project. +func (c *internalClient) undeleteProjectBase(ctx context.Context, req *UndeleteProjectRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := undeleteProjectRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Name) + pb.literal("/undelete") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Undeletes a soft-deleted project. +func (c *internalClient) UndeleteProject(ctx context.Context, req *UndeleteProjectRequest, opts ...call.Option) (*UndeleteProjectOperation, error) { + operation, err := c.undeleteProjectBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &UndeleteProjectOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// UndeleteProjectOperation tracks the state of the long-running operation started by UndeleteProject. +type UndeleteProjectOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *UndeleteProjectOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *UndeleteProjectOperation) Metadata() (*ProjectOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata projectOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := projectOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *UndeleteProjectOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *UndeleteProjectOperation) Wait(ctx context.Context, opts ...lro.Option) error { + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return err + } + return nil +} + +// Updates the specified database branch. You can set this branch as the +// project's default branch, or protect/unprotect it. +func (c *internalClient) updateBranchBase(ctx context.Context, req *UpdateBranchRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := updateBranchRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Branch) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Branch.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the specified database branch. You can set this branch as the +// project's default branch, or protect/unprotect it. +func (c *internalClient) UpdateBranch(ctx context.Context, req *UpdateBranchRequest, opts ...call.Option) (*UpdateBranchOperation, error) { + operation, err := c.updateBranchBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &UpdateBranchOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// UpdateBranchOperation tracks the state of the long-running operation started by UpdateBranch. +type UpdateBranchOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *UpdateBranchOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *UpdateBranchOperation) Metadata() (*BranchOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata branchOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := branchOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *UpdateBranchOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *UpdateBranchOperation) Wait(ctx context.Context, opts ...lro.Option) (*Branch, error) { + var result *Branch + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response branchWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = branchFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Update Data API configuration for a database. +func (c *internalClient) updateDataApiBase(ctx context.Context, req *UpdateDataApiRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := updateDataApiRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.DataApi) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.DataApi.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update Data API configuration for a database. +func (c *internalClient) UpdateDataApi(ctx context.Context, req *UpdateDataApiRequest, opts ...call.Option) (*UpdateDataApiOperation, error) { + operation, err := c.updateDataApiBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &UpdateDataApiOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// UpdateDataApiOperation tracks the state of the long-running operation started by UpdateDataApi. +type UpdateDataApiOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *UpdateDataApiOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *UpdateDataApiOperation) Metadata() (*DataApiOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata dataApiOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := dataApiOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *UpdateDataApiOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *UpdateDataApiOperation) Wait(ctx context.Context, opts ...lro.Option) (*DataApi, error) { + var result *DataApi + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response dataApiWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = dataApiFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Update a Database. +func (c *internalClient) updateDatabaseBase(ctx context.Context, req *UpdateDatabaseRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := updateDatabaseRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Database) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Database.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a Database. +func (c *internalClient) UpdateDatabase(ctx context.Context, req *UpdateDatabaseRequest, opts ...call.Option) (*UpdateDatabaseOperation, error) { + operation, err := c.updateDatabaseBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &UpdateDatabaseOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// UpdateDatabaseOperation tracks the state of the long-running operation started by UpdateDatabase. +type UpdateDatabaseOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *UpdateDatabaseOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *UpdateDatabaseOperation) Metadata() (*DatabaseOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata databaseOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := databaseOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *UpdateDatabaseOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *UpdateDatabaseOperation) Wait(ctx context.Context, opts ...lro.Option) (*Database, error) { + var result *Database + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response databaseWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = databaseFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Updates the specified compute endpoint. You can update autoscaling limits, +// suspend timeout, or enable/disable the compute endpoint. +func (c *internalClient) updateEndpointBase(ctx context.Context, req *UpdateEndpointRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := updateEndpointRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Endpoint) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Endpoint.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the specified compute endpoint. You can update autoscaling limits, +// suspend timeout, or enable/disable the compute endpoint. +func (c *internalClient) UpdateEndpoint(ctx context.Context, req *UpdateEndpointRequest, opts ...call.Option) (*UpdateEndpointOperation, error) { + operation, err := c.updateEndpointBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &UpdateEndpointOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// UpdateEndpointOperation tracks the state of the long-running operation started by UpdateEndpoint. +type UpdateEndpointOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *UpdateEndpointOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *UpdateEndpointOperation) Metadata() (*EndpointOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata endpointOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := endpointOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *UpdateEndpointOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *UpdateEndpointOperation) Wait(ctx context.Context, opts ...lro.Option) (*Endpoint, error) { + var result *Endpoint + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response endpointWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = endpointFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Updates the specified database project. +func (c *internalClient) updateProjectBase(ctx context.Context, req *UpdateProjectRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := updateProjectRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Project) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Project.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the specified database project. +func (c *internalClient) UpdateProject(ctx context.Context, req *UpdateProjectRequest, opts ...call.Option) (*UpdateProjectOperation, error) { + operation, err := c.updateProjectBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &UpdateProjectOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// UpdateProjectOperation tracks the state of the long-running operation started by UpdateProject. +type UpdateProjectOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *UpdateProjectOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *UpdateProjectOperation) Metadata() (*ProjectOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata projectOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := projectOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *UpdateProjectOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *UpdateProjectOperation) Wait(ctx context.Context, opts ...lro.Option) (*Project, error) { + var result *Project + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response projectWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = projectFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Update a role for a branch. +func (c *internalClient) updateRoleBase(ctx context.Context, req *UpdateRoleRequest, opts ...call.Option) (*Operation, error) { + wireReq, err := updateRoleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Role) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/postgres/") + pb.singleSegment(*req.Role.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Operation + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp operationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = operationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a role for a branch. +func (c *internalClient) UpdateRole(ctx context.Context, req *UpdateRoleRequest, opts ...call.Option) (*UpdateRoleOperation, error) { + operation, err := c.updateRoleBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if err := validateOperationName(operation.Name); err != nil { + return nil, err + } + return &UpdateRoleOperation{ + operation: operation, + getOperation: c.getOperation, + }, nil +} + +// UpdateRoleOperation tracks the state of the long-running operation started by UpdateRole. +type UpdateRoleOperation struct { + operation *Operation + getOperation func(context.Context, *GetOperationRequest, ...call.Option) (*Operation, error) +} + +// Name returns the server-assigned operation name. +func (o *UpdateRoleOperation) Name() *string { + return o.operation.Name +} + +// Metadata returns metadata associated with the operation. +func (o *UpdateRoleOperation) Metadata() (*RoleOperationMetadata, error) { + if len(o.operation.Metadata) == 0 || bytes.Equal(bytes.TrimSpace(o.operation.Metadata), []byte("null")) { + return nil, nil + } + var metadata roleOperationMetadataWire + if err := json.Unmarshal(o.operation.Metadata, &metadata); err != nil { + return nil, fmt.Errorf("decode operation metadata: %w", err) + } + converted, err := roleOperationMetadataFromWire(&metadata) + if err != nil { + return nil, err + } + return converted, nil +} + +// Done refreshes the operation and reports whether it has completed. +func (o *UpdateRoleOperation) Done(ctx context.Context, opts ...call.Option) (bool, error) { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}, opts...) + if err != nil { + return false, err + } + if err := validateOperationName(operation.Name); err != nil { + return false, err + } + o.operation = operation + if operation.Done == nil { + return false, fmt.Errorf("invalid operation response: missing done field") + } + return *operation.Done, nil +} + +// Wait polls the operation until it completes. +func (o *UpdateRoleOperation) Wait(ctx context.Context, opts ...lro.Option) (*Role, error) { + var result *Role + poll := func(ctx context.Context) error { + operation, err := o.getOperation(ctx, &GetOperationRequest{Name: o.operation.Name}) + if err != nil { + return err + } + if err := validateOperationName(operation.Name); err != nil { + return err + } + o.operation = operation + if operation.Done == nil { + return fmt.Errorf("invalid operation response: missing done field") + } + if !*operation.Done { + return errOperationStillRunning + } + if operationError, ok := operation.Result.(*Operation_Result_Error); ok && operationError != nil { + return fmt.Errorf("operation failed: %w", &operationError.Error) + } + operationResponse, ok := operation.Result.(*Operation_Result_Response) + if !ok || operationResponse == nil || len(operationResponse.Response) == 0 || bytes.Equal(bytes.TrimSpace(operationResponse.Response), []byte("null")) { + return fmt.Errorf("operation completed without a response") + } + var response roleWire + if err := json.Unmarshal(operationResponse.Response, &response); err != nil { + return fmt.Errorf("decode operation response: %w", err) + } + result, err = roleFromWire(&response) + if err != nil { + return err + } + return nil + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} diff --git a/postgres/v1/genhelper.go b/postgres/v1/genhelper.go new file mode 100755 index 0000000..c1c01f1 --- /dev/null +++ b/postgres/v1/genhelper.go @@ -0,0 +1,250 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package postgres + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func validateOperationName(operationName *string) error { + if operationName == nil || *operationName == "" { + return errors.New("invalid operation response: missing operation name") + } + return nil +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/postgres/v1/model.go b/postgres/v1/model.go new file mode 100755 index 0000000..94b71a3 --- /dev/null +++ b/postgres/v1/model.go @@ -0,0 +1,2310 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package postgres + +import ( + "encoding/json" + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +// The replication state of a single replicated table (CdfStatus). +type CdfState string + +const ( + CdfState_Unspecified CdfState = "" + // Taking the initial snapshot: the table's existing rows are being written to + // the Delta table. + CdfState_CdfStateSnapshotting CdfState = "CDF_STATE_SNAPSHOTTING" + // Continuously streaming WAL changes to the Delta table. + CdfState_CdfStateStreaming CdfState = "CDF_STATE_STREAMING" + // Reserved: replication for this table was superseded by a newer one. Not + // currently returned by the API. + CdfState_CdfStateTerminated CdfState = "CDF_STATE_TERMINATED" + // The table is not being replicated: it was skipped because it is not eligible + // for replication, or replication errored. See status_detail for the specific + // reason. + CdfState_CdfStateSkipped CdfState = "CDF_STATE_SKIPPED" +) + +// The compute endpoint type. Either `read_write` or `read_only`. +type EndpointType string + +const ( + EndpointType_Unspecified EndpointType = "" + EndpointType_EndpointTypeReadWrite EndpointType = "ENDPOINT_TYPE_READ_WRITE" + EndpointType_EndpointTypeReadOnly EndpointType = "ENDPOINT_TYPE_READ_ONLY" +) + +// Error codes returned by Databricks APIs to indicate specific failure +// conditions. +type ErrorCode string + +const ( + ErrorCode_Unspecified ErrorCode = "" + // Internal error. This means that some invariants expected by the underlying + // system have been broken. This error code is reserved for serious errors, + // which generally cannot be resolved by the user. + // + // Prefer this over all kinds of detailed error messages (e.g IO_ERROR), unless + // there's some automation that relies on the custom error code. + // + // Maps to: - google.rpc.Code: INTERNAL = 13; - HTTP code: 500 Internal Server + // Error + ErrorCode_InternalError ErrorCode = "INTERNAL_ERROR" + // The service is currently unavailable. This is most likely a transient + // condition, which can be corrected by retrying with a backoff. Note that it is + // not always safe to retry non-idempotent operations. + // + // Prefer this over SERVICE_UNDER_MAINTENANCE, + // WORKSPACE_TEMPORARILY_UNAVAILABLE. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on how to pick this vs RESOURCE_EXHAUSTED. + // + // Maps to: - google.rpc.Code: UNAVAILABLE = 14; - HTTP code: 503 Service + // Unavailable + ErrorCode_TemporarilyUnavailable ErrorCode = "TEMPORARILY_UNAVAILABLE" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Indicates that an IOException has been internally + // thrown. + ErrorCode_IoError ErrorCode = "IO_ERROR" + // The request is invalid. Prefer more specific error code whenever possible. + // Also see similar recommendation for the google.rpc.Code.FAILED_PRECONDITION. + // + // Prefer this error code over MALFORMED_REQUEST, INVALID_STATE, + // UNPARSEABLE_HTTP_ERROR. + // + // Maps to: - google.rpc.Code: FAILED_PRECONDITION = 9; - HTTP code: 400 Bad + // Request + ErrorCode_BadRequest ErrorCode = "BAD_REQUEST" + // An external service is unavailable temporarily as it is being + // updated/re-deployed. Indicates gateway proxy to safely retry the request. + ErrorCode_ServiceUnderMaintenance ErrorCode = "SERVICE_UNDER_MAINTENANCE" + // A workspace is temporarily unavailable as the workspace is being re-assigned. + ErrorCode_WorkspaceTemporarilyUnavailable ErrorCode = "WORKSPACE_TEMPORARILY_UNAVAILABLE" + // The deadline expired before the operation could complete. For operations that + // change the state of the system, this error may be returned even if the + // operation has completed successfully. For example, a successful response from + // a server could have been delayed long enough for the deadline to expire. When + // possible - implementations should make sure further processing of the request + // is aborted, e.g. by throwing an exception instead of making the RPC request, + // making the database query, etc. + // + // Maps to: - google.rpc.Code: DEADLINE_EXCEEDED = 4; - HTTP code: 504 Gateway + // Timeout + ErrorCode_DeadlineExceeded ErrorCode = "DEADLINE_EXCEEDED" + // The operation was canceled by the caller. An example - client closed the + // connection without waiting for a response. + // + // Maps to: - google.rpc.Code: CANCELLED = 1; - HTTP code: 499 Client Closed + // Request + ErrorCode_Cancelled ErrorCode = "CANCELLED" + // The operation is rejected because of either rate limiting or resource quota, + // such as the client has sent too many requests recently or the client has + // allocated too many resources. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on how to pick this vs TEMPORARILY_UNAVAILABLE. + // + // Maps to: - google.rpc.Code: RESOURCE_EXHAUSTED = 8; - HTTP code: 429 Too Many + // Requests + ErrorCode_ResourceExhausted ErrorCode = "RESOURCE_EXHAUSTED" + // The operation was aborted, typically due to a concurrency issue such as a + // sequencer check failure, transaction abort, or transaction conflict. + // + // Maps to: - google.rpc.Code: ABORTED = 10; - HTTP code: 409 Conflict + ErrorCode_Aborted ErrorCode = "ABORTED" + // Operation was performed on a resource that does not exist, e.g. file or + // directory was not found. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_NotFound ErrorCode = "NOT_FOUND" + // Operation was rejected due a conflict with an existing resource, e.g. + // attempted to create file or directory that already exists. + // + // Prefer this over RESOURCE_CONFLICT. + // + // Maps to: - google.rpc.Code: ALREADY_EXISTS = 6; - HTTP code: 409 Conflict + ErrorCode_AlreadyExists ErrorCode = "ALREADY_EXISTS" + // The request does not have valid authentication (AuthN) credentials for the + // operation. + // + // Prefer this over CUSTOMER_UNAUTHORIZED, unless you need to keep consistent + // behavior with legacy code. For authorization (AuthZ) errors use + // PERMISSION_DENIED. Maps to: - google.rpc.Code: UNAUTHENTICATED = 16; - HTTP + // code: 401 Unauthorized + ErrorCode_Unauthenticated ErrorCode = "UNAUTHENTICATED" + // The service is currently unavailable. Please note that the unavailability may + // or may not be transient. That means if this is a non-transient condition, + // retrying it does not work. If the unavailability is certainly a transient + // condition, pleases use `TEMPORARILY_UNAVAILABLE` which signals its transient + // nature explicitly. An example of this error code’s use case is that when + // DNS resolution fails, the DNS resolver does not know whether it is because + // the domain name is completely wrong (non-transient situation) or the domain + // name is valid but the DNS server does not have an entry for this domain name + // yet (transient situation). Hence, `UNAVAILABLE` is suitable for this case. + // + // Maps to: - google.rpc.Code: UNAVAILABLE = 14; - HTTP code: 503 Service + // Unavailable + ErrorCode_Unavailable ErrorCode = "UNAVAILABLE" + // Supplied value for a parameter was invalid (e.g., giving a number for a + // string parameter). + // + // Maps to: - google.rpc.Code: INVALID_ARGUMENT = 3; - HTTP code: 400 Bad + // Request + ErrorCode_InvalidParameterValue ErrorCode = "INVALID_PARAMETER_VALUE" + // Indicates that the given API endpoint does not exist. Legacy, when possible - + // NOT_IMPLEMENTED should be used instead to indicate that API doesn't exist. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_EndpointNotFound ErrorCode = "ENDPOINT_NOT_FOUND" + // Indicates that the given API request was malformed. + ErrorCode_MalformedRequest ErrorCode = "MALFORMED_REQUEST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. If one or more of the inputs to a given RPC are not in + // a valid state for the action. + ErrorCode_InvalidState ErrorCode = "INVALID_STATE" + // The caller does not have permission to execute the specified operation. + // PERMISSION_DENIED must not be used for rejections caused by exhausting some + // resource, use RESOURCE_EXHAUSTED instead for those errors. PERMISSION_DENIED + // must not be used if the caller can not be identified, use + // CUSTOMER_UNAUTHORIZED instead for those errors. This error code does not + // imply the request is valid or the requested entity exists or satisfies other + // pre-conditions. + // + // Maps to: - google.rpc.Code: PERMISSION_DENIED = 7; - HTTP code: 403 Forbidden + ErrorCode_PermissionDenied ErrorCode = "PERMISSION_DENIED" + // NOTE: Deprecated due to inconsistent mapping in legacy code, see + // https://docs.google.com/document/d/17TZIKX_Y39cJMBr333lc-d5dTvvBLSu3DPUyGU5eMJg/edit?disco=AAAAzVGt6FA. + // Prefer using NOT_FOUND or PERMISSION_DENIED. + // + // If a given user/entity is trying to use a feature which has been disabled. + // + // Maps to: - google.rpc.Code: NOT_FOUND = 5; - HTTP code: 404 Not Found + ErrorCode_FeatureDisabled ErrorCode = "FEATURE_DISABLED" + // The request does not have valid authentication (AuthN) credentials for the + // operation. + // + // For authentication (AuthN) errors prefer using UNAUTHENTICATED, unless you + // need to keep consistent behavior with legacy code. For authorization (AuthZ) + // errors use PERMISSION_DENIED. + // + // Important: name is confusing, this error code is for authentication (AuthN) + // errors, not authorization (AuthZ) errors. It maps to 401 Unauthorized and + // suffers from the same confusing naming. See + // https://datatracker.ietf.org/doc/html/rfc7235#section-3.1 - "[...] status + // code indicates that the request has not been applied because it lacks valid + // authentication credentials for the target resource. [...] If the request + // included authentication credentials, then the 401 response indicates that + // authorization has been refused for those credentials." + // + // Also, see https://stackoverflow.com/a/6937030/16352922, it covers it pretty + // well. + // + // Maps to: - google.rpc.Code: UNAUTHENTICATED = 16; - HTTP code: 401 + // Unauthorized + ErrorCode_CustomerUnauthorized ErrorCode = "CUSTOMER_UNAUTHORIZED" + // The operation is rejected because of request rate limit, for example rate + // limiting applied to users, workspaces, IP addresses, etc. + // + // Prefer a more generic RESOURCE_EXHAUSTED for the new use cases. + // + // See + // https://docs.google.com/document/d/1FL8p2sbYWqBPL-UvhzI7uXAw4EoLG7Rj6PAOQWZRSOk/edit# + // for guideline on the rate limiting vs throttling. + // + // Maps to: - google.rpc.Code: RESOURCE_EXHAUSTED = 8; - HTTP code: 429 Too Many + // Requests + ErrorCode_RequestLimitExceeded ErrorCode = "REQUEST_LIMIT_EXCEEDED" + // Indicates API request was rejected due a conflict with an existing resource. + ErrorCode_ResourceConflict ErrorCode = "RESOURCE_CONFLICT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Indicates that the HTTP response cannot be correctly + // deserialized. This currently is only used in DUST test clients, and not by + // any real service code. + ErrorCode_UnparseableHttpError ErrorCode = "UNPARSEABLE_HTTP_ERROR" + // The operation is not implemented or is not supported/enabled in this service. + // + // Maps to: - google.rpc.Code: UNIMPLEMENTED = 12; - HTTP code: 501 Not + // Implemented + ErrorCode_NotImplemented ErrorCode = "NOT_IMPLEMENTED" + // Unrecoverable data loss or corruption. + // + // One of the major use cases is to indicate that server failed to validate the + // integrity of the request. This error can occur when the checksum specified in + // the `X-Databricks-Checksum` request header (or trailer) doesn't match the + // actual request content checksum. + // + // Note, in case of the severe corruption that results in a malformed request, + // the server may send a generic `400 Bad Request` response rather than sending + // this error code. + // + // Maps to: - google.rpc.Code: DATA_LOSS = 15; - HTTP code: 500 Internal Server + // Error + ErrorCode_DataLoss ErrorCode = "DATA_LOSS" + // If the user attempts to perform an invalid state transition on a shard. + ErrorCode_InvalidStateTransition ErrorCode = "INVALID_STATE_TRANSITION" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Unable to perform the operation because the shard was + // locked by some other operation. + ErrorCode_CouldNotAcquireLock ErrorCode = "COULD_NOT_ACQUIRE_LOCK" + // NOTE: Deprecated, prefer using ALREADY_EXISTS. Unlike ALREADY_EXISTS - this + // maps to HTTP code 400 Bad Request due to legacy reasons, remapping will be a + // backwards incompatible change. + // + // Operation was performed on a resource that already exists. + ErrorCode_ResourceAlreadyExists ErrorCode = "RESOURCE_ALREADY_EXISTS" + // NOTE: Deprecated, prefer using NOT_FOUND - see the note for the + // RESOURCE_ALREADY_EXISTS, because this pair of codes is related and + // RESOURCE_ALREADY_EXISTS has bad mapping to the HTTP codes we added new error + // codes NOT_FOUND and ALREADY_EXISTS, and recommend to use them instead. + // + // Operation was performed on a resource that does not exist. + ErrorCode_ResourceDoesNotExist ErrorCode = "RESOURCE_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_QuotaExceeded ErrorCode = "QUOTA_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxBlockSizeExceeded ErrorCode = "MAX_BLOCK_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxReadSizeExceeded ErrorCode = "MAX_READ_SIZE_EXCEEDED" + ErrorCode_PartialDelete ErrorCode = "PARTIAL_DELETE" + ErrorCode_MaxListSizeExceeded ErrorCode = "MAX_LIST_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DryRunFailed ErrorCode = "DRY_RUN_FAILED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. Cluster request was rejected because it would exceed a + // resource limit. + ErrorCode_ResourceLimitExceeded ErrorCode = "RESOURCE_LIMIT_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DirectoryNotEmpty ErrorCode = "DIRECTORY_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DirectoryProtected ErrorCode = "DIRECTORY_PROTECTED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MaxNotebookSizeExceeded ErrorCode = "MAX_NOTEBOOK_SIZE_EXCEEDED" + ErrorCode_MaxChildNodeSizeExceeded ErrorCode = "MAX_CHILD_NODE_SIZE_EXCEEDED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SearchQueryTooLong ErrorCode = "SEARCH_QUERY_TOO_LONG" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SearchQueryTooShort ErrorCode = "SEARCH_QUERY_TOO_SHORT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ManagedResourceGroupDoesNotExist ErrorCode = "MANAGED_RESOURCE_GROUP_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_PermissionNotPropagated ErrorCode = "PERMISSION_NOT_PROPAGATED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DeploymentTimeout ErrorCode = "DEPLOYMENT_TIMEOUT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitConflict ErrorCode = "GIT_CONFLICT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitUnknownRef ErrorCode = "GIT_UNKNOWN_REF" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitSensitiveTokenDetected ErrorCode = "GIT_SENSITIVE_TOKEN_DETECTED" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitUrlNotOnAllowList ErrorCode = "GIT_URL_NOT_ON_ALLOW_LIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_GitRemoteError ErrorCode = "GIT_REMOTE_ERROR" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProjectsOperationTimeout ErrorCode = "PROJECTS_OPERATION_TIMEOUT" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_IpynbFileInRepo ErrorCode = "IPYNB_FILE_IN_REPO" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_InsecurePartnerResponse ErrorCode = "INSECURE_PARTNER_RESPONSE" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MalformedPartnerResponse ErrorCode = "MALFORMED_PARTNER_RESPONSE" + ErrorCode_MetastoreDoesNotExist ErrorCode = "METASTORE_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DacDoesNotExist ErrorCode = "DAC_DOES_NOT_EXIST" + ErrorCode_CatalogDoesNotExist ErrorCode = "CATALOG_DOES_NOT_EXIST" + ErrorCode_SchemaDoesNotExist ErrorCode = "SCHEMA_DOES_NOT_EXIST" + ErrorCode_TableDoesNotExist ErrorCode = "TABLE_DOES_NOT_EXIST" + ErrorCode_ShareDoesNotExist ErrorCode = "SHARE_DOES_NOT_EXIST" + ErrorCode_RecipientDoesNotExist ErrorCode = "RECIPIENT_DOES_NOT_EXIST" + ErrorCode_StorageCredentialDoesNotExist ErrorCode = "STORAGE_CREDENTIAL_DOES_NOT_EXIST" + ErrorCode_ExternalLocationDoesNotExist ErrorCode = "EXTERNAL_LOCATION_DOES_NOT_EXIST" + ErrorCode_PrincipalDoesNotExist ErrorCode = "PRINCIPAL_DOES_NOT_EXIST" + ErrorCode_ProviderDoesNotExist ErrorCode = "PROVIDER_DOES_NOT_EXIST" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MetastoreAlreadyExists ErrorCode = "METASTORE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_DacAlreadyExists ErrorCode = "DAC_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_CatalogAlreadyExists ErrorCode = "CATALOG_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SchemaAlreadyExists ErrorCode = "SCHEMA_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_TableAlreadyExists ErrorCode = "TABLE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ShareAlreadyExists ErrorCode = "SHARE_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_RecipientAlreadyExists ErrorCode = "RECIPIENT_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_StorageCredentialAlreadyExists ErrorCode = "STORAGE_CREDENTIAL_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ExternalLocationAlreadyExists ErrorCode = "EXTERNAL_LOCATION_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProviderAlreadyExists ErrorCode = "PROVIDER_ALREADY_EXISTS" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_CatalogNotEmpty ErrorCode = "CATALOG_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_SchemaNotEmpty ErrorCode = "SCHEMA_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_MetastoreNotEmpty ErrorCode = "METASTORE_NOT_EMPTY" + // NOTE: Deprecated and kept to maintain backwards compatibility for public APIs + // that use it, avoid using it in the new APIs, refer error codes listed in the + // http://go/error-codes. + ErrorCode_ProviderShareNotAccessible ErrorCode = "PROVIDER_SHARE_NOT_ACCESSIBLE" +) + +// Controls how the Data API exposes the OpenAPI documentation endpoint. Only +// IGNORE_PRIVILEGES and DISABLED are supported today; "follow-privileges" is +// not implemented yet (it may be added later as value 3 — adding new enum +// values is backward-compatible). +type OpenApiMode string + +const ( + OpenApiMode_Unspecified OpenApiMode = "" + // Generate OpenAPI output ignoring the privileges of the requesting role. + OpenApiMode_OpenApiModeIgnorePrivileges OpenApiMode = "OPEN_API_MODE_IGNORE_PRIVILEGES" + // Disable the OpenAPI documentation endpoint entirely. + OpenApiMode_OpenApiModeDisabled OpenApiMode = "OPEN_API_MODE_DISABLED" +) + +// The current phase of the data synchronization pipeline. +type ProvisioningPhase string + +const ( + ProvisioningPhase_Unspecified ProvisioningPhase = "" + // Ingestion phase of the synced table. This is when the synced table is + // ingesting data from the delta table. + ProvisioningPhase_ProvisioningPhaseMain ProvisioningPhase = "PROVISIONING_PHASE_MAIN" + // Index scan phase of the synced table. This is when the synced table is + // creating indexes on the ingested data. + ProvisioningPhase_ProvisioningPhaseIndexScan ProvisioningPhase = "PROVISIONING_PHASE_INDEX_SCAN" + // Index sort phase of the synced table. This is when the synced table is + // creating indexes on the ingested data. + ProvisioningPhase_ProvisioningPhaseIndexSort ProvisioningPhase = "PROVISIONING_PHASE_INDEX_SORT" +) + +// The state of a synced table. +type SyncedTableState string + +const ( + SyncedTableState_Unspecified SyncedTableState = "" + // The synced table has just been created and resources are being provisioned. + // This is also the catch-all state if there is not a more suitable state to + // report for the synced table. + SyncedTableState_SyncedTableProvisioning SyncedTableState = "SYNCED_TABLE_PROVISIONING" + // The synced table is provisioning resources for the data synchronization + // pipeline. + SyncedTableState_SyncedTableProvisioningPipelineResources SyncedTableState = "SYNCED_TABLE_PROVISIONING_PIPELINE_RESOURCES" + // The synced table is executing the initial data synchronization. + SyncedTableState_SyncedTableProvisioningInitialSnapshot SyncedTableState = "SYNCED_TABLE_PROVISIONING_INITIAL_SNAPSHOT" + // The synced table is ready to serve data. + SyncedTableState_SyncedTableOnline SyncedTableState = "SYNCED_TABLE_ONLINE" + // The synced table is ready to serve data and is continuously updating. Only + // shown for synced tables using the "Continuous" sync mode. + SyncedTableState_SyncedTableOnlineContinuousUpdate SyncedTableState = "SYNCED_TABLE_ONLINE_CONTINUOUS_UPDATE" + // The synced table is ready to serve data and an active update is in progress. + // Only shown for synced tables using the "Triggered" sync mode. + SyncedTableState_SyncedTableOnlineTriggeredUpdate SyncedTableState = "SYNCED_TABLE_ONLINE_TRIGGERED_UPDATE" + // The synced table is ready to serve data and there are no active updates. Only + // shown for synced tables using the "Triggered" sync mode. + SyncedTableState_SyncedTableOnlineNoPendingUpdate SyncedTableState = "SYNCED_TABLE_ONLINE_NO_PENDING_UPDATE" + // The synced table has encountered an internal error and is not available for + // serving. + SyncedTableState_SyncedTableOffline SyncedTableState = "SYNCED_TABLE_OFFLINE" + // The synced table is not available for serving because the data + // synchronization pipeline has failed. Please review the pipeline event logs to + // troubleshoot. + SyncedTableState_SyncedTableOfflineFailed SyncedTableState = "SYNCED_TABLE_OFFLINE_FAILED" + // The data synchronization pipeline has encountered an error but the synced + // table is still available for serving (potentially stale) data. Please review + // the pipeline event logs to troubleshoot. + SyncedTableState_SyncedTableOnlinePipelineFailed SyncedTableState = "SYNCED_TABLE_ONLINE_PIPELINE_FAILED" + // The synced table is available for serving, and is provisioning resources for + // a newly started data synchronization pipeline. + SyncedTableState_SyncedTableOnlineUpdatingPipelineResources SyncedTableState = "SYNCED_TABLE_ONLINE_UPDATING_PIPELINE_RESOURCES" +) + +// The state of the branch. +type BranchStatus_State string + +const ( + BranchStatus_State_Unspecified BranchStatus_State = "" + // The branch is being created but is not yet available for querying. + BranchStatus_State_Init BranchStatus_State = "INIT" + // The branch is being imported and is not yet available for querying. + BranchStatus_State_Importing BranchStatus_State = "IMPORTING" + // The branch is being reset to a specific point in time or LSN and is not yet + // available for querying. + BranchStatus_State_Resetting BranchStatus_State = "RESETTING" + // The branch is fully operational and ready for querying. + BranchStatus_State_Ready BranchStatus_State = "READY" + // The branch is stored in cost-effective archival storage. Expect slow query + // response times. + BranchStatus_State_Archived BranchStatus_State = "ARCHIVED" + // The branch is deleted and is not available for querying, but can be + // undeleted. + BranchStatus_State_Deleted BranchStatus_State = "DELETED" +) + +// The state of the compute endpoint. +type EndpointStatus_State string + +const ( + EndpointStatus_State_Unspecified EndpointStatus_State = "" + EndpointStatus_State_Init EndpointStatus_State = "INIT" + EndpointStatus_State_Active EndpointStatus_State = "ACTIVE" + EndpointStatus_State_Idle EndpointStatus_State = "IDLE" + EndpointStatus_State_Degraded EndpointStatus_State = "DEGRADED" +) + +// Release channel of the underlying pipeline's runtime. PREVIEW provides early +// access to the latest features but may be less stable. Some source table +// configurations (e.g., read-time CDF) require PREVIEW. Defaults to CURRENT if +// not specified. +type NewPipelineSpec_PipelineChannel string + +const ( + NewPipelineSpec_PipelineChannel_Unspecified NewPipelineSpec_PipelineChannel = "" + // Uses the stable, generally available runtime. + NewPipelineSpec_PipelineChannel_Current NewPipelineSpec_PipelineChannel = "CURRENT" + // Uses the latest preview runtime. Required for Auto CDF (read-time CDF) + // sources. + NewPipelineSpec_PipelineChannel_Preview NewPipelineSpec_PipelineChannel = "PREVIEW" +) + +type ProvisioningInfo_State string + +const ( + ProvisioningInfo_State_Unspecified ProvisioningInfo_State = "" + ProvisioningInfo_State_Provisioning ProvisioningInfo_State = "PROVISIONING" + ProvisioningInfo_State_Active ProvisioningInfo_State = "ACTIVE" + ProvisioningInfo_State_Failed ProvisioningInfo_State = "FAILED" + ProvisioningInfo_State_Deleting ProvisioningInfo_State = "DELETING" + ProvisioningInfo_State_Updating ProvisioningInfo_State = "UPDATING" + ProvisioningInfo_State_Degraded ProvisioningInfo_State = "DEGRADED" +) + +type RequestedClaims_PermissionSet string + +const ( + RequestedClaims_PermissionSet_Unspecified RequestedClaims_PermissionSet = "" + RequestedClaims_PermissionSet_ReadOnly RequestedClaims_PermissionSet = "READ_ONLY" +) + +// How the role is authenticated when connecting to Postgres. +type Role_AuthMethod string + +const ( + Role_AuthMethod_Unspecified Role_AuthMethod = "" + // NO_LOGIN means this role cannot be used for interactive access + Role_AuthMethod_NoLogin Role_AuthMethod = "NO_LOGIN" + // PG_PASSWORD_SCRAM_SHA_256 is a password-based authentication + Role_AuthMethod_PgPasswordScramSha256 Role_AuthMethod = "PG_PASSWORD_SCRAM_SHA_256" + // LAKEBASE_OAUTH_V1 is for logging in with the managed identities like the + // service principal, Group or user. + Role_AuthMethod_LakebaseOauthV1 Role_AuthMethod = "LAKEBASE_OAUTH_V1" +) + +// The type of the managed identity that this Role represents. +// Leave empty if you wish to create a regular Postgres role not associated with +// a identity. +type Role_IdentityType string + +const ( + Role_IdentityType_Unspecified Role_IdentityType = "" + // A user in a workspace. + Role_IdentityType_User Role_IdentityType = "USER" + // A service principal in a workspace. + Role_IdentityType_ServicePrincipal Role_IdentityType = "SERVICE_PRINCIPAL" + // A group in a workspace. + Role_IdentityType_Group Role_IdentityType = "GROUP" +) + +// Roles that the DatabaseInstanceRole can be a member of. +type Role_MembershipRole string + +const ( + Role_MembershipRole_Unspecified Role_MembershipRole = "" + // Indicates membership in DATABRICKS_SUPERUSER, the highest set of privileges + // exposed to customers. + Role_MembershipRole_DatabricksSuperuser Role_MembershipRole = "DATABRICKS_SUPERUSER" +) + +// How the column's value is populated and kept up to date. +type SyncedTable_SyncedTableSpec_ExtraColumn_Maintenance string + +const ( + SyncedTable_SyncedTableSpec_ExtraColumn_Maintenance_Unspecified SyncedTable_SyncedTableSpec_ExtraColumn_Maintenance = "" + // The value is computed by PostgreSQL and stored. + SyncedTable_SyncedTableSpec_ExtraColumn_Maintenance_StoredGenerated SyncedTable_SyncedTableSpec_ExtraColumn_Maintenance = "STORED_GENERATED" +) + +// PostgreSQL-specific target types that can override the default Delta-to-PG +// mapping. +type SyncedTable_SyncedTableSpec_PgSpecificType string + +const ( + SyncedTable_SyncedTableSpec_PgSpecificType_Unspecified SyncedTable_SyncedTableSpec_PgSpecificType = "" + // Maps the column to the pgvector vector type. + SyncedTable_SyncedTableSpec_PgSpecificType_PgSpecificTypeVector SyncedTable_SyncedTableSpec_PgSpecificType = "PG_SPECIFIC_TYPE_VECTOR" + // Maps the column to the pgvector half-precision halfvec type. + SyncedTable_SyncedTableSpec_PgSpecificType_PgSpecificTypeHalfvec SyncedTable_SyncedTableSpec_PgSpecificType = "PG_SPECIFIC_TYPE_HALFVEC" + // Maps the column to a length-bounded character varying(N) type. + SyncedTable_SyncedTableSpec_PgSpecificType_PgSpecificTypeVarchar SyncedTable_SyncedTableSpec_PgSpecificType = "PG_SPECIFIC_TYPE_VARCHAR" +) + +// Scheduling policy of the synced table's underlying pipeline. +type SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy string + +const ( + SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy_Unspecified SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy = "" + // Pipeline runs continuously after generating the initial data. Requires the + // source table to have Change Data Feed (CDF) enabled. + SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy_Continuous SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy = "CONTINUOUS" + // Pipeline stops after generating the initial data and can be triggered later + // (manually, through a cron job or through data triggers). Requires the source + // table to have Change Data Feed (CDF) enabled. + SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy_Triggered SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy = "TRIGGERED" + // Pipeline stops after generating the initial data and can be triggered later + // (manually, through a cron job or through data triggers). Successive updates + // always perform a full copy of the source table data (no incremental updates). + // Does not require the source table to have Change Data Feed (CDF) enabled. + SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy_Snapshot SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy = "SNAPSHOT" +) + +// Databricks Error that is returned by all Databricks APIs.. +type ApiError struct { + ErrorCode ErrorCode + Message *string + StackTrace *string + Details []json.RawMessage +} + +type Branch struct { + // Output only. The full resource path of the branch. Format: + // projects/{project_id}/branches/{branch_id} + Name *string `fieldmask:"name"` + // System-generated unique ID for the branch. + Uid *string `fieldmask:"uid"` + // The project containing this branch (API resource hierarchy). Format: + // projects/{project_id} + // + // Note: This field indicates where the branch exists in the resource hierarchy. + // For point-in-time branching from another branch, see `status.source_branch`. + Parent *string `fieldmask:"parent"` + // A timestamp indicating when the branch was created. + CreateTime *types.Time `fieldmask:"create_time"` + // A timestamp indicating when the branch was last updated. + UpdateTime *types.Time `fieldmask:"update_time"` + // The spec contains the branch configuration. + Spec *BranchSpec `fieldmask:"spec"` + // The current status of a Branch. + Status *BranchStatus `fieldmask:"status"` + // The part of the name, chosen by the user when the resource was created. + BranchId *string `fieldmask:"branch_id"` +} + +type BranchOperationMetadata struct { +} + +type BranchSpec struct { + // The name of the source branch from which this branch was created (data + // lineage for point-in-time recovery). If not specified, defaults to the + // project's default branch. Format: projects/{project_id}/branches/{branch_id} + SourceBranch *string `fieldmask:"source_branch"` + // The Log Sequence Number (LSN) on the source branch from which this branch was + // created. + SourceBranchLsn *string `fieldmask:"source_branch_lsn"` + // The point in time on the source branch from which this branch was created. + SourceBranchTime *types.Time `fieldmask:"source_branch_time"` + // When set to true, protects the branch from deletion and reset. Associated + // compute endpoints and the project cannot be deleted while the branch is + // protected. + IsProtected *bool `fieldmask:"is_protected"` + // Expiration configuration for the branch. One of expire_time, ttl, or + // no_expiry must be provided. To disable expiration, set no_expiry to true. + // + // When updating this field, use "spec.expiration" in the update_mask. + Expiration isBranchSpec_Expiration + _ [0]branchSpecExpirationFieldMaskMetadata `fieldmask_oneof:"Expiration"` +} + +type isBranchSpec_Expiration interface { + isBranchSpec_Expiration() +} + +// BranchSpec_Expiration_ExpireTime selects ExpireTime for BranchSpec.Expiration. +// Absolute expiration timestamp. When set, the branch will expire at this time. +// Mutually exclusive with `ttl` and `no_expiry`. When updating, use +// `spec.expiration` in the update_mask. +type BranchSpec_Expiration_ExpireTime struct { + ExpireTime types.Time `fieldmask:"expire_time"` +} + +func (*BranchSpec_Expiration_ExpireTime) isBranchSpec_Expiration() {} + +// BranchSpec_Expiration_Ttl selects Ttl for BranchSpec.Expiration. +// Relative time-to-live duration. When set, the branch will expire at +// creation_time + ttl. Mutually exclusive with `expire_time` and `no_expiry`. +// When updating, use `spec.expiration` in the update_mask. +type BranchSpec_Expiration_Ttl struct { + Ttl types.Duration `fieldmask:"ttl"` +} + +func (*BranchSpec_Expiration_Ttl) isBranchSpec_Expiration() {} + +// BranchSpec_Expiration_NoExpiry selects NoExpiry for BranchSpec.Expiration. +// Explicitly disable expiration. When set to true, the branch will not expire. +// If set to false, the request is invalid; provide either ttl or expire_time +// instead. Mutually exclusive with `expire_time` and `ttl`. When updating, use +// `spec.expiration` in the update_mask. +type BranchSpec_Expiration_NoExpiry struct { + NoExpiry bool `fieldmask:"no_expiry"` +} + +func (*BranchSpec_Expiration_NoExpiry) isBranchSpec_Expiration() {} + +type branchSpecExpirationFieldMaskMetadata struct { + *BranchSpec_Expiration_ExpireTime + *BranchSpec_Expiration_Ttl + *BranchSpec_Expiration_NoExpiry +} + +type BranchStatus struct { + // The name of the source branch from which this branch was created. Format: + // projects/{project_id}/branches/{branch_id} + SourceBranch *string `fieldmask:"source_branch"` + // The Log Sequence Number (LSN) on the source branch from which this branch was + // created. + SourceBranchLsn *string `fieldmask:"source_branch_lsn"` + // The point in time on the source branch from which this branch was created. + SourceBranchTime *types.Time `fieldmask:"source_branch_time"` + // Whether the branch is the project's default branch. + Default *bool `fieldmask:"default"` + // Whether the branch is protected. + IsProtected *bool `fieldmask:"is_protected"` + // The branch's state, indicating if it is initializing, ready for use, or + // archived. + CurrentState BranchStatus_State `fieldmask:"current_state"` + // The pending state of the branch, if a state transition is in progress. + PendingState BranchStatus_State `fieldmask:"pending_state"` + // A timestamp indicating when the `current_state` began. + StateChangeTime *types.Time `fieldmask:"state_change_time"` + // The logical size of the branch. + LogicalSizeBytes *int64 `fieldmask:"logical_size_bytes"` + // Absolute expiration time for the branch. Empty if expiration is disabled. + ExpireTime *types.Time `fieldmask:"expire_time"` + // Part of the resource name. + BranchId *string `fieldmask:"branch_id"` + // A timestamp indicating when the branch was deleted. Empty if the branch is + // not deleted. + DeleteTime *types.Time `fieldmask:"delete_time"` + // A timestamp indicating when the branch is scheduled to be purged. Empty if + // the branch is not deleted, otherwise set to a timestamp in the future. + PurgeTime *types.Time `fieldmask:"purge_time"` +} + +type Catalog struct { + // Output only. The full resource path of the catalog. + // + // Format: "catalogs/{catalog_id}". + Name *string + // System-generated unique identifier for the catalog. + Uid *string + // The desired state of the Catalog. + Spec *Catalog_CatalogSpec + // The observed state of the Catalog. + Status *Catalog_CatalogStatus + // A timestamp indicating when the catalog was created. + CreateTime *types.Time + // A timestamp indicating when the catalog was last updated. + UpdateTime *types.Time + // The part of the name, chosen by the user when the resource was created. + CatalogId *string +} + +// The desired state of the Catalog.. +type Catalog_CatalogSpec struct { + // The name of the Postgres database inside the specified Lakebase project and + // branch to be associated with the UC catalog. This database must already + // exist, unless create_database_if_missing is set to true on creation. + // + // A database can only be registered with one UC catalog at a time. To + // re-register a database with a different catalog, the existing catalog must be + // deleted first. + // + // A child branch inherits the fact of parent's registration. This means the + // same-named database in a child branch cannot be registered with a second + // catalog while the parent's registration exists. To allow registering the + // database of a child branch, drop and recreate the database on the child + // branch. This removes the fact of parent's registration from this branch only. + // + // Doing Point In Time Restore (PITR) prior to the moment before the Postgres DB + // was registered in the Catalog drops the fact of registration of the database. + // So the user should avoid doing so. + PostgresDatabase *string + // If set to true, the specified postgres_database is created on behalf of the + // calling user if it does not already exist. In this case, the calling user has + // a role created for them in Postgres if they do not already have one. + // + // Defaults to false, meaning that the request fails if the specified + // postgres_database does not already exist. + CreateDatabaseIfMissing *bool + // The resource path of the branch associated with the catalog. + // + // Format: projects/{project_id}/branches/{branch_id}. + Branch *string +} + +// The observed state of the Catalog.. +type Catalog_CatalogStatus struct { + // The name of the Postgres database associated with the catalog. + PostgresDatabase *string + // The resource path of the project associated with the catalog. + // + // Format: projects/{project_id}. + Project *string + // The resource path of the branch associated with the catalog. + // + // Format: projects/{project_id}/branches/{branch_id}. + Branch *string +} + +type CatalogOperationMetadata struct { +} + +// A Lakebase CDF configuration (CdfConfig): one per Postgres schema per +// database, replicating that schema's tables into a Unity Catalog schema. +// Immutable once created.. +type CdfConfig struct { + // Output only. The full resource name of the CdfConfig. Format: + // projects/{project}/branches/{branch}/databases/{database}/cdf-configs/{cdf_config} + Name *string + // The Unity Catalog catalog that replicated tables are written into. Set at + // creation; the CdfConfig is immutable. + Catalog *string + // The Unity Catalog schema that replicated tables are written into. Set at + // creation; the CdfConfig is immutable. + Schema *string + // When the CdfConfig was created. + CreateTime *types.Time + // The user-specified id; equals the final segment of `name`. Defaults to the + // Postgres schema name for configs without an explicit id. + CdfConfigId *string + // The Postgres schema this CdfConfig replicates from. Unique within the parent + // database. Set at creation; the CdfConfig is immutable. + PostgresSchema *string +} + +// Metadata for CdfConfig long-running operations. Intentionally empty today; +// fields (e.g. progress) may be added as the operation contract grows.. +type CdfConfigOperationMetadata struct { +} + +// The read-only replication status of a single Postgres table replicated under +// a CdfConfig. One status exists per replicated table. It is created +// automatically and cannot be modified.. +type CdfStatus struct { + // Output only. The full resource name of the CdfStatus. Format: + // projects/{project}/branches/{branch}/databases/{database}/cdf-configs/{cdf_config}/cdf-statuses/{cdf_status} + // The {cdf_status} segment is the Postgres table name. + Name *string + // The Postgres table being replicated. + PostgresTable *string + // The Unity Catalog table receiving replicated data. + UcTable *string + // The current replication state of this table. + State CdfState + // The high-watermark Log Sequence Number (LSN) committed to Delta Lake. + CommittedLsn *string + // The last time changes for this table were written to Delta Lake. + LastSyncTime *types.Time + // When replication for this table was first established. + CreateTime *types.Time + // Human-readable detail for the current state (e.g. the skip/error reason). + // Empty for healthy states. + StatusDetail *string +} + +type CreateBranchRequest struct { + // The Project where this Branch will be created. Format: projects/{project_id} + Parent *string + // The ID to use for the Branch. This becomes the final component of the + // branch's resource name. The ID is required and must be 1-63 characters long, + // start with a lowercase letter, and contain only lowercase letters, numbers, + // and hyphens. For example, `development` becomes + // `projects/my-app/branches/development`. + BranchId *string + // The Branch to create. + Branch *Branch + // If true, update the branch if it already exists instead of returning an + // error. + ReplaceExisting *bool +} + +type CreateCatalogRequest struct { + // The ID in the Unity Catalog. It becomes the full resource name, for example + // "my_catalog" becomes "catalogs/my_catalog". + CatalogId *string + Catalog *Catalog +} + +// Request to create a Lakebase CDF configuration (CdfConfig).. +type CreateCdfConfigRequest struct { + // The parent database under which to create the CdfConfig. Format: + // projects/{project}/branches/{branch}/databases/{database} + Parent *string + // The CdfConfig to create. The catalog, schema, and postgres_schema fields are + // required; all other fields are output only and ignored on input. + CdfConfig *CdfConfig + // The user-specified id for the CdfConfig, forming the final segment of its + // resource name. Must match the pattern `[a-z][a-z0-9_]{0,62}`. Defaults to the + // Postgres schema name when omitted. + CdfConfigId *string +} + +// Enable Data API for a database.. +type CreateDataApiRequest struct { + // Parent database: + // projects/{project_id}/branches/{branch_id}/databases/{database_id} + Parent *string + // The Data API configuration to create. + DataApi *DataApi +} + +type CreateDatabaseRequest struct { + // The Branch where this Database will be created. Format: + // projects/{project_id}/branches/{branch_id} + Parent *string + // The ID to use for the Database, which will become the final component of the + // database's resource name. This ID becomes the database name in postgres. + // + // This value should be 4-63 characters, and only use characters available in + // DNS names, as defined by RFC-1123 + // + // If database_id is not specified in the request, it is generated + // automatically. + DatabaseId *string + // The desired specification of a Database. + Database *Database + // If true, update the database if it already exists instead of returning an + // error. + ReplaceExisting *bool +} + +type CreateEndpointRequest struct { + // The Branch where this Endpoint will be created. Format: + // projects/{project_id}/branches/{branch_id} + Parent *string + // The ID to use for the Endpoint. This becomes the final component of the + // endpoint's resource name. The ID is required and must be 1-63 characters + // long, start with a lowercase letter, and contain only lowercase letters, + // numbers, and hyphens. For example, `primary` becomes + // `projects/my-app/branches/development/endpoints/primary`. + EndpointId *string + // The Endpoint to create. + Endpoint *Endpoint + // If true, update the endpoint if it already exists instead of returning an + // error. + ReplaceExisting *bool +} + +type CreateProjectRequest struct { + // The ID to use for the Project. This becomes the final component of the + // project's resource name. The ID is required and must be 1-63 characters long, + // start with a lowercase letter, and contain only lowercase letters, numbers, + // and hyphens. For example, `my-app` becomes `projects/my-app`. + ProjectId *string + // The Project to create. + Project *Project +} + +type CreateRoleRequest struct { + // The Branch where this Role is created. Format: + // projects/{project_id}/branches/{branch_id} + Parent *string + // The ID to use for the Role, which will become the final component of the + // role's resource name. This ID becomes the role in Postgres. + // + // This value should be 4-63 characters, and valid characters are lowercase + // letters, numbers, and hyphens, as defined by RFC 1123. + // + // If role_id is not specified in the request, it is generated automatically. + RoleId *string + // The desired specification of a Role. + Role *Role + // If true, update the role if it already exists instead of returning an error. + // + // When the role already exists, the provided `role` spec fully replaces the + // existing one: `membership_roles` is overwritten, not merged. Leaving + // `membership_roles` empty clears all of the role's existing memberships, + // including `DATABRICKS_SUPERUSER`. Always send the complete desired list of + // memberships when using this field. + ReplaceExisting *bool +} + +// Establish a synchronisation to the Postgres database for Reverse ETL for the +// source table selected from the Unity Catalog.. +type CreateSyncedTableRequest struct { + // The ID to use for the Synced Table. This becomes the final component of the + // SyncedTable's resource name. ID is required and is the synced table name, + // containing (catalog, schema, table) tuple. Elements of the tuple are the UC + // entity names. + // + // Example: "{catalog}.{schema}.{table}" + // + // synced_table_id represents both of the following: + // + // 1. An online VIEW virtual table in the Unity Catalog accessible via the + // Lakehouse Federation. 2. Postgres table named "{table}" in schema "{schema}" + // in the connected Postgres database + SyncedTableId *string + SyncedTable *SyncedTable +} + +// DataApi represents the Data API (PostgREST) configuration for a Database. At +// most one DataApi per database. Create enables Data API, Delete disables it.. +type DataApi struct { + // Resource name: + // projects/{project_id}/branches/{branch_id}/databases/{database_id}/data-api + Name *string `fieldmask:"name"` + // The database containing this Data API configuration. Format: + // projects/{project_id}/branches/{branch_id}/databases/{database_id} + Parent *string `fieldmask:"parent"` + // A timestamp indicating when the Data API was first enabled. + CreateTime *types.Time `fieldmask:"create_time"` + // A timestamp indicating when the Data API configuration was last updated. + UpdateTime *types.Time `fieldmask:"update_time"` + // The desired Data API configuration. + Spec *DataApi_DataApiSpec `fieldmask:"spec"` + // The observed Data API state (read-only). + Status *DataApi_DataApiStatus `fieldmask:"status"` +} + +// Desired PostgREST configuration (input).. +type DataApi_DataApiSpec struct { + // Enable aggregate functions (count, sum, avg, etc.) in Data API responses. + // Default: true. + DbAggregatesEnabled *bool `fieldmask:"db_aggregates_enabled"` + // Additional schemas to include in the PostgreSQL search path. Each entry must + // be a valid PostgreSQL schema name. + DbExtraSearchPath []string `fieldmask:"db_extra_search_path"` + // Maximum number of rows returned in a single Data API response. Must be a + // positive integer. + DbMaxRows *int `fieldmask:"db_max_rows"` + // Database schemas exposed through the Data API. Each entry must be a valid + // PostgreSQL schema name (1-63 chars, [a-zA-Z_][a-zA-Z0-9_$]*). Maximum 100 + // entries. Default: ["public"]. + DbSchemas []string `fieldmask:"db_schemas"` + // JSON path to the role claim in JWT tokens (e.g., ".sub"). Default: ".sub". + JwtRoleClaimKey *string `fieldmask:"jwt_role_claim_key"` + // Maximum lifetime for cached JWT tokens. Zero duration disables caching. + JwtCacheMaxLifetime *types.Duration `fieldmask:"jwt_cache_max_lifetime"` + // OpenAPI documentation mode for the Data API endpoint. + OpenapiMode OpenApiMode `fieldmask:"openapi_mode"` + // Allowed origins for CORS requests. Each entry should be a valid origin URL, + // or use "*" to allow all origins. + ServerCorsAllowedOrigins []string `fieldmask:"server_cors_allowed_origins"` + // Enable the Server-Timing header in Data API responses. + ServerTimingEnabled *bool `fieldmask:"server_timing_enabled"` +} + +// Observed state (output-only).. +type DataApi_DataApiStatus struct { + // Actual aggregate function setting read from the database. + DbAggregatesEnabled *bool `fieldmask:"db_aggregates_enabled"` + // Actual extra search path schemas read from the database. + DbExtraSearchPath []string `fieldmask:"db_extra_search_path"` + // Actual max rows setting read from the database. + DbMaxRows *int `fieldmask:"db_max_rows"` + // Actual exposed schemas read from the database. + DbSchemas []string `fieldmask:"db_schemas"` + // Actual JWT role claim key read from the database. + JwtRoleClaimKey *string `fieldmask:"jwt_role_claim_key"` + // Actual JWT cache max lifetime read from the database. + JwtCacheMaxLifetime *types.Duration `fieldmask:"jwt_cache_max_lifetime"` + // Actual OpenAPI mode read from the database. + OpenapiMode OpenApiMode `fieldmask:"openapi_mode"` + // Actual CORS allowed origins read from the database. + ServerCorsAllowedOrigins []string `fieldmask:"server_cors_allowed_origins"` + // Actual Server-Timing header setting read from the database. + ServerTimingEnabled *bool `fieldmask:"server_timing_enabled"` + // Data API endpoint URL. + Url *string `fieldmask:"url"` + // Schemas available in the database (for reference when configuring + // db_schemas). + AvailableSchemas []string `fieldmask:"available_schemas"` +} + +type DataApiOperationMetadata struct { +} + +// Database represents a Postgres database within a Branch.. +type Database struct { + // The resource name of the database. Format: + // projects/{project_id}/branches/{branch_id}/databases/{database_id} + Name *string `fieldmask:"name"` + // The branch containing this database. Format: + // projects/{project_id}/branches/{branch_id} + Parent *string `fieldmask:"parent"` + // A timestamp indicating when the database was created. + CreateTime *types.Time `fieldmask:"create_time"` + // A timestamp indicating when the database was last updated. + UpdateTime *types.Time `fieldmask:"update_time"` + // The desired state of the Database. + Spec *Database_DatabaseSpec `fieldmask:"spec"` + // The observed state of the Database. + Status *Database_DatabaseStatus `fieldmask:"status"` + // The part of the name, chosen by the user when the resource was created. + DatabaseId *string `fieldmask:"database_id"` +} + +type Database_DatabaseSpec struct { + // The name of the role that owns the database. Format: + // projects/{project_id}/branches/{branch_id}/roles/{role_id} + // + // To change the owner, pass valid existing Role name when updating the Database + // + // A database always has an owner. + Role *string `fieldmask:"role"` + // The name of the Postgres database. + // + // This expects a valid Postgres identifier as specified in the link below. + // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS + // Required when creating the Database. + // + // To rename, pass a valid postgres identifier when updating the Database. + PostgresDatabase *string `fieldmask:"postgres_database"` +} + +type Database_DatabaseStatus struct { + // The name of the role that owns the database. Format: + // projects/{project_id}/branches/{branch_id}/roles/{role_id} + Role *string `fieldmask:"role"` + // The name of the Postgres database. + PostgresDatabase *string `fieldmask:"postgres_database"` + // Part of the resource name. + DatabaseId *string `fieldmask:"database_id"` +} + +type DatabaseCredential struct { + // The OAuth token that can be used as a password when connecting to a database. + Token *string + // Timestamp in UTC of when this credential expires. + ExpireTime *types.Time +} + +type DatabaseOperationMetadata struct { +} + +type DeleteBranchRequest struct { + // The full resource path of the branch to delete. Format: + // projects/{project_id}/branches/{branch_id} + Name *string + // If true, permanently delete the branch; if false, soft delete. + Purge *bool +} + +type DeleteCatalogRequest struct { + // The full resource path of the catalog to delete. + // + // Format: "catalogs/{catalog_id}". + Name *string +} + +// Request to delete a Lakebase CDF configuration (CdfConfig).. +type DeleteCdfConfigRequest struct { + // The resource name of the CdfConfig to delete. Format: + // projects/{project}/branches/{branch}/databases/{database}/cdf-configs/{cdf_config} + Name *string + // When true, also drops the replicated Delta tables in Unity Catalog. When + // false (the default), the replicated tables are preserved at their last synced + // state. + Force *bool +} + +// Disable Data API for a database.. +type DeleteDataApiRequest struct { + // Resource name: + // projects/{project_id}/branches/{branch_id}/databases/{database_id}/data-api + Name *string +} + +type DeleteDatabaseRequest struct { + // The resource name of the postgres database. Format: + // projects/{project_id}/branches/{branch_id}/databases/{database_id} + Name *string +} + +type DeleteEndpointRequest struct { + // The full resource path of the endpoint to delete. Format: + // projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id} + Name *string +} + +type DeleteProjectRequest struct { + // The full resource path of the project to delete. Format: + // projects/{project_id} + Name *string + // If true, permanently deletes the project (hard delete). If false or unset, + // performs a soft delete. + Purge *bool +} + +type DeleteRoleRequest struct { + // The full resource path of the role to delete. Format: + // projects/{project_id}/branches/{branch_id}/roles/{role_id} + Name *string + // Reassign objects. If this is set, all objects owned by the role are + // reassigned to the role specified in this parameter. + // + // NOTE: setting this requires spinning up a compute to succeed, since it + // involves running SQL queries. + ReassignOwnedTo *string +} + +type DeleteSyncedTableRequest struct { + // The Full resource name of the synced table, of the format + // "synced_tables/{catalog}.{schema}.{table}", where (catalog, schema, table) + // are the UC entity names. + Name *string +} + +type DeltaTableSyncInfo struct { + // The Delta Lake commit version that was last successfully synced. + DeltaCommitVersion *int64 + // The timestamp when the above Delta version was committed in the source Delta + // table. Note: This is the Delta commit time, not the time the data was written + // to the synced table. + DeltaCommitTime *types.Time +} + +type Endpoint struct { + // Output only. The full resource path of the endpoint. Format: + // projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id} + Name *string `fieldmask:"name"` + // System-generated unique ID for the endpoint. + Uid *string `fieldmask:"uid"` + // The branch containing this endpoint (API resource hierarchy). Format: + // projects/{project_id}/branches/{branch_id} + Parent *string `fieldmask:"parent"` + // A timestamp indicating when the compute endpoint was created. + CreateTime *types.Time `fieldmask:"create_time"` + // A timestamp indicating when the compute endpoint was last updated. + UpdateTime *types.Time `fieldmask:"update_time"` + // The spec contains the compute endpoint configuration, including autoscaling + // limits, suspend timeout, and disabled state. + Spec *EndpointSpec `fieldmask:"spec"` + // Current operational status of the compute endpoint. + Status *EndpointStatus `fieldmask:"status"` + // The part of the name, chosen by the user when the resource was created. + EndpointId *string `fieldmask:"endpoint_id"` +} + +type EndpointGroupSpec struct { + // The minimum number of computes in the endpoint group. Currently, this must be + // equal to max. This must be greater than or equal to 1. + Min *int `fieldmask:"min"` + // The maximum number of computes in the endpoint group. Currently, this must be + // equal to min. Set to 1 for single compute endpoints, to disable HA. To + // manually suspend all computes in an endpoint group, set disabled to true on + // the EndpointSpec. + Max *int `fieldmask:"max"` + // Whether to allow read-only connections to read-write endpoints. Only relevant + // for read-write endpoints where size.max > 1. + EnableReadableSecondaries *bool `fieldmask:"enable_readable_secondaries"` +} + +type EndpointGroupStatus struct { + // The minimum number of computes in the endpoint group. Currently, this must be + // equal to max. This must be greater than or equal to 1. + Min *int `fieldmask:"min"` + // The maximum number of computes in the endpoint group. Currently, this must be + // equal to min. Set to 1 for single compute endpoints, to disable HA. To + // manually suspend all computes in an endpoint group, set disabled to true on + // the EndpointSpec. + Max *int `fieldmask:"max"` + // Whether read-only connections to read-write endpoints are allowed. Only + // relevant if read replicas are configured by specifying size.max > 1. + EnableReadableSecondaries *bool `fieldmask:"enable_readable_secondaries"` +} + +// Encapsulates various hostnames (r/w or r/o, pooled or not) for an endpoint.. +type EndpointHosts struct { + // The hostname to connect to this endpoint. For read-write endpoints, this is a + // read-write hostname which connects to the primary compute. For read-only + // endpoints, this is a read-only hostname which allows read-only operations. + Host *string `fieldmask:"host"` + // An optionally defined read-only host for the endpoint, without pooling. For + // read-only endpoints, this attribute is always defined and is equivalent to + // host. For read-write endpoints, this attribute is defined if the enclosing + // endpoint is a group with greater than 1 computes configured, and has readable + // secondaries enabled. + ReadOnlyHost *string `fieldmask:"read_only_host"` + // The read-write hostname of the compute endpoint, with pooling. This attribute + // is only defined for read-write endpoints. + ReadWritePooledHost *string `fieldmask:"read_write_pooled_host"` + // The read-only hostname of the compute endpoint, with pooling. This attribute + // is always defined for read-only endpoints, and may be defined for read-write + // endpoints if configured with read replicas and allow read-only connections. + ReadOnlyPooledHost *string `fieldmask:"read_only_pooled_host"` +} + +type EndpointOperationMetadata struct { +} + +// A collection of settings for a compute endpoint.. +type EndpointSettings struct { + // A raw representation of Postgres settings. + PgSettings map[string]string `fieldmask:"pg_settings"` +} + +type EndpointSpec struct { + // The endpoint type. A branch can only have one READ_WRITE endpoint. + EndpointType EndpointType `fieldmask:"endpoint_type"` + // The minimum number of Compute Units. Minimum value is 0.5. + AutoscalingLimitMinCu *float64 `fieldmask:"autoscaling_limit_min_cu"` + // The maximum number of Compute Units. The maximum value is 64. The difference + // between the minimum and maximum Compute Units (max - min) must not exceed 16. + AutoscalingLimitMaxCu *float64 `fieldmask:"autoscaling_limit_max_cu"` + // Whether to restrict connections to the compute endpoint. Enabling this option + // schedules a suspend compute operation. A disabled compute endpoint cannot be + // enabled by a connection or console action. + Disabled *bool `fieldmask:"disabled"` + // Duration of inactivity after which the compute endpoint is automatically + // suspended. One of suspend_timeout_duration or no_suspension can be provided. + // When not specified default suspension behavior will be used (consult with + // documentation). + // + // When updating this field, use "spec.suspension" in the update_mask. + Suspension isEndpointSpec_Suspension + Settings *EndpointSettings `fieldmask:"settings"` + // Settings for optional HA configuration of the endpoint. If unspecified, the + // endpoint defaults to non HA settings, with a single compute backing the + // endpoint (and no readable secondaries for Read/Write endpoints). + Group *EndpointGroupSpec `fieldmask:"group"` + _ [0]endpointSpecSuspensionFieldMaskMetadata `fieldmask_oneof:"Suspension"` +} + +type isEndpointSpec_Suspension interface { + isEndpointSpec_Suspension() +} + +// EndpointSpec_Suspension_SuspendTimeoutDuration selects SuspendTimeoutDuration for EndpointSpec.Suspension. +// Duration of inactivity after which the compute endpoint is automatically +// suspended. If specified should be between 60s and 604800s (1 minute to 1 +// week). Mutually exclusive with `no_suspension`. When updating, use +// `spec.suspension` in the update_mask. +type EndpointSpec_Suspension_SuspendTimeoutDuration struct { + SuspendTimeoutDuration types.Duration `fieldmask:"suspend_timeout_duration"` +} + +func (*EndpointSpec_Suspension_SuspendTimeoutDuration) isEndpointSpec_Suspension() {} + +// EndpointSpec_Suspension_NoSuspension selects NoSuspension for EndpointSpec.Suspension. +// When set to true, explicitly disables automatic suspension (never suspend). +// Should be set to true when provided. Mutually exclusive with +// `suspend_timeout_duration`. When updating, use `spec.suspension` in the +// update_mask. +type EndpointSpec_Suspension_NoSuspension struct { + NoSuspension bool `fieldmask:"no_suspension"` +} + +func (*EndpointSpec_Suspension_NoSuspension) isEndpointSpec_Suspension() {} + +type endpointSpecSuspensionFieldMaskMetadata struct { + *EndpointSpec_Suspension_SuspendTimeoutDuration + *EndpointSpec_Suspension_NoSuspension +} + +type EndpointStatus struct { + // The endpoint type. A branch can only have one READ_WRITE endpoint. + EndpointType EndpointType `fieldmask:"endpoint_type"` + // Contains host information for connecting to the endpoint. + Hosts *EndpointHosts `fieldmask:"hosts"` + // A timestamp indicating when the compute endpoint was last active. + LastActiveTime *types.Time `fieldmask:"last_active_time"` + // The minimum number of Compute Units. + AutoscalingLimitMinCu *float64 `fieldmask:"autoscaling_limit_min_cu"` + // The maximum number of Compute Units. The maximum value is 64. The difference + // between the minimum and maximum Compute Units (max - min) must not exceed 16. + AutoscalingLimitMaxCu *float64 `fieldmask:"autoscaling_limit_max_cu"` + CurrentState EndpointStatus_State `fieldmask:"current_state"` + PendingState EndpointStatus_State `fieldmask:"pending_state"` + // Whether to restrict connections to the compute endpoint. Enabling this option + // schedules a suspend compute operation. A disabled compute endpoint cannot be + // enabled by a connection or console action. + Disabled *bool `fieldmask:"disabled"` + // Duration of inactivity after which the compute endpoint is automatically + // suspended. + SuspendTimeoutDuration *types.Duration `fieldmask:"suspend_timeout_duration"` + Settings *EndpointSettings `fieldmask:"settings"` + // Details on the HA configuration of the endpoint. + Group *EndpointGroupStatus `fieldmask:"group"` + // Part of the resource name. + EndpointId *string `fieldmask:"endpoint_id"` +} + +type GenerateDatabaseCredentialRequest struct { + // The returned token will be scoped to UC tables with the specified + // permissions. + Claims []RequestedClaims + // The endpoint resource name for which this credential will be generated. + // Format: projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id} + Endpoint *string + // Expiration information for the credential. Users can specify either + // expire_time or ttl. If unspecified, maximum allowed duration (1 hour) is + // used. + Expiration isGenerateDatabaseCredentialRequest_Expiration +} + +type isGenerateDatabaseCredentialRequest_Expiration interface { + isGenerateDatabaseCredentialRequest_Expiration() +} + +// GenerateDatabaseCredentialRequest_Expiration_Ttl selects Ttl for GenerateDatabaseCredentialRequest.Expiration. +// The requested time-to-live for the generated credential token. Must be at +// least 300 seconds (5 minutes) and at most 3600 seconds (1 hour). +type GenerateDatabaseCredentialRequest_Expiration_Ttl struct { + Ttl types.Duration +} + +func (*GenerateDatabaseCredentialRequest_Expiration_Ttl) isGenerateDatabaseCredentialRequest_Expiration() { +} + +// GenerateDatabaseCredentialRequest_Expiration_ExpireTime selects ExpireTime for GenerateDatabaseCredentialRequest.Expiration. +// Timestamp in UTC of when this credential should expire. Must be at least 300 +// seconds (5 minutes) and at most 1 hour from the current time. +type GenerateDatabaseCredentialRequest_Expiration_ExpireTime struct { + ExpireTime types.Time +} + +func (*GenerateDatabaseCredentialRequest_Expiration_ExpireTime) isGenerateDatabaseCredentialRequest_Expiration() { +} + +type GetBranchRequest struct { + // The full resource path of the branch to retrieve. Format: + // projects/{project_id}/branches/{branch_id} + Name *string +} + +type GetCatalogRequest struct { + // The full resource path of the catalog to retrieve. + // + // Format: "catalogs/{catalog_id}". + Name *string +} + +// Request to retrieve a single CdfConfig.. +type GetCdfConfigRequest struct { + // The resource name of the CdfConfig to retrieve. Format: + // projects/{project}/branches/{branch}/databases/{database}/cdf-configs/{cdf_config} + Name *string +} + +// Request to retrieve the status of a single replicated table (CdfStatus).. +type GetCdfStatusRequest struct { + // The resource name of the CdfStatus to retrieve. Format: + // projects/{project}/branches/{branch}/databases/{database}/cdf-configs/{cdf_config}/cdf-statuses/{cdf_status} + Name *string +} + +// Get Data API configuration for a database.. +type GetDataApiRequest struct { + // Resource name: + // projects/{project_id}/branches/{branch_id}/databases/{database_id}/data-api + Name *string +} + +type GetDatabaseRequest struct { + // The name of the Database to retrieve. Format: + // projects/{project_id}/branches/{branch_id}/databases/{database_id} + Name *string +} + +type GetEndpointRequest struct { + // The full resource path of the endpoint to retrieve. Format: + // projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id} + Name *string +} + +// The request message for `GetOperation` method.. +type GetOperationRequest struct { + // The name of the operation resource. + Name *string +} + +type GetProjectRequest struct { + // The full resource path of the project to retrieve. Format: + // projects/{project_id} + Name *string +} + +type GetRoleRequest struct { + // The full resource path of the role to retrieve. Format: + // projects/{project_id}/branches/{branch_id}/roles/{role_id} + Name *string +} + +type GetSyncedTableRequest struct { + // The Full resource name of the synced table. Format: + // "synced_tables/{catalog}.{schema}.{table}", where (catalog, schema, table) + // are the entity names in the Unity Catalog. + Name *string +} + +// Configuration for the initial default branch created during project creation.. +type InitialBranchSpec struct { + // Whether the initial default branch should be protected from deletion. + IsProtected *bool `fieldmask:"is_protected"` +} + +// Configuration for the initial Read/Write endpoint created during project +// creation.. +type InitialEndpointSpec struct { + // Settings for HA configuration of the endpoint. + Group *EndpointGroupSpec `fieldmask:"group"` + // The minimum number of Compute Units for the initial endpoint. + AutoscalingLimitMinCu *float64 `fieldmask:"autoscaling_limit_min_cu"` + // The maximum number of Compute Units for the initial endpoint. + AutoscalingLimitMaxCu *float64 `fieldmask:"autoscaling_limit_max_cu"` + Suspension isInitialEndpointSpec_Suspension + _ [0]initialEndpointSpecSuspensionFieldMaskMetadata `fieldmask_oneof:"Suspension"` +} + +type isInitialEndpointSpec_Suspension interface { + isInitialEndpointSpec_Suspension() +} + +// InitialEndpointSpec_Suspension_SuspendTimeoutDuration selects SuspendTimeoutDuration for InitialEndpointSpec.Suspension. +// Duration of inactivity after which the initial endpoint is automatically +// suspended. If specified, should be between 60s and 604800s (1 minute to 1 +// week). Mutually exclusive with `no_suspension`. +type InitialEndpointSpec_Suspension_SuspendTimeoutDuration struct { + SuspendTimeoutDuration types.Duration `fieldmask:"suspend_timeout_duration"` +} + +func (*InitialEndpointSpec_Suspension_SuspendTimeoutDuration) isInitialEndpointSpec_Suspension() {} + +// InitialEndpointSpec_Suspension_NoSuspension selects NoSuspension for InitialEndpointSpec.Suspension. +// When set to true, explicitly disables automatic suspension (never suspend). +// Should be set to true when provided. Mutually exclusive with +// `suspend_timeout_duration`. +type InitialEndpointSpec_Suspension_NoSuspension struct { + NoSuspension bool `fieldmask:"no_suspension"` +} + +func (*InitialEndpointSpec_Suspension_NoSuspension) isInitialEndpointSpec_Suspension() {} + +type initialEndpointSpecSuspensionFieldMaskMetadata struct { + *InitialEndpointSpec_Suspension_SuspendTimeoutDuration + *InitialEndpointSpec_Suspension_NoSuspension +} + +type ListBranchesRequest struct { + // The Project that owns this collection of branches. Format: + // projects/{project_id} + Parent *string + // Page token from a previous response. If not provided, returns the first page. + PageToken *string + // Upper bound for items returned. Cannot be negative. + PageSize *int + // Whether to include soft-deleted branches in the response. When true, deleted + // branches are included alongside active branches. Purged branches are never + // returned. + ShowDeleted *bool +} + +type ListBranchesResponse struct { + // List of branches in the project. + Branches []Branch + // Token to request the next page of branches. + NextPageToken *string +} + +// Request to list the Lakebase CDF configurations (CdfConfigs) under a +// database.. +type ListCdfConfigsRequest struct { + // The parent database to list CdfConfigs for. Format: + // projects/{project}/branches/{branch}/databases/{database} + Parent *string + // Maximum number of CdfConfigs to return. + PageSize *int + // Pagination token returned by a previous ListCdfConfigs call. Empty on the + // first page. + PageToken *string +} + +// Response to a ListCdfConfigs request, containing a page of CdfConfigs and a +// token for fetching the next page.. +type ListCdfConfigsResponse struct { + // The CdfConfigs under the parent database. + CdfConfigs []CdfConfig + // Token to retrieve the next page of results; empty when there are no more. + NextPageToken *string +} + +// Request to list the statuses of all tables replicated under a Lakebase CDF +// configuration (CdfConfig).. +type ListCdfStatusesRequest struct { + // The parent CdfConfig to list CdfStatuses for. Format: + // projects/{project}/branches/{branch}/databases/{database}/cdf-configs/{cdf_config} + Parent *string + // Maximum number of CdfStatuses to return. + PageSize *int + // Pagination token returned by a previous ListCdfStatuses call. Empty on the + // first page. + PageToken *string +} + +// Response to a ListCdfStatuses request, containing a page of replicated table +// statuses and a token for fetching the next page.. +type ListCdfStatusesResponse struct { + // The replicated tables under the parent CdfConfig. + CdfStatuses []CdfStatus + // Token to retrieve the next page of results; empty when there are no more. + NextPageToken *string +} + +// List Databases.. +type ListDatabasesRequest struct { + // The Branch that owns this collection of databases. Format: + // projects/{project_id}/branches/{branch_id} + Parent *string + // Pagination token to go to the next page of Databases. Requests first page if + // absent. + PageToken *string + // Upper bound for items returned. + PageSize *int +} + +type ListDatabasesResponse struct { + // List of databases. + Databases []Database + // Pagination token to request the next page of databases. + NextPageToken *string +} + +type ListEndpointsRequest struct { + // The Branch that owns this collection of endpoints. Format: + // projects/{project_id}/branches/{branch_id} + Parent *string + // Page token from a previous response. If not provided, returns the first page. + PageToken *string + // Upper bound for items returned. Cannot be negative. + PageSize *int +} + +type ListEndpointsResponse struct { + // List of compute endpoints in the branch. + Endpoints []Endpoint + // Token to request the next page of compute endpoints. + NextPageToken *string +} + +type ListProjectsRequest struct { + // Page token from a previous response. If not provided, returns the first page. + PageToken *string + // Upper bound for items returned. Cannot be negative. The maximum value is 100. + PageSize *int + // Whether to include soft-deleted projects in the response. When true, + // soft-deleted projects are included alongside active projects. Hard-deleted + // and already-purged projects are never returned. + ShowDeleted *bool +} + +type ListProjectsResponse struct { + // List of all projects in the workspace that the user has permission to access. + Projects []Project + // Token to request the next page of projects. + NextPageToken *string +} + +type ListRolesRequest struct { + // The Branch that owns this collection of roles. Format: + // projects/{project_id}/branches/{branch_id} + Parent *string + // Page token from a previous response. If not provided, returns the first page. + PageToken *string + // Upper bound for items returned. Cannot be negative. + PageSize *int +} + +type ListRolesResponse struct { + // List of Postgres roles in the branch. + Roles []Role + // Token to request the next page of Postgres roles. + NextPageToken *string +} + +type NewPipelineSpec struct { + // UC catalog for the pipeline to store intermediate files (checkpoints, event + // logs etc). This needs to be a standard catalog where the user has permissions + // to create Delta tables. + StorageCatalog *string + // UC schema for the pipeline to store intermediate files (checkpoints, event + // logs etc). This needs to be in the standard catalog where the user has + // permissions to create Delta tables. + StorageSchema *string + // Budget policy to set on the newly created pipeline. + BudgetPolicyId *string + // Release channel of the underlying pipeline's runtime. Some source table + // configurations (e.g., read-time CDF) require PREVIEW. Defaults to CURRENT if + // not specified. + PipelineChannel NewPipelineSpec_PipelineChannel +} + +// This resource represents a long-running operation that is the result of a +// network API call.. +type Operation struct { + // The server-assigned name, which is only unique within the same service that + // originally returns it. If you use the default HTTP mapping, the `name` should + // be a resource name ending with `operations/{unique_id}`. + Name *string + // Service-specific metadata associated with the operation. It typically + // contains progress information and common metadata such as create time. Some + // services might not provide such metadata. + Metadata json.RawMessage + // If the value is `false`, it means the operation is still in progress. If + // `true`, the operation is completed, and either `error` or `response` is + // available. + Done *bool + // The operation result, which can be either an `error` or a valid `response`. + // If `done` == `false`, neither `error` nor `response` is set. If `done` == + // `true`, exactly one of `error` or `response` can be set. Some services might + // not provide the result. + Result isOperation_Result +} + +type isOperation_Result interface { + isOperation_Result() +} + +// Operation_Result_Error selects Error for Operation.Result. +// The error result of the operation in case of failure or cancellation. +type Operation_Result_Error struct { + Error ApiError +} + +func (*Operation_Result_Error) isOperation_Result() {} + +// Operation_Result_Response selects Response for Operation.Result. +// The normal, successful response of the operation. +type Operation_Result_Response struct { + Response json.RawMessage +} + +func (*Operation_Result_Response) isOperation_Result() {} + +type Project struct { + // Output only. The full resource path of the project. Format: + // projects/{project_id} + Name *string `fieldmask:"name"` + // System-generated unique ID for the project. + Uid *string `fieldmask:"uid"` + // A timestamp indicating when the project was created. + CreateTime *types.Time `fieldmask:"create_time"` + // A timestamp indicating when the project was last updated. + UpdateTime *types.Time `fieldmask:"update_time"` + // The spec contains the project configuration, including display_name, + // pg_version (Postgres version), history_retention_duration, and + // default_endpoint_settings. + Spec *ProjectSpec `fieldmask:"spec"` + // The current status of a Project. + Status *ProjectStatus `fieldmask:"status"` + // Configuration settings for the initial Read/Write endpoint created inside the + // initial branch for a newly created project. If omitted, the initial endpoint + // created will have default settings, without high availability configured. + // This field does not apply to any endpoints created after project creation. + // Use spec.default_endpoint_settings to configure default settings for + // endpoints created after project creation. + InitialEndpointSpec *InitialEndpointSpec `fieldmask:"initial_endpoint_spec"` + // A timestamp indicating when the project was soft-deleted. Empty if the + // project is not deleted, otherwise set to a timestamp in the past. + DeleteTime *types.Time `fieldmask:"delete_time"` + // A timestamp indicating when the project is scheduled for permanent deletion. + // Empty if the project is not deleted, otherwise set to a timestamp in the + // future. + PurgeTime *types.Time `fieldmask:"purge_time"` + // Configuration for the initial default branch created as part of project + // creation. Allows overriding branch protection. These settings only apply at + // creation time and do not affect resources created after project creation. + InitialBranchSpec *InitialBranchSpec `fieldmask:"initial_branch_spec"` + // The part of the name, chosen by the user when the resource was created. + ProjectId *string `fieldmask:"project_id"` +} + +type ProjectCustomTag struct { + // The key of the custom tag. + Key *string + // The value of the custom tag. + Value *string +} + +// A collection of settings for a compute endpoint.. +type ProjectDefaultEndpointSettings struct { + // The minimum number of Compute Units. Minimum value is 0.5. + AutoscalingLimitMinCu *float64 `fieldmask:"autoscaling_limit_min_cu"` + // The maximum number of Compute Units. Minimum value is 0.5. + AutoscalingLimitMaxCu *float64 `fieldmask:"autoscaling_limit_max_cu"` + Suspension isProjectDefaultEndpointSettings_Suspension + // A raw representation of Postgres settings. + PgSettings map[string]string `fieldmask:"pg_settings"` + _ [0]projectDefaultEndpointSettingsSuspensionFieldMaskMetadata `fieldmask_oneof:"Suspension"` +} + +type isProjectDefaultEndpointSettings_Suspension interface { + isProjectDefaultEndpointSettings_Suspension() +} + +// ProjectDefaultEndpointSettings_Suspension_SuspendTimeoutDuration selects SuspendTimeoutDuration for ProjectDefaultEndpointSettings.Suspension. +// Duration of inactivity after which the compute endpoint is automatically +// suspended. If specified should be between 60s and 604800s (1 minute to 1 +// week). Mutually exclusive with `no_suspension`. When updating, use +// `spec.project_default_settings.suspension` in the update_mask. +type ProjectDefaultEndpointSettings_Suspension_SuspendTimeoutDuration struct { + SuspendTimeoutDuration types.Duration `fieldmask:"suspend_timeout_duration"` +} + +func (*ProjectDefaultEndpointSettings_Suspension_SuspendTimeoutDuration) isProjectDefaultEndpointSettings_Suspension() { +} + +// ProjectDefaultEndpointSettings_Suspension_NoSuspension selects NoSuspension for ProjectDefaultEndpointSettings.Suspension. +// When set to true, explicitly disables automatic suspension (never suspend). +// Should be set to true when provided. Mutually exclusive with +// `suspend_timeout_duration`. When updating, use +// `spec.project_default_settings.suspension` in the update_mask. +type ProjectDefaultEndpointSettings_Suspension_NoSuspension struct { + NoSuspension bool `fieldmask:"no_suspension"` +} + +func (*ProjectDefaultEndpointSettings_Suspension_NoSuspension) isProjectDefaultEndpointSettings_Suspension() { +} + +type projectDefaultEndpointSettingsSuspensionFieldMaskMetadata struct { + *ProjectDefaultEndpointSettings_Suspension_SuspendTimeoutDuration + *ProjectDefaultEndpointSettings_Suspension_NoSuspension +} + +type ProjectOperationMetadata struct { +} + +type ProjectSpec struct { + // Human-readable project name. Length should be between 1 and 256 characters. + DisplayName *string `fieldmask:"display_name"` + // The major Postgres version number. The set of supported versions may vary; + // consult the API documentation for currently accepted values. + PgVersion *int `fieldmask:"pg_version"` + // The number of seconds to retain the shared history for point in time recovery + // for all branches in this project. Value should be between 172800s (2 days) + // and 3024000s (35 days). + HistoryRetentionDuration *types.Duration `fieldmask:"history_retention_duration"` + DefaultEndpointSettings *ProjectDefaultEndpointSettings `fieldmask:"default_endpoint_settings"` + // The desired budget policy to associate with the project. See + // status.budget_policy_id for the policy that is actually applied to the + // project. + BudgetPolicyId *string `fieldmask:"budget_policy_id"` + // Custom tags to associate with the project. Forwarded to LBM for billing and + // cost tracking. To update tags, provide the new tag list and include + // "spec.custom_tags" in the update_mask. To clear all tags, provide an empty + // list and include "spec.custom_tags" in the update_mask. To preserve existing + // tags, omit this field from the update_mask (or use wildcard "*" which + // auto-excludes empty tags). + CustomTags []ProjectCustomTag `fieldmask:"custom_tags"` + // Whether to enable PG native password login on all endpoints in this project. + // Defaults to false. + EnablePgNativeLogin *bool `fieldmask:"enable_pg_native_login"` + // The full resource path for the default branch of the project Format: + // projects/{project_id}/branches/{branch_id} + DefaultBranch *string `fieldmask:"default_branch"` +} + +type ProjectStatus struct { + // The effective human-readable project name. + DisplayName *string `fieldmask:"display_name"` + // The effective major Postgres version number. + PgVersion *int `fieldmask:"pg_version"` + // The effective number of seconds to retain the shared history for point in + // time recovery. + HistoryRetentionDuration *types.Duration `fieldmask:"history_retention_duration"` + // The effective default endpoint settings. + DefaultEndpointSettings *ProjectDefaultEndpointSettings `fieldmask:"default_endpoint_settings"` + // The logical size limit for a branch. + BranchLogicalSizeLimitBytes *int64 `fieldmask:"branch_logical_size_limit_bytes"` + // The current space occupied by the project in storage. + SyntheticStorageSizeBytes *int64 `fieldmask:"synthetic_storage_size_bytes"` + // The most recent time when any endpoint of this project was active. + ComputeLastActiveTime *types.Time `fieldmask:"compute_last_active_time"` + // The budget policy that is applied to the project. + BudgetPolicyId *string `fieldmask:"budget_policy_id"` + // The effective custom tags associated with the project. + CustomTags []ProjectCustomTag `fieldmask:"custom_tags"` + // The email of the project owner. + Owner *string `fieldmask:"owner"` + // Whether to enable PG native password login on all endpoints in this project. + EnablePgNativeLogin *bool `fieldmask:"enable_pg_native_login"` + // The full resource path of the default branch of the project + DefaultBranch *string `fieldmask:"default_branch"` + // Part of the resource name. + ProjectId *string `fieldmask:"project_id"` +} + +// The provisioning state of a resource in Unity Catalog.. +type ProvisioningInfo struct { +} + +type RequestedClaims struct { + PermissionSet RequestedClaims_PermissionSet + Resources []RequestedResource +} + +type RequestedResource struct { + ResourceName isRequestedResource_ResourceName +} + +type isRequestedResource_ResourceName interface { + isRequestedResource_ResourceName() +} + +// RequestedResource_ResourceName_TableName selects TableName for RequestedResource.ResourceName. +// The full Unity Catalog table name. +type RequestedResource_ResourceName_TableName struct { + TableName string +} + +func (*RequestedResource_ResourceName_TableName) isRequestedResource_ResourceName() {} + +// Role represents a Postgres role within a Branch.. +type Role struct { + // Output only. The full resource path of the role. Format: + // projects/{project_id}/branches/{branch_id}/roles/{role_id} + Name *string `fieldmask:"name"` + // The Branch where this Role exists. Format: + // projects/{project_id}/branches/{branch_id} + Parent *string `fieldmask:"parent"` + CreateTime *types.Time `fieldmask:"create_time"` + UpdateTime *types.Time `fieldmask:"update_time"` + // The spec contains the role configuration, including identity type, + // authentication method, and role attributes. + Spec *Role_RoleSpec `fieldmask:"spec"` + // Current status of the role, including its identity type, authentication + // method, and role attributes. + Status *Role_RoleStatus `fieldmask:"status"` + // The part of the name, chosen by the user when the resource was created. + RoleId *string `fieldmask:"role_id"` +} + +// Attributes that can be granted to a Postgres role. We are only implementing a +// subset for now, see xref: +// https://www.postgresql.org/docs/16/sql-createrole.html The values follow +// Postgres keyword naming e.g. CREATEDB, BYPASSRLS, etc. which is why they +// don't include typical underscores between words.. +type Role_Attributes struct { + Createdb *bool `fieldmask:"createdb"` + Createrole *bool `fieldmask:"createrole"` + Bypassrls *bool `fieldmask:"bypassrls"` +} + +type Role_RoleSpec struct { + // An enum value for a standard role that this role is a member of. + MembershipRoles []Role_MembershipRole `fieldmask:"membership_roles"` + // The type of role. When specifying a managed-identity, the chosen role_id must + // be a valid: + // + // * application ID for SERVICE_PRINCIPAL * user email for USER * group name for + // GROUP + IdentityType Role_IdentityType `fieldmask:"identity_type"` + // The desired API-exposed Postgres role attribute to associate with the role. + // Optional. + Attributes *Role_Attributes `fieldmask:"attributes"` + // Controls how the Postgres role authenticates when a client opens a database + // connection. Supported values: + // + // * LAKEBASE_OAUTH_V1: the role authenticates by presenting a Databricks OAuth + // access token derived from the backing managed identity (the + // user, service principal, or group named by the role's `postgres_role`). No + // static password exists for roles using this method. * + // PG_PASSWORD_SCRAM_SHA_256: the role authenticates with a Postgres password + // verified server-side using the SCRAM-SHA-256 mechanism. Lakebase generates a + // password for the role. * NO_LOGIN: the role cannot open a Postgres session at + // all. Useful for roles that exist only to own objects or to aggregate + // privileges that are then granted to other, loginable roles. + // + // If auth_method is left unspecified, a meaningful authentication method is + // derived from the identity_type: * For the managed identities, OAUTH is used. + // * For the regular postgres roles, authentication based on postgres passwords + // is used. + // + // NOTE: for the identity type GROUP, LAKEBASE_OAUTH_V1 is the + // default auth method (group can login as well). + AuthMethod Role_AuthMethod `fieldmask:"auth_method"` + // The name of the Postgres role. + // + // This expects a valid Postgres identifier as specified in the link below. + // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS + // + // Required when creating the Role. + // + // If you wish to create a Postgres Role backed by a managed + // identity, then postgres_role must be one of the following: + // + // 1. user email for IdentityType.USER 2. app ID for + // IdentityType.SERVICE_PRINCIPAL 2. group name for IdentityType.GROUP + PostgresRole *string `fieldmask:"postgres_role"` +} + +type Role_RoleStatus struct { + // An enum value for a standard role that this role is a member of. + MembershipRoles []Role_MembershipRole `fieldmask:"membership_roles"` + // The type of the role. + IdentityType Role_IdentityType `fieldmask:"identity_type"` + // The PG role attributes associated with the role. + Attributes *Role_Attributes `fieldmask:"attributes"` + AuthMethod Role_AuthMethod `fieldmask:"auth_method"` + // The name of the Postgres role. + PostgresRole *string `fieldmask:"postgres_role"` + // Part of the resource name. + RoleId *string `fieldmask:"role_id"` +} + +type RoleOperationMetadata struct { +} + +type SyncedTable struct { + // Output only. The Full resource name of the synced table in Postgres where + // (catalog, schema, table) are the UC entity names. + // + // Format "synced_tables/{catalog}.{schema}.{table}" + // + // For the corresponding source table in the Unity catalog look for the + // "source_table_full_name" attribute. + Name *string + // The Unity Catalog table ID for this synced table. + Uid *string + // Configuration details of the synced table, such as the source table, + // scheduling policy, etc. This attribute is specified at creation time and most + // fields are returned as is on subsequent queries. + Spec *SyncedTable_SyncedTableSpec + // Synced Table data synchronization status. + Status *SyncedTable_SyncedTableStatus + CreateTime *types.Time + // The part of the name, chosen by the user when the resource was created. + SyncedTableId *string +} + +type SyncedTable_SyncedTableSpec struct { + // The Postgres database name where the synced table will be created in. + // + // If this synced table is created inside a Lakebase Catalog, this attribute can + // be omitted on creation and is inferred from the postgres_database associated + // with the Lakebase Catalog. If specified when inside a Lakebase Catalog, the + // value must match. + // + // A value must be specified when creating a synced table inside a Standard + // Catalog. + PostgresDatabase *string + // The full resource name the branch associated with the table. + // + // Format: "projects/{project_id}/branches/{branch_id}". + Branch *string + // Scheduling policy of the underlying pipeline. + SchedulingPolicy SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy + // Three-part (catalog, schema, table) name of the source Delta table. + // + // For the corresponding destination table, use any of the two: + // + // * synced_table_id used at the creation of the SyncedTable * "name" consisting + // of "synced_tables/" prefix and the full name of the destination table. + SourceTableFullName *string + // Primary Key columns to be used for data insert/update in the destination. + PrimaryKeyColumns []string + // Time series key to deduplicate (tie-break) rows with the same primary key. + TimeseriesKey *string + // ID of an existing pipeline to bin-pack this synced table into. At most one of + // existing_pipeline_id and new_pipeline_spec should be defined. + // + // The pipeline used for the synced table is returned via the top level + // pipeline_id attribute. + ExistingPipelineId *string + // If true, the synced table's logical database and schema resources in PG will + // be created if they do not already exist. The request will fail if this is + // false and the database/schema do not exist. + // + // Defaults to true if omitted. + CreateDatabaseObjectsIfMissing *bool + // Specification for creating a new pipeline. At most one of + // existing_pipeline_id and new_pipeline_spec should be defined. + // + // The pipeline used for the synced table is returned via the top level + // pipeline_id attribute. + NewPipelineSpec *NewPipelineSpec + // When true, enables accelerated sync mode for the initial data load. This + // significantly improves performance for large tables. Requires workspace-level + // enablement through Lakebase Accelerated Sync preview. + AcceleratedSync *bool + // Override the default Delta->PG type mapping for specific columns. A + // TypeOverride with PG_SPECIFIC_TYPE_UNSPECIFIED is rejected; a valid pg_type + // must be set. + TypeOverrides []SyncedTable_SyncedTableSpec_TypeOverride + // Extra PostgreSQL-only columns to add to the synced table. + ExtraColumns []SyncedTable_SyncedTableSpec_ExtraColumn +} + +// An extra PostgreSQL column to add to the synced table.. +type SyncedTable_SyncedTableSpec_ExtraColumn struct { + // Name of the column. + ColumnName *string + // PostgreSQL type of the column, for example "tsvector" or "vector(1024)". + ColumnType *string + Maintenance SyncedTable_SyncedTableSpec_ExtraColumn_Maintenance + // SQL expression used to compute the column's value, for example + // "to_tsvector('english', content)". + Compute *string +} + +// Overrides the default Delta-to-PostgreSQL type mapping for a single column.. +type SyncedTable_SyncedTableSpec_TypeOverride struct { + // Name of the source column whose target PostgreSQL type should be overridden. + ColumnName *string + // PostgreSQL-specific target type to use for the column. + PgType SyncedTable_SyncedTableSpec_PgSpecificType + // Size parameter for the target type, for types that take one (e.g. vector + // dimension, varchar length). Required when the chosen pg_type needs a size. + Size *int +} + +type SyncedTable_SyncedTableStatus struct { + // A text description of the current state of the synced table. + Message *string + // The state of the synced table. + DetailedState SyncedTableState + // Summary of the last successful synchronization from source to destination. + LastSync *SyncedTablePosition + OngoingSyncProgress *SyncedTablePipelineProgress + // The current phase of the data synchronization pipeline. + ProvisioningPhase ProvisioningPhase + // The last source table Delta version that was successfully synced to the + // synced table. + LastProcessedCommitVersion *int64 + // The end timestamp of the last time any data was synchronized from the source + // table to the synced table. This is when the data is available in the synced + // table. + LastSyncTime *types.Time + // ID of the associated pipeline. + PipelineId *string + // The provisioning state of the synced table entity in Unity Catalog. + UnityCatalogProvisioningState ProvisioningInfo_State + // The full resource name of the project associated with the table. + // + // Format: "projects/{project_id}". + Project *string +} + +// Metadata for SyncedTable long-running operations.. +type SyncedTableOperationMetadata struct { +} + +// Progress information of the Synced Table data synchronization pipeline.. +type SyncedTablePipelineProgress struct { + // The source table Delta version that was last processed by the pipeline. The + // pipeline may not have completely processed this version yet. + LatestVersionCurrentlyProcessing *int64 + // The number of rows that have been synced in this update. + SyncedRowCount *int64 + // The total number of rows that need to be synced in this update. This number + // may be an estimate. + TotalRowCount *int64 + // The completion ratio of this update. This is a number between 0 and 1. + SyncProgressCompletion *float64 + // The estimated time remaining to complete this update in seconds. + EstimatedCompletionTimeSeconds *float64 +} + +type SyncedTablePosition struct { + // The starting timestamp of the most recent successful synchronization from the + // source table to the destination (synced) table. Note this is the starting + // timestamp of the sync operation, not the end time. E.g., for a batch, this is + // the time when the sync operation started. + SyncStartTime *types.Time + // The end timestamp of the most recent successful synchronization. This is the + // time when the data is available in the synced table. + SyncEndTime *types.Time + // Information about the source system at the time of the last sync. + SourceSyncInfo isSyncedTablePosition_SourceSyncInfo +} + +type isSyncedTablePosition_SourceSyncInfo interface { + isSyncedTablePosition_SourceSyncInfo() +} + +// SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo selects DeltaTableSyncInfo for SyncedTablePosition.SourceSyncInfo. +type SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo struct { + DeltaTableSyncInfo DeltaTableSyncInfo +} + +func (*SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo) isSyncedTablePosition_SourceSyncInfo() { +} + +type UndeleteBranchRequest struct { + // The full resource path of the branch to undelete. Format: + // projects/{project_id}/branches/{branch_id} + Name *string +} + +// Request to restore a soft-deleted project within its retention period.. +type UndeleteProjectRequest struct { + // The full resource path of the project to undelete. Format: + // projects/{project_id} + Name *string +} + +type UpdateBranchRequest struct { + // The Branch to update. + // + // The branch's `name` field is used to identify the branch to update. Format: + // projects/{project_id}/branches/{branch_id} + Branch *Branch + // The list of fields to update. + UpdateMask *types.FieldMask[Branch] +} + +// Update Data API configuration for a database.. +type UpdateDataApiRequest struct { + // The Data API configuration to update. The data_api's `name` field identifies + // the resource. + DataApi *DataApi + // The list of fields to update. + UpdateMask *types.FieldMask[DataApi] +} + +type UpdateDatabaseRequest struct { + // The Database to update. + // + // The database's `name` field is used to identify the database to update. + // Format: projects/{project_id}/branches/{branch_id}/databases/{database_id} + Database *Database + // The list of fields to update. + UpdateMask *types.FieldMask[Database] +} + +type UpdateEndpointRequest struct { + // The Endpoint to update. + // + // The endpoint's `name` field is used to identify the endpoint to update. + // Format: projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id} + Endpoint *Endpoint + // The list of fields to update. + UpdateMask *types.FieldMask[Endpoint] +} + +type UpdateProjectRequest struct { + // The Project to update. + // + // The project's `name` field is used to identify the project to update. Format: + // projects/{project_id} + Project *Project + // The list of fields to update. + UpdateMask *types.FieldMask[Project] +} + +type UpdateRoleRequest struct { + // The Postgres Role to update. + // + // The role's `name` field is used to identify the role to update. Format: + // projects/{project_id}/branches/{branch_id}/roles/{role_id} + Role *Role + // The list of fields to update. + UpdateMask *types.FieldMask[Role] +} + +// Error returns the LRO error code and message. +func (e *ApiError) Error() string { + message := "unknown error" + if e.Message != nil && *e.Message != "" { + message = *e.Message + } + if e.ErrorCode != "" { + return fmt.Sprintf("[%v] %s", e.ErrorCode, message) + } + return message +} diff --git a/postgres/v1/wire.go b/postgres/v1/wire.go new file mode 100755 index 0000000..f5f6c0d --- /dev/null +++ b/postgres/v1/wire.go @@ -0,0 +1,2868 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package postgres + +import ( + "encoding/json" + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type apiErrorWire struct { + ErrorCode ErrorCode `json:"error_code,omitempty"` + Message *string `json:"message,omitempty"` + StackTrace *string `json:"stack_trace,omitempty"` + Details []json.RawMessage `json:"details,omitempty"` +} + +func apiErrorFromWire(w *apiErrorWire) (*ApiError, error) { + if w == nil { + return nil, nil + } + return &ApiError{ + ErrorCode: w.ErrorCode, + Message: w.Message, + StackTrace: w.StackTrace, + Details: w.Details, + }, nil +} + +type branchWire struct { + Name *string `json:"name,omitempty"` + Uid *string `json:"uid,omitempty"` + Parent *string `json:"parent,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Spec *branchSpecWire `json:"spec,omitempty"` + Status *branchStatusWire `json:"status,omitempty"` + BranchId *string `json:"branch_id,omitempty"` +} + +func branchToWire(v *Branch) (*branchWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := branchSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Branch.Spec", err) + } + statusWireValue, err := branchStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Branch.Status", err) + } + return &branchWire{ + Name: v.Name, + Uid: v.Uid, + Parent: v.Parent, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + Spec: specWireValue, + Status: statusWireValue, + BranchId: v.BranchId, + }, nil +} + +func branchFromWire(w *branchWire) (*Branch, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := branchSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Branch.Spec", err) + } + statusPublicValue, err := branchStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Branch.Status", err) + } + return &Branch{ + Name: w.Name, + Uid: w.Uid, + Parent: w.Parent, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Spec: specPublicValue, + Status: statusPublicValue, + BranchId: w.BranchId, + }, nil +} + +type branchOperationMetadataWire struct { +} + +func branchOperationMetadataFromWire(w *branchOperationMetadataWire) (*BranchOperationMetadata, error) { + if w == nil { + return nil, nil + } + return &BranchOperationMetadata{}, nil +} + +type branchSpecWire struct { + SourceBranch *string `json:"source_branch,omitempty"` + SourceBranchLsn *string `json:"source_branch_lsn,omitempty"` + SourceBranchTime *types.Time `json:"source_branch_time,omitempty"` + IsProtected *bool `json:"is_protected,omitempty"` + ExpireTime *types.Time `json:"expire_time,omitempty"` + Ttl *types.Duration `json:"ttl,omitempty"` + NoExpiry *bool `json:"no_expiry,omitempty"` +} + +func branchSpecToWire(v *BranchSpec) (*branchSpecWire, error) { + if v == nil { + return nil, nil + } + var expirationExpireTimeWire *types.Time + var expirationTtlWire *types.Duration + var expirationNoExpiryWire *bool + switch value := v.Expiration.(type) { + case nil: + case *BranchSpec_Expiration_ExpireTime: + if value != nil { + expirationExpireTimeWire = new(value.ExpireTime) + } + case *BranchSpec_Expiration_Ttl: + if value != nil { + expirationTtlWire = new(value.Ttl) + } + case *BranchSpec_Expiration_NoExpiry: + if value != nil { + expirationNoExpiryWire = new(value.NoExpiry) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "BranchSpec.Expiration", value) + } + return &branchSpecWire{ + SourceBranch: v.SourceBranch, + SourceBranchLsn: v.SourceBranchLsn, + SourceBranchTime: v.SourceBranchTime, + IsProtected: v.IsProtected, + ExpireTime: expirationExpireTimeWire, + Ttl: expirationTtlWire, + NoExpiry: expirationNoExpiryWire, + }, nil +} + +func branchSpecFromWire(w *branchSpecWire) (*BranchSpec, error) { + if w == nil { + return nil, nil + } + expirationMembers := 0 + if w.ExpireTime != nil { + expirationMembers++ + } + if w.Ttl != nil { + expirationMembers++ + } + if w.NoExpiry != nil { + expirationMembers++ + } + if expirationMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "BranchSpec.Expiration") + } + var expirationSelection isBranchSpec_Expiration + switch { + case w.ExpireTime != nil: + expirationSelection = &BranchSpec_Expiration_ExpireTime{ExpireTime: *w.ExpireTime} + case w.Ttl != nil: + expirationSelection = &BranchSpec_Expiration_Ttl{Ttl: *w.Ttl} + case w.NoExpiry != nil: + expirationSelection = &BranchSpec_Expiration_NoExpiry{NoExpiry: *w.NoExpiry} + } + return &BranchSpec{ + SourceBranch: w.SourceBranch, + SourceBranchLsn: w.SourceBranchLsn, + SourceBranchTime: w.SourceBranchTime, + IsProtected: w.IsProtected, + Expiration: expirationSelection, + }, nil +} + +type branchStatusWire struct { + SourceBranch *string `json:"source_branch,omitempty"` + SourceBranchLsn *string `json:"source_branch_lsn,omitempty"` + SourceBranchTime *types.Time `json:"source_branch_time,omitempty"` + Default *bool `json:"default,omitempty"` + IsProtected *bool `json:"is_protected,omitempty"` + CurrentState BranchStatus_State `json:"current_state,omitempty"` + PendingState BranchStatus_State `json:"pending_state,omitempty"` + StateChangeTime *types.Time `json:"state_change_time,omitempty"` + LogicalSizeBytes *int64 `json:"logical_size_bytes,omitempty"` + ExpireTime *types.Time `json:"expire_time,omitempty"` + BranchId *string `json:"branch_id,omitempty"` + DeleteTime *types.Time `json:"delete_time,omitempty"` + PurgeTime *types.Time `json:"purge_time,omitempty"` +} + +func branchStatusToWire(v *BranchStatus) (*branchStatusWire, error) { + if v == nil { + return nil, nil + } + return &branchStatusWire{ + SourceBranch: v.SourceBranch, + SourceBranchLsn: v.SourceBranchLsn, + SourceBranchTime: v.SourceBranchTime, + Default: v.Default, + IsProtected: v.IsProtected, + CurrentState: v.CurrentState, + PendingState: v.PendingState, + StateChangeTime: v.StateChangeTime, + LogicalSizeBytes: v.LogicalSizeBytes, + ExpireTime: v.ExpireTime, + BranchId: v.BranchId, + DeleteTime: v.DeleteTime, + PurgeTime: v.PurgeTime, + }, nil +} + +func branchStatusFromWire(w *branchStatusWire) (*BranchStatus, error) { + if w == nil { + return nil, nil + } + return &BranchStatus{ + SourceBranch: w.SourceBranch, + SourceBranchLsn: w.SourceBranchLsn, + SourceBranchTime: w.SourceBranchTime, + Default: w.Default, + IsProtected: w.IsProtected, + CurrentState: w.CurrentState, + PendingState: w.PendingState, + StateChangeTime: w.StateChangeTime, + LogicalSizeBytes: w.LogicalSizeBytes, + ExpireTime: w.ExpireTime, + BranchId: w.BranchId, + DeleteTime: w.DeleteTime, + PurgeTime: w.PurgeTime, + }, nil +} + +type catalogWire struct { + Name *string `json:"name,omitempty"` + Uid *string `json:"uid,omitempty"` + Spec *catalog_CatalogSpecWire `json:"spec,omitempty"` + Status *catalog_CatalogStatusWire `json:"status,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + CatalogId *string `json:"catalog_id,omitempty"` +} + +func catalogToWire(v *Catalog) (*catalogWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := catalog_CatalogSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Catalog.Spec", err) + } + statusWireValue, err := catalog_CatalogStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Catalog.Status", err) + } + return &catalogWire{ + Name: v.Name, + Uid: v.Uid, + Spec: specWireValue, + Status: statusWireValue, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + CatalogId: v.CatalogId, + }, nil +} + +func catalogFromWire(w *catalogWire) (*Catalog, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := catalog_CatalogSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Catalog.Spec", err) + } + statusPublicValue, err := catalog_CatalogStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Catalog.Status", err) + } + return &Catalog{ + Name: w.Name, + Uid: w.Uid, + Spec: specPublicValue, + Status: statusPublicValue, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + CatalogId: w.CatalogId, + }, nil +} + +type catalog_CatalogSpecWire struct { + PostgresDatabase *string `json:"postgres_database,omitempty"` + CreateDatabaseIfMissing *bool `json:"create_database_if_missing,omitempty"` + Branch *string `json:"branch,omitempty"` +} + +func catalog_CatalogSpecToWire(v *Catalog_CatalogSpec) (*catalog_CatalogSpecWire, error) { + if v == nil { + return nil, nil + } + return &catalog_CatalogSpecWire{ + PostgresDatabase: v.PostgresDatabase, + CreateDatabaseIfMissing: v.CreateDatabaseIfMissing, + Branch: v.Branch, + }, nil +} + +func catalog_CatalogSpecFromWire(w *catalog_CatalogSpecWire) (*Catalog_CatalogSpec, error) { + if w == nil { + return nil, nil + } + return &Catalog_CatalogSpec{ + PostgresDatabase: w.PostgresDatabase, + CreateDatabaseIfMissing: w.CreateDatabaseIfMissing, + Branch: w.Branch, + }, nil +} + +type catalog_CatalogStatusWire struct { + PostgresDatabase *string `json:"postgres_database,omitempty"` + Project *string `json:"project,omitempty"` + Branch *string `json:"branch,omitempty"` +} + +func catalog_CatalogStatusToWire(v *Catalog_CatalogStatus) (*catalog_CatalogStatusWire, error) { + if v == nil { + return nil, nil + } + return &catalog_CatalogStatusWire{ + PostgresDatabase: v.PostgresDatabase, + Project: v.Project, + Branch: v.Branch, + }, nil +} + +func catalog_CatalogStatusFromWire(w *catalog_CatalogStatusWire) (*Catalog_CatalogStatus, error) { + if w == nil { + return nil, nil + } + return &Catalog_CatalogStatus{ + PostgresDatabase: w.PostgresDatabase, + Project: w.Project, + Branch: w.Branch, + }, nil +} + +type catalogOperationMetadataWire struct { +} + +func catalogOperationMetadataFromWire(w *catalogOperationMetadataWire) (*CatalogOperationMetadata, error) { + if w == nil { + return nil, nil + } + return &CatalogOperationMetadata{}, nil +} + +type cdfConfigWire struct { + Name *string `json:"name,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Schema *string `json:"schema,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + CdfConfigId *string `json:"cdf_config_id,omitempty"` + PostgresSchema *string `json:"postgres_schema,omitempty"` +} + +func cdfConfigToWire(v *CdfConfig) (*cdfConfigWire, error) { + if v == nil { + return nil, nil + } + return &cdfConfigWire{ + Name: v.Name, + Catalog: v.Catalog, + Schema: v.Schema, + CreateTime: v.CreateTime, + CdfConfigId: v.CdfConfigId, + PostgresSchema: v.PostgresSchema, + }, nil +} + +func cdfConfigFromWire(w *cdfConfigWire) (*CdfConfig, error) { + if w == nil { + return nil, nil + } + return &CdfConfig{ + Name: w.Name, + Catalog: w.Catalog, + Schema: w.Schema, + CreateTime: w.CreateTime, + CdfConfigId: w.CdfConfigId, + PostgresSchema: w.PostgresSchema, + }, nil +} + +type cdfConfigOperationMetadataWire struct { +} + +func cdfConfigOperationMetadataFromWire(w *cdfConfigOperationMetadataWire) (*CdfConfigOperationMetadata, error) { + if w == nil { + return nil, nil + } + return &CdfConfigOperationMetadata{}, nil +} + +type cdfStatusWire struct { + Name *string `json:"name,omitempty"` + PostgresTable *string `json:"postgres_table,omitempty"` + UcTable *string `json:"uc_table,omitempty"` + State CdfState `json:"state,omitempty"` + CommittedLsn *string `json:"committed_lsn,omitempty"` + LastSyncTime *types.Time `json:"last_sync_time,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + StatusDetail *string `json:"status_detail,omitempty"` +} + +func cdfStatusFromWire(w *cdfStatusWire) (*CdfStatus, error) { + if w == nil { + return nil, nil + } + return &CdfStatus{ + Name: w.Name, + PostgresTable: w.PostgresTable, + UcTable: w.UcTable, + State: w.State, + CommittedLsn: w.CommittedLsn, + LastSyncTime: w.LastSyncTime, + CreateTime: w.CreateTime, + StatusDetail: w.StatusDetail, + }, nil +} + +type createBranchRequestWire struct { + Parent *string `json:"parent,omitempty"` + BranchId *string `json:"branch_id,omitempty"` + Branch *branchWire `json:"branch,omitempty"` + ReplaceExisting *bool `json:"replace_existing,omitempty"` +} + +func createBranchRequestToWire(v *CreateBranchRequest) (*createBranchRequestWire, error) { + if v == nil { + return nil, nil + } + branchWireValue, err := branchToWire(v.Branch) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateBranchRequest.Branch", err) + } + return &createBranchRequestWire{ + Parent: v.Parent, + BranchId: v.BranchId, + Branch: branchWireValue, + ReplaceExisting: v.ReplaceExisting, + }, nil +} + +type createCatalogRequestWire struct { + CatalogId *string `json:"catalog_id,omitempty"` + Catalog *catalogWire `json:"catalog,omitempty"` +} + +func createCatalogRequestToWire(v *CreateCatalogRequest) (*createCatalogRequestWire, error) { + if v == nil { + return nil, nil + } + catalogWireValue, err := catalogToWire(v.Catalog) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCatalogRequest.Catalog", err) + } + return &createCatalogRequestWire{ + CatalogId: v.CatalogId, + Catalog: catalogWireValue, + }, nil +} + +type createCdfConfigRequestWire struct { + Parent *string `json:"parent,omitempty"` + CdfConfig *cdfConfigWire `json:"cdf_config,omitempty"` + CdfConfigId *string `json:"cdf_config_id,omitempty"` +} + +func createCdfConfigRequestToWire(v *CreateCdfConfigRequest) (*createCdfConfigRequestWire, error) { + if v == nil { + return nil, nil + } + cdfConfigWireValue, err := cdfConfigToWire(v.CdfConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCdfConfigRequest.CdfConfig", err) + } + return &createCdfConfigRequestWire{ + Parent: v.Parent, + CdfConfig: cdfConfigWireValue, + CdfConfigId: v.CdfConfigId, + }, nil +} + +type createDataApiRequestWire struct { + Parent *string `json:"parent,omitempty"` + DataApi *dataApiWire `json:"data_api,omitempty"` +} + +func createDataApiRequestToWire(v *CreateDataApiRequest) (*createDataApiRequestWire, error) { + if v == nil { + return nil, nil + } + dataApiWireValue, err := dataApiToWire(v.DataApi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateDataApiRequest.DataApi", err) + } + return &createDataApiRequestWire{ + Parent: v.Parent, + DataApi: dataApiWireValue, + }, nil +} + +type createDatabaseRequestWire struct { + Parent *string `json:"parent,omitempty"` + DatabaseId *string `json:"database_id,omitempty"` + Database *databaseWire `json:"database,omitempty"` + ReplaceExisting *bool `json:"replace_existing,omitempty"` +} + +func createDatabaseRequestToWire(v *CreateDatabaseRequest) (*createDatabaseRequestWire, error) { + if v == nil { + return nil, nil + } + databaseWireValue, err := databaseToWire(v.Database) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateDatabaseRequest.Database", err) + } + return &createDatabaseRequestWire{ + Parent: v.Parent, + DatabaseId: v.DatabaseId, + Database: databaseWireValue, + ReplaceExisting: v.ReplaceExisting, + }, nil +} + +type createEndpointRequestWire struct { + Parent *string `json:"parent,omitempty"` + EndpointId *string `json:"endpoint_id,omitempty"` + Endpoint *endpointWire `json:"endpoint,omitempty"` + ReplaceExisting *bool `json:"replace_existing,omitempty"` +} + +func createEndpointRequestToWire(v *CreateEndpointRequest) (*createEndpointRequestWire, error) { + if v == nil { + return nil, nil + } + endpointWireValue, err := endpointToWire(v.Endpoint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateEndpointRequest.Endpoint", err) + } + return &createEndpointRequestWire{ + Parent: v.Parent, + EndpointId: v.EndpointId, + Endpoint: endpointWireValue, + ReplaceExisting: v.ReplaceExisting, + }, nil +} + +type createProjectRequestWire struct { + ProjectId *string `json:"project_id,omitempty"` + Project *projectWire `json:"project,omitempty"` +} + +func createProjectRequestToWire(v *CreateProjectRequest) (*createProjectRequestWire, error) { + if v == nil { + return nil, nil + } + projectWireValue, err := projectToWire(v.Project) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateProjectRequest.Project", err) + } + return &createProjectRequestWire{ + ProjectId: v.ProjectId, + Project: projectWireValue, + }, nil +} + +type createRoleRequestWire struct { + Parent *string `json:"parent,omitempty"` + RoleId *string `json:"role_id,omitempty"` + Role *roleWire `json:"role,omitempty"` + ReplaceExisting *bool `json:"replace_existing,omitempty"` +} + +func createRoleRequestToWire(v *CreateRoleRequest) (*createRoleRequestWire, error) { + if v == nil { + return nil, nil + } + roleWireValue, err := roleToWire(v.Role) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRoleRequest.Role", err) + } + return &createRoleRequestWire{ + Parent: v.Parent, + RoleId: v.RoleId, + Role: roleWireValue, + ReplaceExisting: v.ReplaceExisting, + }, nil +} + +type createSyncedTableRequestWire struct { + SyncedTableId *string `json:"synced_table_id,omitempty"` + SyncedTable *syncedTableWire `json:"synced_table,omitempty"` +} + +func createSyncedTableRequestToWire(v *CreateSyncedTableRequest) (*createSyncedTableRequestWire, error) { + if v == nil { + return nil, nil + } + syncedTableWireValue, err := syncedTableToWire(v.SyncedTable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateSyncedTableRequest.SyncedTable", err) + } + return &createSyncedTableRequestWire{ + SyncedTableId: v.SyncedTableId, + SyncedTable: syncedTableWireValue, + }, nil +} + +type dataApiWire struct { + Name *string `json:"name,omitempty"` + Parent *string `json:"parent,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Spec *dataApi_DataApiSpecWire `json:"spec,omitempty"` + Status *dataApi_DataApiStatusWire `json:"status,omitempty"` +} + +func dataApiToWire(v *DataApi) (*dataApiWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := dataApi_DataApiSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataApi.Spec", err) + } + statusWireValue, err := dataApi_DataApiStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataApi.Status", err) + } + return &dataApiWire{ + Name: v.Name, + Parent: v.Parent, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + Spec: specWireValue, + Status: statusWireValue, + }, nil +} + +func dataApiFromWire(w *dataApiWire) (*DataApi, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := dataApi_DataApiSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataApi.Spec", err) + } + statusPublicValue, err := dataApi_DataApiStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DataApi.Status", err) + } + return &DataApi{ + Name: w.Name, + Parent: w.Parent, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Spec: specPublicValue, + Status: statusPublicValue, + }, nil +} + +type dataApi_DataApiSpecWire struct { + DbAggregatesEnabled *bool `json:"db_aggregates_enabled,omitempty"` + DbExtraSearchPath []string `json:"db_extra_search_path,omitempty"` + DbMaxRows *int `json:"db_max_rows,omitempty"` + DbSchemas []string `json:"db_schemas,omitempty"` + JwtRoleClaimKey *string `json:"jwt_role_claim_key,omitempty"` + JwtCacheMaxLifetime *types.Duration `json:"jwt_cache_max_lifetime,omitempty"` + OpenapiMode OpenApiMode `json:"openapi_mode,omitempty"` + ServerCorsAllowedOrigins []string `json:"server_cors_allowed_origins,omitempty"` + ServerTimingEnabled *bool `json:"server_timing_enabled,omitempty"` +} + +func dataApi_DataApiSpecToWire(v *DataApi_DataApiSpec) (*dataApi_DataApiSpecWire, error) { + if v == nil { + return nil, nil + } + return &dataApi_DataApiSpecWire{ + DbAggregatesEnabled: v.DbAggregatesEnabled, + DbExtraSearchPath: v.DbExtraSearchPath, + DbMaxRows: v.DbMaxRows, + DbSchemas: v.DbSchemas, + JwtRoleClaimKey: v.JwtRoleClaimKey, + JwtCacheMaxLifetime: v.JwtCacheMaxLifetime, + OpenapiMode: v.OpenapiMode, + ServerCorsAllowedOrigins: v.ServerCorsAllowedOrigins, + ServerTimingEnabled: v.ServerTimingEnabled, + }, nil +} + +func dataApi_DataApiSpecFromWire(w *dataApi_DataApiSpecWire) (*DataApi_DataApiSpec, error) { + if w == nil { + return nil, nil + } + return &DataApi_DataApiSpec{ + DbAggregatesEnabled: w.DbAggregatesEnabled, + DbExtraSearchPath: w.DbExtraSearchPath, + DbMaxRows: w.DbMaxRows, + DbSchemas: w.DbSchemas, + JwtRoleClaimKey: w.JwtRoleClaimKey, + JwtCacheMaxLifetime: w.JwtCacheMaxLifetime, + OpenapiMode: w.OpenapiMode, + ServerCorsAllowedOrigins: w.ServerCorsAllowedOrigins, + ServerTimingEnabled: w.ServerTimingEnabled, + }, nil +} + +type dataApi_DataApiStatusWire struct { + DbAggregatesEnabled *bool `json:"db_aggregates_enabled,omitempty"` + DbExtraSearchPath []string `json:"db_extra_search_path,omitempty"` + DbMaxRows *int `json:"db_max_rows,omitempty"` + DbSchemas []string `json:"db_schemas,omitempty"` + JwtRoleClaimKey *string `json:"jwt_role_claim_key,omitempty"` + JwtCacheMaxLifetime *types.Duration `json:"jwt_cache_max_lifetime,omitempty"` + OpenapiMode OpenApiMode `json:"openapi_mode,omitempty"` + ServerCorsAllowedOrigins []string `json:"server_cors_allowed_origins,omitempty"` + ServerTimingEnabled *bool `json:"server_timing_enabled,omitempty"` + Url *string `json:"url,omitempty"` + AvailableSchemas []string `json:"available_schemas,omitempty"` +} + +func dataApi_DataApiStatusToWire(v *DataApi_DataApiStatus) (*dataApi_DataApiStatusWire, error) { + if v == nil { + return nil, nil + } + return &dataApi_DataApiStatusWire{ + DbAggregatesEnabled: v.DbAggregatesEnabled, + DbExtraSearchPath: v.DbExtraSearchPath, + DbMaxRows: v.DbMaxRows, + DbSchemas: v.DbSchemas, + JwtRoleClaimKey: v.JwtRoleClaimKey, + JwtCacheMaxLifetime: v.JwtCacheMaxLifetime, + OpenapiMode: v.OpenapiMode, + ServerCorsAllowedOrigins: v.ServerCorsAllowedOrigins, + ServerTimingEnabled: v.ServerTimingEnabled, + Url: v.Url, + AvailableSchemas: v.AvailableSchemas, + }, nil +} + +func dataApi_DataApiStatusFromWire(w *dataApi_DataApiStatusWire) (*DataApi_DataApiStatus, error) { + if w == nil { + return nil, nil + } + return &DataApi_DataApiStatus{ + DbAggregatesEnabled: w.DbAggregatesEnabled, + DbExtraSearchPath: w.DbExtraSearchPath, + DbMaxRows: w.DbMaxRows, + DbSchemas: w.DbSchemas, + JwtRoleClaimKey: w.JwtRoleClaimKey, + JwtCacheMaxLifetime: w.JwtCacheMaxLifetime, + OpenapiMode: w.OpenapiMode, + ServerCorsAllowedOrigins: w.ServerCorsAllowedOrigins, + ServerTimingEnabled: w.ServerTimingEnabled, + Url: w.Url, + AvailableSchemas: w.AvailableSchemas, + }, nil +} + +type dataApiOperationMetadataWire struct { +} + +func dataApiOperationMetadataFromWire(w *dataApiOperationMetadataWire) (*DataApiOperationMetadata, error) { + if w == nil { + return nil, nil + } + return &DataApiOperationMetadata{}, nil +} + +type databaseWire struct { + Name *string `json:"name,omitempty"` + Parent *string `json:"parent,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Spec *database_DatabaseSpecWire `json:"spec,omitempty"` + Status *database_DatabaseStatusWire `json:"status,omitempty"` + DatabaseId *string `json:"database_id,omitempty"` +} + +func databaseToWire(v *Database) (*databaseWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := database_DatabaseSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Database.Spec", err) + } + statusWireValue, err := database_DatabaseStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Database.Status", err) + } + return &databaseWire{ + Name: v.Name, + Parent: v.Parent, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + Spec: specWireValue, + Status: statusWireValue, + DatabaseId: v.DatabaseId, + }, nil +} + +func databaseFromWire(w *databaseWire) (*Database, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := database_DatabaseSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Database.Spec", err) + } + statusPublicValue, err := database_DatabaseStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Database.Status", err) + } + return &Database{ + Name: w.Name, + Parent: w.Parent, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Spec: specPublicValue, + Status: statusPublicValue, + DatabaseId: w.DatabaseId, + }, nil +} + +type database_DatabaseSpecWire struct { + Role *string `json:"role,omitempty"` + PostgresDatabase *string `json:"postgres_database,omitempty"` +} + +func database_DatabaseSpecToWire(v *Database_DatabaseSpec) (*database_DatabaseSpecWire, error) { + if v == nil { + return nil, nil + } + return &database_DatabaseSpecWire{ + Role: v.Role, + PostgresDatabase: v.PostgresDatabase, + }, nil +} + +func database_DatabaseSpecFromWire(w *database_DatabaseSpecWire) (*Database_DatabaseSpec, error) { + if w == nil { + return nil, nil + } + return &Database_DatabaseSpec{ + Role: w.Role, + PostgresDatabase: w.PostgresDatabase, + }, nil +} + +type database_DatabaseStatusWire struct { + Role *string `json:"role,omitempty"` + PostgresDatabase *string `json:"postgres_database,omitempty"` + DatabaseId *string `json:"database_id,omitempty"` +} + +func database_DatabaseStatusToWire(v *Database_DatabaseStatus) (*database_DatabaseStatusWire, error) { + if v == nil { + return nil, nil + } + return &database_DatabaseStatusWire{ + Role: v.Role, + PostgresDatabase: v.PostgresDatabase, + DatabaseId: v.DatabaseId, + }, nil +} + +func database_DatabaseStatusFromWire(w *database_DatabaseStatusWire) (*Database_DatabaseStatus, error) { + if w == nil { + return nil, nil + } + return &Database_DatabaseStatus{ + Role: w.Role, + PostgresDatabase: w.PostgresDatabase, + DatabaseId: w.DatabaseId, + }, nil +} + +type databaseCredentialWire struct { + Token *string `json:"token,omitempty"` + ExpireTime *types.Time `json:"expire_time,omitempty"` +} + +func databaseCredentialFromWire(w *databaseCredentialWire) (*DatabaseCredential, error) { + if w == nil { + return nil, nil + } + return &DatabaseCredential{ + Token: w.Token, + ExpireTime: w.ExpireTime, + }, nil +} + +type databaseOperationMetadataWire struct { +} + +func databaseOperationMetadataFromWire(w *databaseOperationMetadataWire) (*DatabaseOperationMetadata, error) { + if w == nil { + return nil, nil + } + return &DatabaseOperationMetadata{}, nil +} + +type deleteBranchRequestWire struct { + Name *string `json:"name,omitempty"` + Purge *bool `json:"purge,omitempty"` +} + +func deleteBranchRequestToWire(v *DeleteBranchRequest) (*deleteBranchRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteBranchRequestWire{ + Name: v.Name, + Purge: v.Purge, + }, nil +} + +type deleteCdfConfigRequestWire struct { + Name *string `json:"name,omitempty"` + Force *bool `json:"force,omitempty"` +} + +func deleteCdfConfigRequestToWire(v *DeleteCdfConfigRequest) (*deleteCdfConfigRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteCdfConfigRequestWire{ + Name: v.Name, + Force: v.Force, + }, nil +} + +type deleteProjectRequestWire struct { + Name *string `json:"name,omitempty"` + Purge *bool `json:"purge,omitempty"` +} + +func deleteProjectRequestToWire(v *DeleteProjectRequest) (*deleteProjectRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteProjectRequestWire{ + Name: v.Name, + Purge: v.Purge, + }, nil +} + +type deleteRoleRequestWire struct { + Name *string `json:"name,omitempty"` + ReassignOwnedTo *string `json:"reassign_owned_to,omitempty"` +} + +func deleteRoleRequestToWire(v *DeleteRoleRequest) (*deleteRoleRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteRoleRequestWire{ + Name: v.Name, + ReassignOwnedTo: v.ReassignOwnedTo, + }, nil +} + +type deltaTableSyncInfoWire struct { + DeltaCommitVersion *int64 `json:"delta_commit_version,omitempty"` + DeltaCommitTime *types.Time `json:"delta_commit_time,omitempty"` +} + +func deltaTableSyncInfoToWire(v *DeltaTableSyncInfo) (*deltaTableSyncInfoWire, error) { + if v == nil { + return nil, nil + } + return &deltaTableSyncInfoWire{ + DeltaCommitVersion: v.DeltaCommitVersion, + DeltaCommitTime: v.DeltaCommitTime, + }, nil +} + +func deltaTableSyncInfoFromWire(w *deltaTableSyncInfoWire) (*DeltaTableSyncInfo, error) { + if w == nil { + return nil, nil + } + return &DeltaTableSyncInfo{ + DeltaCommitVersion: w.DeltaCommitVersion, + DeltaCommitTime: w.DeltaCommitTime, + }, nil +} + +type endpointWire struct { + Name *string `json:"name,omitempty"` + Uid *string `json:"uid,omitempty"` + Parent *string `json:"parent,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Spec *endpointSpecWire `json:"spec,omitempty"` + Status *endpointStatusWire `json:"status,omitempty"` + EndpointId *string `json:"endpoint_id,omitempty"` +} + +func endpointToWire(v *Endpoint) (*endpointWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := endpointSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.Spec", err) + } + statusWireValue, err := endpointStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.Status", err) + } + return &endpointWire{ + Name: v.Name, + Uid: v.Uid, + Parent: v.Parent, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + Spec: specWireValue, + Status: statusWireValue, + EndpointId: v.EndpointId, + }, nil +} + +func endpointFromWire(w *endpointWire) (*Endpoint, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := endpointSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.Spec", err) + } + statusPublicValue, err := endpointStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.Status", err) + } + return &Endpoint{ + Name: w.Name, + Uid: w.Uid, + Parent: w.Parent, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Spec: specPublicValue, + Status: statusPublicValue, + EndpointId: w.EndpointId, + }, nil +} + +type endpointGroupSpecWire struct { + Min *int `json:"min,omitempty"` + Max *int `json:"max,omitempty"` + EnableReadableSecondaries *bool `json:"enable_readable_secondaries,omitempty"` +} + +func endpointGroupSpecToWire(v *EndpointGroupSpec) (*endpointGroupSpecWire, error) { + if v == nil { + return nil, nil + } + return &endpointGroupSpecWire{ + Min: v.Min, + Max: v.Max, + EnableReadableSecondaries: v.EnableReadableSecondaries, + }, nil +} + +func endpointGroupSpecFromWire(w *endpointGroupSpecWire) (*EndpointGroupSpec, error) { + if w == nil { + return nil, nil + } + return &EndpointGroupSpec{ + Min: w.Min, + Max: w.Max, + EnableReadableSecondaries: w.EnableReadableSecondaries, + }, nil +} + +type endpointGroupStatusWire struct { + Min *int `json:"min,omitempty"` + Max *int `json:"max,omitempty"` + EnableReadableSecondaries *bool `json:"enable_readable_secondaries,omitempty"` +} + +func endpointGroupStatusToWire(v *EndpointGroupStatus) (*endpointGroupStatusWire, error) { + if v == nil { + return nil, nil + } + return &endpointGroupStatusWire{ + Min: v.Min, + Max: v.Max, + EnableReadableSecondaries: v.EnableReadableSecondaries, + }, nil +} + +func endpointGroupStatusFromWire(w *endpointGroupStatusWire) (*EndpointGroupStatus, error) { + if w == nil { + return nil, nil + } + return &EndpointGroupStatus{ + Min: w.Min, + Max: w.Max, + EnableReadableSecondaries: w.EnableReadableSecondaries, + }, nil +} + +type endpointHostsWire struct { + Host *string `json:"host,omitempty"` + ReadOnlyHost *string `json:"read_only_host,omitempty"` + ReadWritePooledHost *string `json:"read_write_pooled_host,omitempty"` + ReadOnlyPooledHost *string `json:"read_only_pooled_host,omitempty"` +} + +func endpointHostsToWire(v *EndpointHosts) (*endpointHostsWire, error) { + if v == nil { + return nil, nil + } + return &endpointHostsWire{ + Host: v.Host, + ReadOnlyHost: v.ReadOnlyHost, + ReadWritePooledHost: v.ReadWritePooledHost, + ReadOnlyPooledHost: v.ReadOnlyPooledHost, + }, nil +} + +func endpointHostsFromWire(w *endpointHostsWire) (*EndpointHosts, error) { + if w == nil { + return nil, nil + } + return &EndpointHosts{ + Host: w.Host, + ReadOnlyHost: w.ReadOnlyHost, + ReadWritePooledHost: w.ReadWritePooledHost, + ReadOnlyPooledHost: w.ReadOnlyPooledHost, + }, nil +} + +type endpointOperationMetadataWire struct { +} + +func endpointOperationMetadataFromWire(w *endpointOperationMetadataWire) (*EndpointOperationMetadata, error) { + if w == nil { + return nil, nil + } + return &EndpointOperationMetadata{}, nil +} + +type endpointSettingsWire struct { + PgSettings map[string]string `json:"pg_settings,omitempty"` +} + +func endpointSettingsToWire(v *EndpointSettings) (*endpointSettingsWire, error) { + if v == nil { + return nil, nil + } + return &endpointSettingsWire{ + PgSettings: v.PgSettings, + }, nil +} + +func endpointSettingsFromWire(w *endpointSettingsWire) (*EndpointSettings, error) { + if w == nil { + return nil, nil + } + return &EndpointSettings{ + PgSettings: w.PgSettings, + }, nil +} + +type endpointSpecWire struct { + EndpointType EndpointType `json:"endpoint_type,omitempty"` + AutoscalingLimitMinCu *float64 `json:"autoscaling_limit_min_cu,omitempty"` + AutoscalingLimitMaxCu *float64 `json:"autoscaling_limit_max_cu,omitempty"` + Disabled *bool `json:"disabled,omitempty"` + SuspendTimeoutDuration *types.Duration `json:"suspend_timeout_duration,omitempty"` + NoSuspension *bool `json:"no_suspension,omitempty"` + Settings *endpointSettingsWire `json:"settings,omitempty"` + Group *endpointGroupSpecWire `json:"group,omitempty"` +} + +func endpointSpecToWire(v *EndpointSpec) (*endpointSpecWire, error) { + if v == nil { + return nil, nil + } + settingsWireValue, err := endpointSettingsToWire(v.Settings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointSpec.Settings", err) + } + groupWireValue, err := endpointGroupSpecToWire(v.Group) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointSpec.Group", err) + } + var suspensionSuspendTimeoutDurationWire *types.Duration + var suspensionNoSuspensionWire *bool + switch value := v.Suspension.(type) { + case nil: + case *EndpointSpec_Suspension_SuspendTimeoutDuration: + if value != nil { + suspensionSuspendTimeoutDurationWire = new(value.SuspendTimeoutDuration) + } + case *EndpointSpec_Suspension_NoSuspension: + if value != nil { + suspensionNoSuspensionWire = new(value.NoSuspension) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "EndpointSpec.Suspension", value) + } + return &endpointSpecWire{ + EndpointType: v.EndpointType, + AutoscalingLimitMinCu: v.AutoscalingLimitMinCu, + AutoscalingLimitMaxCu: v.AutoscalingLimitMaxCu, + Disabled: v.Disabled, + SuspendTimeoutDuration: suspensionSuspendTimeoutDurationWire, + NoSuspension: suspensionNoSuspensionWire, + Settings: settingsWireValue, + Group: groupWireValue, + }, nil +} + +func endpointSpecFromWire(w *endpointSpecWire) (*EndpointSpec, error) { + if w == nil { + return nil, nil + } + suspensionMembers := 0 + if w.SuspendTimeoutDuration != nil { + suspensionMembers++ + } + if w.NoSuspension != nil { + suspensionMembers++ + } + if suspensionMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "EndpointSpec.Suspension") + } + settingsPublicValue, err := endpointSettingsFromWire(w.Settings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointSpec.Settings", err) + } + groupPublicValue, err := endpointGroupSpecFromWire(w.Group) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointSpec.Group", err) + } + var suspensionSelection isEndpointSpec_Suspension + switch { + case w.SuspendTimeoutDuration != nil: + suspensionSelection = &EndpointSpec_Suspension_SuspendTimeoutDuration{SuspendTimeoutDuration: *w.SuspendTimeoutDuration} + case w.NoSuspension != nil: + suspensionSelection = &EndpointSpec_Suspension_NoSuspension{NoSuspension: *w.NoSuspension} + } + return &EndpointSpec{ + EndpointType: w.EndpointType, + AutoscalingLimitMinCu: w.AutoscalingLimitMinCu, + AutoscalingLimitMaxCu: w.AutoscalingLimitMaxCu, + Disabled: w.Disabled, + Settings: settingsPublicValue, + Group: groupPublicValue, + Suspension: suspensionSelection, + }, nil +} + +type endpointStatusWire struct { + EndpointType EndpointType `json:"endpoint_type,omitempty"` + Hosts *endpointHostsWire `json:"hosts,omitempty"` + LastActiveTime *types.Time `json:"last_active_time,omitempty"` + AutoscalingLimitMinCu *float64 `json:"autoscaling_limit_min_cu,omitempty"` + AutoscalingLimitMaxCu *float64 `json:"autoscaling_limit_max_cu,omitempty"` + CurrentState EndpointStatus_State `json:"current_state,omitempty"` + PendingState EndpointStatus_State `json:"pending_state,omitempty"` + Disabled *bool `json:"disabled,omitempty"` + SuspendTimeoutDuration *types.Duration `json:"suspend_timeout_duration,omitempty"` + Settings *endpointSettingsWire `json:"settings,omitempty"` + Group *endpointGroupStatusWire `json:"group,omitempty"` + EndpointId *string `json:"endpoint_id,omitempty"` +} + +func endpointStatusToWire(v *EndpointStatus) (*endpointStatusWire, error) { + if v == nil { + return nil, nil + } + hostsWireValue, err := endpointHostsToWire(v.Hosts) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointStatus.Hosts", err) + } + settingsWireValue, err := endpointSettingsToWire(v.Settings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointStatus.Settings", err) + } + groupWireValue, err := endpointGroupStatusToWire(v.Group) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointStatus.Group", err) + } + return &endpointStatusWire{ + EndpointType: v.EndpointType, + Hosts: hostsWireValue, + LastActiveTime: v.LastActiveTime, + AutoscalingLimitMinCu: v.AutoscalingLimitMinCu, + AutoscalingLimitMaxCu: v.AutoscalingLimitMaxCu, + CurrentState: v.CurrentState, + PendingState: v.PendingState, + Disabled: v.Disabled, + SuspendTimeoutDuration: v.SuspendTimeoutDuration, + Settings: settingsWireValue, + Group: groupWireValue, + EndpointId: v.EndpointId, + }, nil +} + +func endpointStatusFromWire(w *endpointStatusWire) (*EndpointStatus, error) { + if w == nil { + return nil, nil + } + hostsPublicValue, err := endpointHostsFromWire(w.Hosts) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointStatus.Hosts", err) + } + settingsPublicValue, err := endpointSettingsFromWire(w.Settings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointStatus.Settings", err) + } + groupPublicValue, err := endpointGroupStatusFromWire(w.Group) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointStatus.Group", err) + } + return &EndpointStatus{ + EndpointType: w.EndpointType, + Hosts: hostsPublicValue, + LastActiveTime: w.LastActiveTime, + AutoscalingLimitMinCu: w.AutoscalingLimitMinCu, + AutoscalingLimitMaxCu: w.AutoscalingLimitMaxCu, + CurrentState: w.CurrentState, + PendingState: w.PendingState, + Disabled: w.Disabled, + SuspendTimeoutDuration: w.SuspendTimeoutDuration, + Settings: settingsPublicValue, + Group: groupPublicValue, + EndpointId: w.EndpointId, + }, nil +} + +type generateDatabaseCredentialRequestWire struct { + Claims []requestedClaimsWire `json:"claims,omitempty"` + Endpoint *string `json:"endpoint,omitempty"` + Ttl *types.Duration `json:"ttl,omitempty"` + ExpireTime *types.Time `json:"expire_time,omitempty"` +} + +func generateDatabaseCredentialRequestToWire(v *GenerateDatabaseCredentialRequest) (*generateDatabaseCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + claimsWireValue, err := convertSlice(v.Claims, requestedClaimsToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateDatabaseCredentialRequest.Claims", err) + } + var expirationTtlWire *types.Duration + var expirationExpireTimeWire *types.Time + switch value := v.Expiration.(type) { + case nil: + case *GenerateDatabaseCredentialRequest_Expiration_Ttl: + if value != nil { + expirationTtlWire = new(value.Ttl) + } + case *GenerateDatabaseCredentialRequest_Expiration_ExpireTime: + if value != nil { + expirationExpireTimeWire = new(value.ExpireTime) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "GenerateDatabaseCredentialRequest.Expiration", value) + } + return &generateDatabaseCredentialRequestWire{ + Claims: claimsWireValue, + Endpoint: v.Endpoint, + Ttl: expirationTtlWire, + ExpireTime: expirationExpireTimeWire, + }, nil +} + +type initialBranchSpecWire struct { + IsProtected *bool `json:"is_protected,omitempty"` +} + +func initialBranchSpecToWire(v *InitialBranchSpec) (*initialBranchSpecWire, error) { + if v == nil { + return nil, nil + } + return &initialBranchSpecWire{ + IsProtected: v.IsProtected, + }, nil +} + +func initialBranchSpecFromWire(w *initialBranchSpecWire) (*InitialBranchSpec, error) { + if w == nil { + return nil, nil + } + return &InitialBranchSpec{ + IsProtected: w.IsProtected, + }, nil +} + +type initialEndpointSpecWire struct { + Group *endpointGroupSpecWire `json:"group,omitempty"` + AutoscalingLimitMinCu *float64 `json:"autoscaling_limit_min_cu,omitempty"` + AutoscalingLimitMaxCu *float64 `json:"autoscaling_limit_max_cu,omitempty"` + SuspendTimeoutDuration *types.Duration `json:"suspend_timeout_duration,omitempty"` + NoSuspension *bool `json:"no_suspension,omitempty"` +} + +func initialEndpointSpecToWire(v *InitialEndpointSpec) (*initialEndpointSpecWire, error) { + if v == nil { + return nil, nil + } + groupWireValue, err := endpointGroupSpecToWire(v.Group) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitialEndpointSpec.Group", err) + } + var suspensionSuspendTimeoutDurationWire *types.Duration + var suspensionNoSuspensionWire *bool + switch value := v.Suspension.(type) { + case nil: + case *InitialEndpointSpec_Suspension_SuspendTimeoutDuration: + if value != nil { + suspensionSuspendTimeoutDurationWire = new(value.SuspendTimeoutDuration) + } + case *InitialEndpointSpec_Suspension_NoSuspension: + if value != nil { + suspensionNoSuspensionWire = new(value.NoSuspension) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "InitialEndpointSpec.Suspension", value) + } + return &initialEndpointSpecWire{ + Group: groupWireValue, + AutoscalingLimitMinCu: v.AutoscalingLimitMinCu, + AutoscalingLimitMaxCu: v.AutoscalingLimitMaxCu, + SuspendTimeoutDuration: suspensionSuspendTimeoutDurationWire, + NoSuspension: suspensionNoSuspensionWire, + }, nil +} + +func initialEndpointSpecFromWire(w *initialEndpointSpecWire) (*InitialEndpointSpec, error) { + if w == nil { + return nil, nil + } + suspensionMembers := 0 + if w.SuspendTimeoutDuration != nil { + suspensionMembers++ + } + if w.NoSuspension != nil { + suspensionMembers++ + } + if suspensionMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "InitialEndpointSpec.Suspension") + } + groupPublicValue, err := endpointGroupSpecFromWire(w.Group) + if err != nil { + return nil, fmt.Errorf("%s: %w", "InitialEndpointSpec.Group", err) + } + var suspensionSelection isInitialEndpointSpec_Suspension + switch { + case w.SuspendTimeoutDuration != nil: + suspensionSelection = &InitialEndpointSpec_Suspension_SuspendTimeoutDuration{SuspendTimeoutDuration: *w.SuspendTimeoutDuration} + case w.NoSuspension != nil: + suspensionSelection = &InitialEndpointSpec_Suspension_NoSuspension{NoSuspension: *w.NoSuspension} + } + return &InitialEndpointSpec{ + Group: groupPublicValue, + AutoscalingLimitMinCu: w.AutoscalingLimitMinCu, + AutoscalingLimitMaxCu: w.AutoscalingLimitMaxCu, + Suspension: suspensionSelection, + }, nil +} + +type listBranchesRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` + ShowDeleted *bool `json:"show_deleted,omitempty"` +} + +func listBranchesRequestToWire(v *ListBranchesRequest) (*listBranchesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listBranchesRequestWire{ + Parent: v.Parent, + PageToken: v.PageToken, + PageSize: v.PageSize, + ShowDeleted: v.ShowDeleted, + }, nil +} + +type listBranchesResponseWire struct { + Branches []branchWire `json:"branches,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listBranchesResponseFromWire(w *listBranchesResponseWire) (*ListBranchesResponse, error) { + if w == nil { + return nil, nil + } + branchesPublicValue, err := convertSlice(w.Branches, branchFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListBranchesResponse.Branches", err) + } + return &ListBranchesResponse{ + Branches: branchesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listCdfConfigsRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listCdfConfigsRequestToWire(v *ListCdfConfigsRequest) (*listCdfConfigsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCdfConfigsRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listCdfConfigsResponseWire struct { + CdfConfigs []cdfConfigWire `json:"cdf_configs,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCdfConfigsResponseFromWire(w *listCdfConfigsResponseWire) (*ListCdfConfigsResponse, error) { + if w == nil { + return nil, nil + } + cdfConfigsPublicValue, err := convertSlice(w.CdfConfigs, cdfConfigFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCdfConfigsResponse.CdfConfigs", err) + } + return &ListCdfConfigsResponse{ + CdfConfigs: cdfConfigsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listCdfStatusesRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listCdfStatusesRequestToWire(v *ListCdfStatusesRequest) (*listCdfStatusesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCdfStatusesRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listCdfStatusesResponseWire struct { + CdfStatuses []cdfStatusWire `json:"cdf_statuses,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCdfStatusesResponseFromWire(w *listCdfStatusesResponseWire) (*ListCdfStatusesResponse, error) { + if w == nil { + return nil, nil + } + cdfStatusesPublicValue, err := convertSlice(w.CdfStatuses, cdfStatusFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCdfStatusesResponse.CdfStatuses", err) + } + return &ListCdfStatusesResponse{ + CdfStatuses: cdfStatusesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listDatabasesRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listDatabasesRequestToWire(v *ListDatabasesRequest) (*listDatabasesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listDatabasesRequestWire{ + Parent: v.Parent, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listDatabasesResponseWire struct { + Databases []databaseWire `json:"databases,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listDatabasesResponseFromWire(w *listDatabasesResponseWire) (*ListDatabasesResponse, error) { + if w == nil { + return nil, nil + } + databasesPublicValue, err := convertSlice(w.Databases, databaseFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListDatabasesResponse.Databases", err) + } + return &ListDatabasesResponse{ + Databases: databasesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listEndpointsRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listEndpointsRequestToWire(v *ListEndpointsRequest) (*listEndpointsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listEndpointsRequestWire{ + Parent: v.Parent, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listEndpointsResponseWire struct { + Endpoints []endpointWire `json:"endpoints,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listEndpointsResponseFromWire(w *listEndpointsResponseWire) (*ListEndpointsResponse, error) { + if w == nil { + return nil, nil + } + endpointsPublicValue, err := convertSlice(w.Endpoints, endpointFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListEndpointsResponse.Endpoints", err) + } + return &ListEndpointsResponse{ + Endpoints: endpointsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listProjectsRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` + ShowDeleted *bool `json:"show_deleted,omitempty"` +} + +func listProjectsRequestToWire(v *ListProjectsRequest) (*listProjectsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listProjectsRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + ShowDeleted: v.ShowDeleted, + }, nil +} + +type listProjectsResponseWire struct { + Projects []projectWire `json:"projects,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listProjectsResponseFromWire(w *listProjectsResponseWire) (*ListProjectsResponse, error) { + if w == nil { + return nil, nil + } + projectsPublicValue, err := convertSlice(w.Projects, projectFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListProjectsResponse.Projects", err) + } + return &ListProjectsResponse{ + Projects: projectsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listRolesRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listRolesRequestToWire(v *ListRolesRequest) (*listRolesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listRolesRequestWire{ + Parent: v.Parent, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listRolesResponseWire struct { + Roles []roleWire `json:"roles,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listRolesResponseFromWire(w *listRolesResponseWire) (*ListRolesResponse, error) { + if w == nil { + return nil, nil + } + rolesPublicValue, err := convertSlice(w.Roles, roleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListRolesResponse.Roles", err) + } + return &ListRolesResponse{ + Roles: rolesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type newPipelineSpecWire struct { + StorageCatalog *string `json:"storage_catalog,omitempty"` + StorageSchema *string `json:"storage_schema,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + PipelineChannel NewPipelineSpec_PipelineChannel `json:"pipeline_channel,omitempty"` +} + +func newPipelineSpecToWire(v *NewPipelineSpec) (*newPipelineSpecWire, error) { + if v == nil { + return nil, nil + } + return &newPipelineSpecWire{ + StorageCatalog: v.StorageCatalog, + StorageSchema: v.StorageSchema, + BudgetPolicyId: v.BudgetPolicyId, + PipelineChannel: v.PipelineChannel, + }, nil +} + +func newPipelineSpecFromWire(w *newPipelineSpecWire) (*NewPipelineSpec, error) { + if w == nil { + return nil, nil + } + return &NewPipelineSpec{ + StorageCatalog: w.StorageCatalog, + StorageSchema: w.StorageSchema, + BudgetPolicyId: w.BudgetPolicyId, + PipelineChannel: w.PipelineChannel, + }, nil +} + +type operationWire struct { + Name *string `json:"name,omitempty"` + Metadata json.RawMessage `json:"metadata,omitempty"` + Done *bool `json:"done,omitempty"` + Error *apiErrorWire `json:"error,omitempty"` + Response json.RawMessage `json:"response,omitempty"` +} + +func operationFromWire(w *operationWire) (*Operation, error) { + if w == nil { + return nil, nil + } + resultMembers := 0 + if w.Error != nil { + resultMembers++ + } + if w.Response != nil { + resultMembers++ + } + if resultMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Operation.Result") + } + var resultSelection isOperation_Result + switch { + case w.Error != nil: + resultErrorConverted, err := apiErrorFromWire(w.Error) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Operation.Result.Error", err) + } + resultSelection = &Operation_Result_Error{Error: *resultErrorConverted} + case w.Response != nil: + resultSelection = &Operation_Result_Response{Response: w.Response} + } + return &Operation{ + Name: w.Name, + Metadata: w.Metadata, + Done: w.Done, + Result: resultSelection, + }, nil +} + +type projectWire struct { + Name *string `json:"name,omitempty"` + Uid *string `json:"uid,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Spec *projectSpecWire `json:"spec,omitempty"` + Status *projectStatusWire `json:"status,omitempty"` + InitialEndpointSpec *initialEndpointSpecWire `json:"initial_endpoint_spec,omitempty"` + DeleteTime *types.Time `json:"delete_time,omitempty"` + PurgeTime *types.Time `json:"purge_time,omitempty"` + InitialBranchSpec *initialBranchSpecWire `json:"initial_branch_spec,omitempty"` + ProjectId *string `json:"project_id,omitempty"` +} + +func projectToWire(v *Project) (*projectWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := projectSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Project.Spec", err) + } + statusWireValue, err := projectStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Project.Status", err) + } + initialEndpointSpecWireValue, err := initialEndpointSpecToWire(v.InitialEndpointSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Project.InitialEndpointSpec", err) + } + initialBranchSpecWireValue, err := initialBranchSpecToWire(v.InitialBranchSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Project.InitialBranchSpec", err) + } + return &projectWire{ + Name: v.Name, + Uid: v.Uid, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + Spec: specWireValue, + Status: statusWireValue, + InitialEndpointSpec: initialEndpointSpecWireValue, + DeleteTime: v.DeleteTime, + PurgeTime: v.PurgeTime, + InitialBranchSpec: initialBranchSpecWireValue, + ProjectId: v.ProjectId, + }, nil +} + +func projectFromWire(w *projectWire) (*Project, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := projectSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Project.Spec", err) + } + statusPublicValue, err := projectStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Project.Status", err) + } + initialEndpointSpecPublicValue, err := initialEndpointSpecFromWire(w.InitialEndpointSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Project.InitialEndpointSpec", err) + } + initialBranchSpecPublicValue, err := initialBranchSpecFromWire(w.InitialBranchSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Project.InitialBranchSpec", err) + } + return &Project{ + Name: w.Name, + Uid: w.Uid, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Spec: specPublicValue, + Status: statusPublicValue, + InitialEndpointSpec: initialEndpointSpecPublicValue, + DeleteTime: w.DeleteTime, + PurgeTime: w.PurgeTime, + InitialBranchSpec: initialBranchSpecPublicValue, + ProjectId: w.ProjectId, + }, nil +} + +type projectCustomTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func projectCustomTagToWire(v *ProjectCustomTag) (*projectCustomTagWire, error) { + if v == nil { + return nil, nil + } + return &projectCustomTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func projectCustomTagFromWire(w *projectCustomTagWire) (*ProjectCustomTag, error) { + if w == nil { + return nil, nil + } + return &ProjectCustomTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type projectDefaultEndpointSettingsWire struct { + AutoscalingLimitMinCu *float64 `json:"autoscaling_limit_min_cu,omitempty"` + AutoscalingLimitMaxCu *float64 `json:"autoscaling_limit_max_cu,omitempty"` + SuspendTimeoutDuration *types.Duration `json:"suspend_timeout_duration,omitempty"` + NoSuspension *bool `json:"no_suspension,omitempty"` + PgSettings map[string]string `json:"pg_settings,omitempty"` +} + +func projectDefaultEndpointSettingsToWire(v *ProjectDefaultEndpointSettings) (*projectDefaultEndpointSettingsWire, error) { + if v == nil { + return nil, nil + } + var suspensionSuspendTimeoutDurationWire *types.Duration + var suspensionNoSuspensionWire *bool + switch value := v.Suspension.(type) { + case nil: + case *ProjectDefaultEndpointSettings_Suspension_SuspendTimeoutDuration: + if value != nil { + suspensionSuspendTimeoutDurationWire = new(value.SuspendTimeoutDuration) + } + case *ProjectDefaultEndpointSettings_Suspension_NoSuspension: + if value != nil { + suspensionNoSuspensionWire = new(value.NoSuspension) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ProjectDefaultEndpointSettings.Suspension", value) + } + return &projectDefaultEndpointSettingsWire{ + AutoscalingLimitMinCu: v.AutoscalingLimitMinCu, + AutoscalingLimitMaxCu: v.AutoscalingLimitMaxCu, + SuspendTimeoutDuration: suspensionSuspendTimeoutDurationWire, + NoSuspension: suspensionNoSuspensionWire, + PgSettings: v.PgSettings, + }, nil +} + +func projectDefaultEndpointSettingsFromWire(w *projectDefaultEndpointSettingsWire) (*ProjectDefaultEndpointSettings, error) { + if w == nil { + return nil, nil + } + suspensionMembers := 0 + if w.SuspendTimeoutDuration != nil { + suspensionMembers++ + } + if w.NoSuspension != nil { + suspensionMembers++ + } + if suspensionMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ProjectDefaultEndpointSettings.Suspension") + } + var suspensionSelection isProjectDefaultEndpointSettings_Suspension + switch { + case w.SuspendTimeoutDuration != nil: + suspensionSelection = &ProjectDefaultEndpointSettings_Suspension_SuspendTimeoutDuration{SuspendTimeoutDuration: *w.SuspendTimeoutDuration} + case w.NoSuspension != nil: + suspensionSelection = &ProjectDefaultEndpointSettings_Suspension_NoSuspension{NoSuspension: *w.NoSuspension} + } + return &ProjectDefaultEndpointSettings{ + AutoscalingLimitMinCu: w.AutoscalingLimitMinCu, + AutoscalingLimitMaxCu: w.AutoscalingLimitMaxCu, + PgSettings: w.PgSettings, + Suspension: suspensionSelection, + }, nil +} + +type projectOperationMetadataWire struct { +} + +func projectOperationMetadataFromWire(w *projectOperationMetadataWire) (*ProjectOperationMetadata, error) { + if w == nil { + return nil, nil + } + return &ProjectOperationMetadata{}, nil +} + +type projectSpecWire struct { + DisplayName *string `json:"display_name,omitempty"` + PgVersion *int `json:"pg_version,omitempty"` + HistoryRetentionDuration *types.Duration `json:"history_retention_duration,omitempty"` + DefaultEndpointSettings *projectDefaultEndpointSettingsWire `json:"default_endpoint_settings,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + CustomTags []projectCustomTagWire `json:"custom_tags,omitempty"` + EnablePgNativeLogin *bool `json:"enable_pg_native_login,omitempty"` + DefaultBranch *string `json:"default_branch,omitempty"` +} + +func projectSpecToWire(v *ProjectSpec) (*projectSpecWire, error) { + if v == nil { + return nil, nil + } + defaultEndpointSettingsWireValue, err := projectDefaultEndpointSettingsToWire(v.DefaultEndpointSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProjectSpec.DefaultEndpointSettings", err) + } + customTagsWireValue, err := convertSlice(v.CustomTags, projectCustomTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProjectSpec.CustomTags", err) + } + return &projectSpecWire{ + DisplayName: v.DisplayName, + PgVersion: v.PgVersion, + HistoryRetentionDuration: v.HistoryRetentionDuration, + DefaultEndpointSettings: defaultEndpointSettingsWireValue, + BudgetPolicyId: v.BudgetPolicyId, + CustomTags: customTagsWireValue, + EnablePgNativeLogin: v.EnablePgNativeLogin, + DefaultBranch: v.DefaultBranch, + }, nil +} + +func projectSpecFromWire(w *projectSpecWire) (*ProjectSpec, error) { + if w == nil { + return nil, nil + } + defaultEndpointSettingsPublicValue, err := projectDefaultEndpointSettingsFromWire(w.DefaultEndpointSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProjectSpec.DefaultEndpointSettings", err) + } + customTagsPublicValue, err := convertSlice(w.CustomTags, projectCustomTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProjectSpec.CustomTags", err) + } + return &ProjectSpec{ + DisplayName: w.DisplayName, + PgVersion: w.PgVersion, + HistoryRetentionDuration: w.HistoryRetentionDuration, + DefaultEndpointSettings: defaultEndpointSettingsPublicValue, + BudgetPolicyId: w.BudgetPolicyId, + CustomTags: customTagsPublicValue, + EnablePgNativeLogin: w.EnablePgNativeLogin, + DefaultBranch: w.DefaultBranch, + }, nil +} + +type projectStatusWire struct { + DisplayName *string `json:"display_name,omitempty"` + PgVersion *int `json:"pg_version,omitempty"` + HistoryRetentionDuration *types.Duration `json:"history_retention_duration,omitempty"` + DefaultEndpointSettings *projectDefaultEndpointSettingsWire `json:"default_endpoint_settings,omitempty"` + BranchLogicalSizeLimitBytes *int64 `json:"branch_logical_size_limit_bytes,omitempty"` + SyntheticStorageSizeBytes *int64 `json:"synthetic_storage_size_bytes,omitempty"` + ComputeLastActiveTime *types.Time `json:"compute_last_active_time,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + CustomTags []projectCustomTagWire `json:"custom_tags,omitempty"` + Owner *string `json:"owner,omitempty"` + EnablePgNativeLogin *bool `json:"enable_pg_native_login,omitempty"` + DefaultBranch *string `json:"default_branch,omitempty"` + ProjectId *string `json:"project_id,omitempty"` +} + +func projectStatusToWire(v *ProjectStatus) (*projectStatusWire, error) { + if v == nil { + return nil, nil + } + defaultEndpointSettingsWireValue, err := projectDefaultEndpointSettingsToWire(v.DefaultEndpointSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProjectStatus.DefaultEndpointSettings", err) + } + customTagsWireValue, err := convertSlice(v.CustomTags, projectCustomTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProjectStatus.CustomTags", err) + } + return &projectStatusWire{ + DisplayName: v.DisplayName, + PgVersion: v.PgVersion, + HistoryRetentionDuration: v.HistoryRetentionDuration, + DefaultEndpointSettings: defaultEndpointSettingsWireValue, + BranchLogicalSizeLimitBytes: v.BranchLogicalSizeLimitBytes, + SyntheticStorageSizeBytes: v.SyntheticStorageSizeBytes, + ComputeLastActiveTime: v.ComputeLastActiveTime, + BudgetPolicyId: v.BudgetPolicyId, + CustomTags: customTagsWireValue, + Owner: v.Owner, + EnablePgNativeLogin: v.EnablePgNativeLogin, + DefaultBranch: v.DefaultBranch, + ProjectId: v.ProjectId, + }, nil +} + +func projectStatusFromWire(w *projectStatusWire) (*ProjectStatus, error) { + if w == nil { + return nil, nil + } + defaultEndpointSettingsPublicValue, err := projectDefaultEndpointSettingsFromWire(w.DefaultEndpointSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProjectStatus.DefaultEndpointSettings", err) + } + customTagsPublicValue, err := convertSlice(w.CustomTags, projectCustomTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProjectStatus.CustomTags", err) + } + return &ProjectStatus{ + DisplayName: w.DisplayName, + PgVersion: w.PgVersion, + HistoryRetentionDuration: w.HistoryRetentionDuration, + DefaultEndpointSettings: defaultEndpointSettingsPublicValue, + BranchLogicalSizeLimitBytes: w.BranchLogicalSizeLimitBytes, + SyntheticStorageSizeBytes: w.SyntheticStorageSizeBytes, + ComputeLastActiveTime: w.ComputeLastActiveTime, + BudgetPolicyId: w.BudgetPolicyId, + CustomTags: customTagsPublicValue, + Owner: w.Owner, + EnablePgNativeLogin: w.EnablePgNativeLogin, + DefaultBranch: w.DefaultBranch, + ProjectId: w.ProjectId, + }, nil +} + +type requestedClaimsWire struct { + PermissionSet RequestedClaims_PermissionSet `json:"permission_set,omitempty"` + Resources []requestedResourceWire `json:"resources,omitempty"` +} + +func requestedClaimsToWire(v *RequestedClaims) (*requestedClaimsWire, error) { + if v == nil { + return nil, nil + } + resourcesWireValue, err := convertSlice(v.Resources, requestedResourceToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RequestedClaims.Resources", err) + } + return &requestedClaimsWire{ + PermissionSet: v.PermissionSet, + Resources: resourcesWireValue, + }, nil +} + +type requestedResourceWire struct { + TableName *string `json:"table_name,omitempty"` +} + +func requestedResourceToWire(v *RequestedResource) (*requestedResourceWire, error) { + if v == nil { + return nil, nil + } + var resourceNameTableNameWire *string + switch value := v.ResourceName.(type) { + case nil: + case *RequestedResource_ResourceName_TableName: + if value != nil { + resourceNameTableNameWire = new(value.TableName) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "RequestedResource.ResourceName", value) + } + return &requestedResourceWire{ + TableName: resourceNameTableNameWire, + }, nil +} + +type roleWire struct { + Name *string `json:"name,omitempty"` + Parent *string `json:"parent,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Spec *role_RoleSpecWire `json:"spec,omitempty"` + Status *role_RoleStatusWire `json:"status,omitempty"` + RoleId *string `json:"role_id,omitempty"` +} + +func roleToWire(v *Role) (*roleWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := role_RoleSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Role.Spec", err) + } + statusWireValue, err := role_RoleStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Role.Status", err) + } + return &roleWire{ + Name: v.Name, + Parent: v.Parent, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + Spec: specWireValue, + Status: statusWireValue, + RoleId: v.RoleId, + }, nil +} + +func roleFromWire(w *roleWire) (*Role, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := role_RoleSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Role.Spec", err) + } + statusPublicValue, err := role_RoleStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Role.Status", err) + } + return &Role{ + Name: w.Name, + Parent: w.Parent, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Spec: specPublicValue, + Status: statusPublicValue, + RoleId: w.RoleId, + }, nil +} + +type role_AttributesWire struct { + Createdb *bool `json:"createdb,omitempty"` + Createrole *bool `json:"createrole,omitempty"` + Bypassrls *bool `json:"bypassrls,omitempty"` +} + +func role_AttributesToWire(v *Role_Attributes) (*role_AttributesWire, error) { + if v == nil { + return nil, nil + } + return &role_AttributesWire{ + Createdb: v.Createdb, + Createrole: v.Createrole, + Bypassrls: v.Bypassrls, + }, nil +} + +func role_AttributesFromWire(w *role_AttributesWire) (*Role_Attributes, error) { + if w == nil { + return nil, nil + } + return &Role_Attributes{ + Createdb: w.Createdb, + Createrole: w.Createrole, + Bypassrls: w.Bypassrls, + }, nil +} + +type role_RoleSpecWire struct { + MembershipRoles []Role_MembershipRole `json:"membership_roles,omitempty"` + IdentityType Role_IdentityType `json:"identity_type,omitempty"` + Attributes *role_AttributesWire `json:"attributes,omitempty"` + AuthMethod Role_AuthMethod `json:"auth_method,omitempty"` + PostgresRole *string `json:"postgres_role,omitempty"` +} + +func role_RoleSpecToWire(v *Role_RoleSpec) (*role_RoleSpecWire, error) { + if v == nil { + return nil, nil + } + attributesWireValue, err := role_AttributesToWire(v.Attributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Role_RoleSpec.Attributes", err) + } + return &role_RoleSpecWire{ + MembershipRoles: v.MembershipRoles, + IdentityType: v.IdentityType, + Attributes: attributesWireValue, + AuthMethod: v.AuthMethod, + PostgresRole: v.PostgresRole, + }, nil +} + +func role_RoleSpecFromWire(w *role_RoleSpecWire) (*Role_RoleSpec, error) { + if w == nil { + return nil, nil + } + attributesPublicValue, err := role_AttributesFromWire(w.Attributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Role_RoleSpec.Attributes", err) + } + return &Role_RoleSpec{ + MembershipRoles: w.MembershipRoles, + IdentityType: w.IdentityType, + Attributes: attributesPublicValue, + AuthMethod: w.AuthMethod, + PostgresRole: w.PostgresRole, + }, nil +} + +type role_RoleStatusWire struct { + MembershipRoles []Role_MembershipRole `json:"membership_roles,omitempty"` + IdentityType Role_IdentityType `json:"identity_type,omitempty"` + Attributes *role_AttributesWire `json:"attributes,omitempty"` + AuthMethod Role_AuthMethod `json:"auth_method,omitempty"` + PostgresRole *string `json:"postgres_role,omitempty"` + RoleId *string `json:"role_id,omitempty"` +} + +func role_RoleStatusToWire(v *Role_RoleStatus) (*role_RoleStatusWire, error) { + if v == nil { + return nil, nil + } + attributesWireValue, err := role_AttributesToWire(v.Attributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Role_RoleStatus.Attributes", err) + } + return &role_RoleStatusWire{ + MembershipRoles: v.MembershipRoles, + IdentityType: v.IdentityType, + Attributes: attributesWireValue, + AuthMethod: v.AuthMethod, + PostgresRole: v.PostgresRole, + RoleId: v.RoleId, + }, nil +} + +func role_RoleStatusFromWire(w *role_RoleStatusWire) (*Role_RoleStatus, error) { + if w == nil { + return nil, nil + } + attributesPublicValue, err := role_AttributesFromWire(w.Attributes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Role_RoleStatus.Attributes", err) + } + return &Role_RoleStatus{ + MembershipRoles: w.MembershipRoles, + IdentityType: w.IdentityType, + Attributes: attributesPublicValue, + AuthMethod: w.AuthMethod, + PostgresRole: w.PostgresRole, + RoleId: w.RoleId, + }, nil +} + +type roleOperationMetadataWire struct { +} + +func roleOperationMetadataFromWire(w *roleOperationMetadataWire) (*RoleOperationMetadata, error) { + if w == nil { + return nil, nil + } + return &RoleOperationMetadata{}, nil +} + +type syncedTableWire struct { + Name *string `json:"name,omitempty"` + Uid *string `json:"uid,omitempty"` + Spec *syncedTable_SyncedTableSpecWire `json:"spec,omitempty"` + Status *syncedTable_SyncedTableStatusWire `json:"status,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + SyncedTableId *string `json:"synced_table_id,omitempty"` +} + +func syncedTableToWire(v *SyncedTable) (*syncedTableWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := syncedTable_SyncedTableSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable.Spec", err) + } + statusWireValue, err := syncedTable_SyncedTableStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable.Status", err) + } + return &syncedTableWire{ + Name: v.Name, + Uid: v.Uid, + Spec: specWireValue, + Status: statusWireValue, + CreateTime: v.CreateTime, + SyncedTableId: v.SyncedTableId, + }, nil +} + +func syncedTableFromWire(w *syncedTableWire) (*SyncedTable, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := syncedTable_SyncedTableSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable.Spec", err) + } + statusPublicValue, err := syncedTable_SyncedTableStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable.Status", err) + } + return &SyncedTable{ + Name: w.Name, + Uid: w.Uid, + Spec: specPublicValue, + Status: statusPublicValue, + CreateTime: w.CreateTime, + SyncedTableId: w.SyncedTableId, + }, nil +} + +type syncedTable_SyncedTableSpecWire struct { + PostgresDatabase *string `json:"postgres_database,omitempty"` + Branch *string `json:"branch,omitempty"` + SchedulingPolicy SyncedTable_SyncedTableSpec_SyncedTableSchedulingPolicy `json:"scheduling_policy,omitempty"` + SourceTableFullName *string `json:"source_table_full_name,omitempty"` + PrimaryKeyColumns []string `json:"primary_key_columns,omitempty"` + TimeseriesKey *string `json:"timeseries_key,omitempty"` + ExistingPipelineId *string `json:"existing_pipeline_id,omitempty"` + CreateDatabaseObjectsIfMissing *bool `json:"create_database_objects_if_missing,omitempty"` + NewPipelineSpec *newPipelineSpecWire `json:"new_pipeline_spec,omitempty"` + AcceleratedSync *bool `json:"accelerated_sync,omitempty"` + TypeOverrides []syncedTable_SyncedTableSpec_TypeOverrideWire `json:"type_overrides,omitempty"` + ExtraColumns []syncedTable_SyncedTableSpec_ExtraColumnWire `json:"extra_columns,omitempty"` +} + +func syncedTable_SyncedTableSpecToWire(v *SyncedTable_SyncedTableSpec) (*syncedTable_SyncedTableSpecWire, error) { + if v == nil { + return nil, nil + } + newPipelineSpecWireValue, err := newPipelineSpecToWire(v.NewPipelineSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable_SyncedTableSpec.NewPipelineSpec", err) + } + typeOverridesWireValue, err := convertSlice(v.TypeOverrides, syncedTable_SyncedTableSpec_TypeOverrideToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable_SyncedTableSpec.TypeOverrides", err) + } + extraColumnsWireValue, err := convertSlice(v.ExtraColumns, syncedTable_SyncedTableSpec_ExtraColumnToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable_SyncedTableSpec.ExtraColumns", err) + } + return &syncedTable_SyncedTableSpecWire{ + PostgresDatabase: v.PostgresDatabase, + Branch: v.Branch, + SchedulingPolicy: v.SchedulingPolicy, + SourceTableFullName: v.SourceTableFullName, + PrimaryKeyColumns: v.PrimaryKeyColumns, + TimeseriesKey: v.TimeseriesKey, + ExistingPipelineId: v.ExistingPipelineId, + CreateDatabaseObjectsIfMissing: v.CreateDatabaseObjectsIfMissing, + NewPipelineSpec: newPipelineSpecWireValue, + AcceleratedSync: v.AcceleratedSync, + TypeOverrides: typeOverridesWireValue, + ExtraColumns: extraColumnsWireValue, + }, nil +} + +func syncedTable_SyncedTableSpecFromWire(w *syncedTable_SyncedTableSpecWire) (*SyncedTable_SyncedTableSpec, error) { + if w == nil { + return nil, nil + } + newPipelineSpecPublicValue, err := newPipelineSpecFromWire(w.NewPipelineSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable_SyncedTableSpec.NewPipelineSpec", err) + } + typeOverridesPublicValue, err := convertSlice(w.TypeOverrides, syncedTable_SyncedTableSpec_TypeOverrideFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable_SyncedTableSpec.TypeOverrides", err) + } + extraColumnsPublicValue, err := convertSlice(w.ExtraColumns, syncedTable_SyncedTableSpec_ExtraColumnFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable_SyncedTableSpec.ExtraColumns", err) + } + return &SyncedTable_SyncedTableSpec{ + PostgresDatabase: w.PostgresDatabase, + Branch: w.Branch, + SchedulingPolicy: w.SchedulingPolicy, + SourceTableFullName: w.SourceTableFullName, + PrimaryKeyColumns: w.PrimaryKeyColumns, + TimeseriesKey: w.TimeseriesKey, + ExistingPipelineId: w.ExistingPipelineId, + CreateDatabaseObjectsIfMissing: w.CreateDatabaseObjectsIfMissing, + NewPipelineSpec: newPipelineSpecPublicValue, + AcceleratedSync: w.AcceleratedSync, + TypeOverrides: typeOverridesPublicValue, + ExtraColumns: extraColumnsPublicValue, + }, nil +} + +type syncedTable_SyncedTableSpec_ExtraColumnWire struct { + ColumnName *string `json:"column_name,omitempty"` + ColumnType *string `json:"column_type,omitempty"` + Maintenance SyncedTable_SyncedTableSpec_ExtraColumn_Maintenance `json:"maintenance,omitempty"` + Compute *string `json:"compute,omitempty"` +} + +func syncedTable_SyncedTableSpec_ExtraColumnToWire(v *SyncedTable_SyncedTableSpec_ExtraColumn) (*syncedTable_SyncedTableSpec_ExtraColumnWire, error) { + if v == nil { + return nil, nil + } + return &syncedTable_SyncedTableSpec_ExtraColumnWire{ + ColumnName: v.ColumnName, + ColumnType: v.ColumnType, + Maintenance: v.Maintenance, + Compute: v.Compute, + }, nil +} + +func syncedTable_SyncedTableSpec_ExtraColumnFromWire(w *syncedTable_SyncedTableSpec_ExtraColumnWire) (*SyncedTable_SyncedTableSpec_ExtraColumn, error) { + if w == nil { + return nil, nil + } + return &SyncedTable_SyncedTableSpec_ExtraColumn{ + ColumnName: w.ColumnName, + ColumnType: w.ColumnType, + Maintenance: w.Maintenance, + Compute: w.Compute, + }, nil +} + +type syncedTable_SyncedTableSpec_TypeOverrideWire struct { + ColumnName *string `json:"column_name,omitempty"` + PgType SyncedTable_SyncedTableSpec_PgSpecificType `json:"pg_type,omitempty"` + Size *int `json:"size,omitempty"` +} + +func syncedTable_SyncedTableSpec_TypeOverrideToWire(v *SyncedTable_SyncedTableSpec_TypeOverride) (*syncedTable_SyncedTableSpec_TypeOverrideWire, error) { + if v == nil { + return nil, nil + } + return &syncedTable_SyncedTableSpec_TypeOverrideWire{ + ColumnName: v.ColumnName, + PgType: v.PgType, + Size: v.Size, + }, nil +} + +func syncedTable_SyncedTableSpec_TypeOverrideFromWire(w *syncedTable_SyncedTableSpec_TypeOverrideWire) (*SyncedTable_SyncedTableSpec_TypeOverride, error) { + if w == nil { + return nil, nil + } + return &SyncedTable_SyncedTableSpec_TypeOverride{ + ColumnName: w.ColumnName, + PgType: w.PgType, + Size: w.Size, + }, nil +} + +type syncedTable_SyncedTableStatusWire struct { + Message *string `json:"message,omitempty"` + DetailedState SyncedTableState `json:"detailed_state,omitempty"` + LastSync *syncedTablePositionWire `json:"last_sync,omitempty"` + OngoingSyncProgress *syncedTablePipelineProgressWire `json:"ongoing_sync_progress,omitempty"` + ProvisioningPhase ProvisioningPhase `json:"provisioning_phase,omitempty"` + LastProcessedCommitVersion *int64 `json:"last_processed_commit_version,omitempty"` + LastSyncTime *types.Time `json:"last_sync_time,omitempty"` + PipelineId *string `json:"pipeline_id,omitempty"` + UnityCatalogProvisioningState ProvisioningInfo_State `json:"unity_catalog_provisioning_state,omitempty"` + Project *string `json:"project,omitempty"` +} + +func syncedTable_SyncedTableStatusToWire(v *SyncedTable_SyncedTableStatus) (*syncedTable_SyncedTableStatusWire, error) { + if v == nil { + return nil, nil + } + lastSyncWireValue, err := syncedTablePositionToWire(v.LastSync) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable_SyncedTableStatus.LastSync", err) + } + ongoingSyncProgressWireValue, err := syncedTablePipelineProgressToWire(v.OngoingSyncProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable_SyncedTableStatus.OngoingSyncProgress", err) + } + return &syncedTable_SyncedTableStatusWire{ + Message: v.Message, + DetailedState: v.DetailedState, + LastSync: lastSyncWireValue, + OngoingSyncProgress: ongoingSyncProgressWireValue, + ProvisioningPhase: v.ProvisioningPhase, + LastProcessedCommitVersion: v.LastProcessedCommitVersion, + LastSyncTime: v.LastSyncTime, + PipelineId: v.PipelineId, + UnityCatalogProvisioningState: v.UnityCatalogProvisioningState, + Project: v.Project, + }, nil +} + +func syncedTable_SyncedTableStatusFromWire(w *syncedTable_SyncedTableStatusWire) (*SyncedTable_SyncedTableStatus, error) { + if w == nil { + return nil, nil + } + lastSyncPublicValue, err := syncedTablePositionFromWire(w.LastSync) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable_SyncedTableStatus.LastSync", err) + } + ongoingSyncProgressPublicValue, err := syncedTablePipelineProgressFromWire(w.OngoingSyncProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTable_SyncedTableStatus.OngoingSyncProgress", err) + } + return &SyncedTable_SyncedTableStatus{ + Message: w.Message, + DetailedState: w.DetailedState, + LastSync: lastSyncPublicValue, + OngoingSyncProgress: ongoingSyncProgressPublicValue, + ProvisioningPhase: w.ProvisioningPhase, + LastProcessedCommitVersion: w.LastProcessedCommitVersion, + LastSyncTime: w.LastSyncTime, + PipelineId: w.PipelineId, + UnityCatalogProvisioningState: w.UnityCatalogProvisioningState, + Project: w.Project, + }, nil +} + +type syncedTableOperationMetadataWire struct { +} + +func syncedTableOperationMetadataFromWire(w *syncedTableOperationMetadataWire) (*SyncedTableOperationMetadata, error) { + if w == nil { + return nil, nil + } + return &SyncedTableOperationMetadata{}, nil +} + +type syncedTablePipelineProgressWire struct { + LatestVersionCurrentlyProcessing *int64 `json:"latest_version_currently_processing,omitempty"` + SyncedRowCount *int64 `json:"synced_row_count,omitempty"` + TotalRowCount *int64 `json:"total_row_count,omitempty"` + SyncProgressCompletion *float64 `json:"sync_progress_completion,omitempty"` + EstimatedCompletionTimeSeconds *float64 `json:"estimated_completion_time_seconds,omitempty"` +} + +func syncedTablePipelineProgressToWire(v *SyncedTablePipelineProgress) (*syncedTablePipelineProgressWire, error) { + if v == nil { + return nil, nil + } + return &syncedTablePipelineProgressWire{ + LatestVersionCurrentlyProcessing: v.LatestVersionCurrentlyProcessing, + SyncedRowCount: v.SyncedRowCount, + TotalRowCount: v.TotalRowCount, + SyncProgressCompletion: v.SyncProgressCompletion, + EstimatedCompletionTimeSeconds: v.EstimatedCompletionTimeSeconds, + }, nil +} + +func syncedTablePipelineProgressFromWire(w *syncedTablePipelineProgressWire) (*SyncedTablePipelineProgress, error) { + if w == nil { + return nil, nil + } + return &SyncedTablePipelineProgress{ + LatestVersionCurrentlyProcessing: w.LatestVersionCurrentlyProcessing, + SyncedRowCount: w.SyncedRowCount, + TotalRowCount: w.TotalRowCount, + SyncProgressCompletion: w.SyncProgressCompletion, + EstimatedCompletionTimeSeconds: w.EstimatedCompletionTimeSeconds, + }, nil +} + +type syncedTablePositionWire struct { + SyncStartTime *types.Time `json:"sync_start_time,omitempty"` + SyncEndTime *types.Time `json:"sync_end_time,omitempty"` + DeltaTableSyncInfo *deltaTableSyncInfoWire `json:"delta_table_sync_info,omitempty"` +} + +func syncedTablePositionToWire(v *SyncedTablePosition) (*syncedTablePositionWire, error) { + if v == nil { + return nil, nil + } + var sourceSyncInfoDeltaTableSyncInfoWire *deltaTableSyncInfoWire + switch value := v.SourceSyncInfo.(type) { + case nil: + case *SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo: + if value != nil { + sourceSyncInfoDeltaTableSyncInfoConverted, err := deltaTableSyncInfoToWire(&value.DeltaTableSyncInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTablePosition.SourceSyncInfo.DeltaTableSyncInfo", err) + } + sourceSyncInfoDeltaTableSyncInfoWire = sourceSyncInfoDeltaTableSyncInfoConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "SyncedTablePosition.SourceSyncInfo", value) + } + return &syncedTablePositionWire{ + SyncStartTime: v.SyncStartTime, + SyncEndTime: v.SyncEndTime, + DeltaTableSyncInfo: sourceSyncInfoDeltaTableSyncInfoWire, + }, nil +} + +func syncedTablePositionFromWire(w *syncedTablePositionWire) (*SyncedTablePosition, error) { + if w == nil { + return nil, nil + } + sourceSyncInfoMembers := 0 + if w.DeltaTableSyncInfo != nil { + sourceSyncInfoMembers++ + } + if sourceSyncInfoMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "SyncedTablePosition.SourceSyncInfo") + } + var sourceSyncInfoSelection isSyncedTablePosition_SourceSyncInfo + switch { + case w.DeltaTableSyncInfo != nil: + sourceSyncInfoDeltaTableSyncInfoConverted, err := deltaTableSyncInfoFromWire(w.DeltaTableSyncInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SyncedTablePosition.SourceSyncInfo.DeltaTableSyncInfo", err) + } + sourceSyncInfoSelection = &SyncedTablePosition_SourceSyncInfo_DeltaTableSyncInfo{DeltaTableSyncInfo: *sourceSyncInfoDeltaTableSyncInfoConverted} + } + return &SyncedTablePosition{ + SyncStartTime: w.SyncStartTime, + SyncEndTime: w.SyncEndTime, + SourceSyncInfo: sourceSyncInfoSelection, + }, nil +} + +type undeleteBranchRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func undeleteBranchRequestToWire(v *UndeleteBranchRequest) (*undeleteBranchRequestWire, error) { + if v == nil { + return nil, nil + } + return &undeleteBranchRequestWire{ + Name: v.Name, + }, nil +} + +type undeleteProjectRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func undeleteProjectRequestToWire(v *UndeleteProjectRequest) (*undeleteProjectRequestWire, error) { + if v == nil { + return nil, nil + } + return &undeleteProjectRequestWire{ + Name: v.Name, + }, nil +} + +type updateBranchRequestWire struct { + Branch *branchWire `json:"branch,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateBranchRequestToWire(v *UpdateBranchRequest) (*updateBranchRequestWire, error) { + if v == nil { + return nil, nil + } + branchWireValue, err := branchToWire(v.Branch) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateBranchRequest.Branch", err) + } + return &updateBranchRequestWire{ + Branch: branchWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateDataApiRequestWire struct { + DataApi *dataApiWire `json:"data_api,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateDataApiRequestToWire(v *UpdateDataApiRequest) (*updateDataApiRequestWire, error) { + if v == nil { + return nil, nil + } + dataApiWireValue, err := dataApiToWire(v.DataApi) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateDataApiRequest.DataApi", err) + } + return &updateDataApiRequestWire{ + DataApi: dataApiWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateDatabaseRequestWire struct { + Database *databaseWire `json:"database,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateDatabaseRequestToWire(v *UpdateDatabaseRequest) (*updateDatabaseRequestWire, error) { + if v == nil { + return nil, nil + } + databaseWireValue, err := databaseToWire(v.Database) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateDatabaseRequest.Database", err) + } + return &updateDatabaseRequestWire{ + Database: databaseWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateEndpointRequestWire struct { + Endpoint *endpointWire `json:"endpoint,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateEndpointRequestToWire(v *UpdateEndpointRequest) (*updateEndpointRequestWire, error) { + if v == nil { + return nil, nil + } + endpointWireValue, err := endpointToWire(v.Endpoint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateEndpointRequest.Endpoint", err) + } + return &updateEndpointRequestWire{ + Endpoint: endpointWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateProjectRequestWire struct { + Project *projectWire `json:"project,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateProjectRequestToWire(v *UpdateProjectRequest) (*updateProjectRequestWire, error) { + if v == nil { + return nil, nil + } + projectWireValue, err := projectToWire(v.Project) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateProjectRequest.Project", err) + } + return &updateProjectRequestWire{ + Project: projectWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateRoleRequestWire struct { + Role *roleWire `json:"role,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateRoleRequestToWire(v *UpdateRoleRequest) (*updateRoleRequestWire, error) { + if v == nil { + return nil, nil + } + roleWireValue, err := roleToWire(v.Role) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRoleRequest.Role", err) + } + return &updateRoleRequestWire{ + Role: roleWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/queries/.package.json b/queries/.package.json new file mode 100644 index 0000000..6900691 --- /dev/null +++ b/queries/.package.json @@ -0,0 +1,3 @@ +{ + "package": "queries" +} diff --git a/queries/CHANGELOG.md b/queries/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/queries/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/queries/README.md b/queries/README.md new file mode 100644 index 0000000..f0a164a --- /dev/null +++ b/queries/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/queries + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/queries@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/queries/v1" + +client, err := queries.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/queries/go.mod b/queries/go.mod new file mode 100644 index 0000000..d6882c6 --- /dev/null +++ b/queries/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/queries + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/queries/internal/version.go b/queries/internal/version.go new file mode 100644 index 0000000..73e2776 --- /dev/null +++ b/queries/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-queries" + +const Version = "0.0.1-dev.1" diff --git a/queries/v1/client.go b/queries/v1/client.go new file mode 100755 index 0000000..3430c0f --- /dev/null +++ b/queries/v1/client.go @@ -0,0 +1,555 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package queries + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/queries/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a query. +func (c *internalClient) CreateQuery(ctx context.Context, req *CreateQueryRequest, opts ...call.Option) (*Query, error) { + wireReq, err := createQueryRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/sql/queries" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Query + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp queryWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = queryFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a query. +func (c *internalClient) GetQuery(ctx context.Context, req *GetQueryRequest, opts ...call.Option) (*Query, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/queries/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Query + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp queryWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = queryFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a list of queries accessible to the user, ordered by creation time. +// **Warning:** Calling this API concurrently 10 or more times could result in +// throttling, service degradation, or a temporary ban. +func (c *internalClient) ListQueries(ctx context.Context, req *ListQueriesRequest, opts ...call.Option) (*ListQueriesResponse, error) { + wireReq, err := listQueriesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/sql/queries" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListQueriesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listQueriesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listQueriesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListQueriesIter returns an iterator that iterates +// over the results of ListQueries. +// +// For example: +// +// for item, err := range c.ListQueriesIter(ctx, &ListQueriesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListQueries call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListQueries directly. +func (c *internalClient) ListQueriesIter(ctx context.Context, req *ListQueriesRequest, opts ...call.Option) iter.Seq2[*ListQueryObjectsResponseQuery, error] { + return func(yield func(*ListQueryObjectsResponseQuery, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListQueriesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListQueries(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Results { + if !yield(&resp.Results[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Gets a list of visualizations on a query. +func (c *internalClient) ListVisualizationsForQuery(ctx context.Context, req *ListVisualizationsForQueryRequest, opts ...call.Option) (*ListVisualizationsForQueryResponse, error) { + wireReq, err := listVisualizationsForQueryRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/queries/") + pb.singleSegment(*req.Id) + pb.literal("/visualizations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListVisualizationsForQueryResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listVisualizationsForQueryResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listVisualizationsForQueryResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListVisualizationsForQueryIter returns an iterator that iterates +// over the results of ListVisualizationsForQuery. +// +// For example: +// +// for item, err := range c.ListVisualizationsForQueryIter(ctx, &ListVisualizationsForQueryRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListVisualizationsForQuery call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListVisualizationsForQuery directly. +func (c *internalClient) ListVisualizationsForQueryIter(ctx context.Context, req *ListVisualizationsForQueryRequest, opts ...call.Option) iter.Seq2[*Visualization, error] { + return func(yield func(*Visualization, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListVisualizationsForQueryRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListVisualizationsForQuery(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Results { + if !yield(&resp.Results[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Moves a query to the trash. Trashed queries immediately disappear from +// searches and list views, and cannot be used for alerts. You can restore a +// trashed query through the UI. A trashed query is permanently deleted after 30 +// days. +func (c *internalClient) TrashQuery(ctx context.Context, req *TrashQueryRequest, opts ...call.Option) (*Empty, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/queries/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Empty + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &Empty{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a query. +func (c *internalClient) UpdateQuery(ctx context.Context, req *UpdateQueryRequest, opts ...call.Option) (*Query, error) { + wireReq, err := updateQueryRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/queries/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Query + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp queryWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = queryFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/queries/v1/genhelper.go b/queries/v1/genhelper.go new file mode 100755 index 0000000..cc64b69 --- /dev/null +++ b/queries/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package queries + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/queries/v1/model.go b/queries/v1/model.go new file mode 100755 index 0000000..bd3bc7f --- /dev/null +++ b/queries/v1/model.go @@ -0,0 +1,450 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package queries + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type DatePrecision string + +const ( + DatePrecision_Unspecified DatePrecision = "" + DatePrecision_DayPrecision DatePrecision = "DAY_PRECISION" + DatePrecision_MinutePrecision DatePrecision = "MINUTE_PRECISION" + DatePrecision_SecondPrecision DatePrecision = "SECOND_PRECISION" +) + +type LifecycleState string + +const ( + LifecycleState_Unspecified LifecycleState = "" + LifecycleState_Active LifecycleState = "ACTIVE" + LifecycleState_Trashed LifecycleState = "TRASHED" +) + +type RunAsMode string + +const ( + RunAsMode_Unspecified RunAsMode = "" + RunAsMode_Owner RunAsMode = "OWNER" + RunAsMode_Viewer RunAsMode = "VIEWER" +) + +type DateRangeValue_DynamicDateRange string + +const ( + DateRangeValue_DynamicDateRange_Unspecified DateRangeValue_DynamicDateRange = "" + DateRangeValue_DynamicDateRange_Today DateRangeValue_DynamicDateRange = "TODAY" + DateRangeValue_DynamicDateRange_Yesterday DateRangeValue_DynamicDateRange = "YESTERDAY" + DateRangeValue_DynamicDateRange_ThisWeek DateRangeValue_DynamicDateRange = "THIS_WEEK" + DateRangeValue_DynamicDateRange_ThisMonth DateRangeValue_DynamicDateRange = "THIS_MONTH" + DateRangeValue_DynamicDateRange_ThisYear DateRangeValue_DynamicDateRange = "THIS_YEAR" + DateRangeValue_DynamicDateRange_LastWeek DateRangeValue_DynamicDateRange = "LAST_WEEK" + DateRangeValue_DynamicDateRange_LastMonth DateRangeValue_DynamicDateRange = "LAST_MONTH" + DateRangeValue_DynamicDateRange_LastYear DateRangeValue_DynamicDateRange = "LAST_YEAR" + DateRangeValue_DynamicDateRange_LastHour DateRangeValue_DynamicDateRange = "LAST_HOUR" + DateRangeValue_DynamicDateRange_Last8Hours DateRangeValue_DynamicDateRange = "LAST_8_HOURS" + DateRangeValue_DynamicDateRange_Last24Hours DateRangeValue_DynamicDateRange = "LAST_24_HOURS" + DateRangeValue_DynamicDateRange_Last7Days DateRangeValue_DynamicDateRange = "LAST_7_DAYS" + DateRangeValue_DynamicDateRange_Last14Days DateRangeValue_DynamicDateRange = "LAST_14_DAYS" + DateRangeValue_DynamicDateRange_Last30Days DateRangeValue_DynamicDateRange = "LAST_30_DAYS" + DateRangeValue_DynamicDateRange_Last60Days DateRangeValue_DynamicDateRange = "LAST_60_DAYS" + DateRangeValue_DynamicDateRange_Last90Days DateRangeValue_DynamicDateRange = "LAST_90_DAYS" + DateRangeValue_DynamicDateRange_Last12Months DateRangeValue_DynamicDateRange = "LAST_12_MONTHS" +) + +type DateValue_DynamicDate string + +const ( + DateValue_DynamicDate_Unspecified DateValue_DynamicDate = "" + DateValue_DynamicDate_Now DateValue_DynamicDate = "NOW" + DateValue_DynamicDate_Yesterday DateValue_DynamicDate = "YESTERDAY" +) + +type CreateQueryRequest struct { + Query *CreateQueryRequestQuery + // If true, automatically resolve query display name conflicts. Otherwise, fail + // the request if the query's display name conflicts with an existing query's + // display name. + AutoResolveDisplayName *bool +} + +type CreateQueryRequestQuery struct { + // UUID identifying the query. + Id *string + // Display name of the query that appears in list views, widget headings, and on + // the query page. + DisplayName *string + // General description that conveys additional information about this query such + // as usage notes. + Description *string + // Username of the user that owns the query. + OwnerUserName *string + // ID of the SQL warehouse attached to the query. + WarehouseId *string + // Text of the query to be run. + QueryText *string + // Sets the "Run as" role for the object. + RunAsMode RunAsMode + // Indicates whether the query is trashed. + LifecycleState LifecycleState + // Username of the user who last saved changes to this query. + LastModifierUserName *string + // Workspace path of the workspace folder containing the object. + ParentPath *string + Tags []string + // Timestamp when this query was created. + CreateTime *types.Time + // Timestamp when this query was last updated. + UpdateTime *types.Time + // List of query parameter definitions. + Parameters []QueryParameter + // Whether to apply a 1000 row limit to the query result. + ApplyAutoLimit *bool + // Name of the catalog where this query will be executed. + Catalog *string + // Name of the schema where this query will be executed. + Schema *string +} + +type DateRange struct { + Start *string + End *string +} + +type DateRangeValue struct { + Value isDateRangeValue_Value + // Date-time precision to format the value into when the query is run. Defaults + // to DAY_PRECISION (YYYY-MM-DD). + Precision DatePrecision + StartDayOfWeek *int +} + +type isDateRangeValue_Value interface { + isDateRangeValue_Value() +} + +// DateRangeValue_Value_DynamicDateRangeValue selects DynamicDateRangeValue for DateRangeValue.Value. +// Dynamic date-time range value based on current date-time. +type DateRangeValue_Value_DynamicDateRangeValue struct { + DynamicDateRangeValue DateRangeValue_DynamicDateRange +} + +func (*DateRangeValue_Value_DynamicDateRangeValue) isDateRangeValue_Value() {} + +// DateRangeValue_Value_DateRangeValue selects DateRangeValue for DateRangeValue.Value. +// Manually specified date-time range value. +type DateRangeValue_Value_DateRangeValue struct { + DateRangeValue DateRange +} + +func (*DateRangeValue_Value_DateRangeValue) isDateRangeValue_Value() {} + +type DateValue struct { + Value isDateValue_Value + // Date-time precision to format the value into when the query is run. Defaults + // to DAY_PRECISION (YYYY-MM-DD). + Precision DatePrecision +} + +type isDateValue_Value interface { + isDateValue_Value() +} + +// DateValue_Value_DynamicDateValue selects DynamicDateValue for DateValue.Value. +// Dynamic date-time value based on current date-time. +type DateValue_Value_DynamicDateValue struct { + DynamicDateValue DateValue_DynamicDate +} + +func (*DateValue_Value_DynamicDateValue) isDateValue_Value() {} + +// DateValue_Value_DateValue selects DateValue for DateValue.Value. +// Manually specified date-time value. +type DateValue_Value_DateValue struct { + DateValue string +} + +func (*DateValue_Value_DateValue) isDateValue_Value() {} + +// Represents an empty message, similar to google.protobuf.Empty, which is not +// available in the firm right now.. +type Empty struct { +} + +type EnumValue struct { + // List of selected query parameter values. + Values []string + // List of valid query parameter values, newline delimited. + EnumOptions *string + // If specified, allows multiple values to be selected for this parameter. + MultiValuesOptions *MultiValuesOptions +} + +type GetQueryRequest struct { + Id *string +} + +type ListQueriesRequest struct { + PageToken *string + PageSize *int +} + +type ListQueriesResponse struct { + Results []ListQueryObjectsResponseQuery + NextPageToken *string +} + +type ListQueryObjectsResponseQuery struct { + // UUID identifying the query. + Id *string + // Display name of the query that appears in list views, widget headings, and on + // the query page. + DisplayName *string + // General description that conveys additional information about this query such + // as usage notes. + Description *string + // Username of the user that owns the query. + OwnerUserName *string + // ID of the SQL warehouse attached to the query. + WarehouseId *string + // Text of the query to be run. + QueryText *string + // Sets the "Run as" role for the object. + RunAsMode RunAsMode + // Indicates whether the query is trashed. + LifecycleState LifecycleState + // Username of the user who last saved changes to this query. + LastModifierUserName *string + // Workspace path of the workspace folder containing the object. + ParentPath *string + Tags []string + // Timestamp when this query was created. + CreateTime *types.Time + // Timestamp when this query was last updated. + UpdateTime *types.Time + // List of query parameter definitions. + Parameters []QueryParameter + // Whether to apply a 1000 row limit to the query result. + ApplyAutoLimit *bool + // Name of the catalog where this query will be executed. + Catalog *string + // Name of the schema where this query will be executed. + Schema *string +} + +type ListVisualizationsForQueryRequest struct { + Id *string + PageToken *string + PageSize *int +} + +type ListVisualizationsForQueryResponse struct { + Results []Visualization + NextPageToken *string +} + +type MultiValuesOptions struct { + // Character that prefixes each selected parameter value. + Prefix *string + // Character that separates each selected parameter value. Defaults to a comma. + Separator *string + // Character that suffixes each selected parameter value. + Suffix *string +} + +type NumericValue struct { + Value *float64 +} + +type Query struct { + // UUID identifying the query. + Id *string + // Display name of the query that appears in list views, widget headings, and on + // the query page. + DisplayName *string + // General description that conveys additional information about this query such + // as usage notes. + Description *string + // Username of the user that owns the query. + OwnerUserName *string + // ID of the SQL warehouse attached to the query. + WarehouseId *string + // Text of the query to be run. + QueryText *string + // Sets the "Run as" role for the object. + RunAsMode RunAsMode + // Indicates whether the query is trashed. + LifecycleState LifecycleState + // Username of the user who last saved changes to this query. + LastModifierUserName *string + // Workspace path of the workspace folder containing the object. + ParentPath *string + Tags []string + // Timestamp when this query was created. + CreateTime *types.Time + // Timestamp when this query was last updated. + UpdateTime *types.Time + // List of query parameter definitions. + Parameters []QueryParameter + // Whether to apply a 1000 row limit to the query result. + ApplyAutoLimit *bool + // Name of the catalog where this query will be executed. + Catalog *string + // Name of the schema where this query will be executed. + Schema *string +} + +type QueryBackedValue struct { + // List of selected query parameter values. + Values []string + // UUID of the query that provides the parameter values. + QueryId *string + // If specified, allows multiple values to be selected for this parameter. + MultiValuesOptions *MultiValuesOptions +} + +type QueryParameter struct { + // Text displayed in the user-facing parameter widget in the UI. + Title *string + // Literal parameter marker that appears between double curly braces in the + // query text. + Name *string + // Only one of the following fields may be set, depending on the type of + // parameter. + ParameterValue isQueryParameter_ParameterValue +} + +type isQueryParameter_ParameterValue interface { + isQueryParameter_ParameterValue() +} + +// QueryParameter_ParameterValue_TextValue selects TextValue for QueryParameter.ParameterValue. +// Text query parameter value. +type QueryParameter_ParameterValue_TextValue struct { + TextValue TextValue +} + +func (*QueryParameter_ParameterValue_TextValue) isQueryParameter_ParameterValue() {} + +// QueryParameter_ParameterValue_NumericValue selects NumericValue for QueryParameter.ParameterValue. +// Numeric query parameter value. +type QueryParameter_ParameterValue_NumericValue struct { + NumericValue NumericValue +} + +func (*QueryParameter_ParameterValue_NumericValue) isQueryParameter_ParameterValue() {} + +// QueryParameter_ParameterValue_EnumValue selects EnumValue for QueryParameter.ParameterValue. +// Dropdown query parameter value. +type QueryParameter_ParameterValue_EnumValue struct { + EnumValue EnumValue +} + +func (*QueryParameter_ParameterValue_EnumValue) isQueryParameter_ParameterValue() {} + +// QueryParameter_ParameterValue_DateValue selects DateValue for QueryParameter.ParameterValue. +// Date query parameter value. Can only specify one of `dynamic_date_value` or +// `date_value`. +type QueryParameter_ParameterValue_DateValue struct { + DateValue DateValue +} + +func (*QueryParameter_ParameterValue_DateValue) isQueryParameter_ParameterValue() {} + +// QueryParameter_ParameterValue_DateRangeValue selects DateRangeValue for QueryParameter.ParameterValue. +// Date-range query parameter value. Can only specify one of +// `dynamic_date_range_value` or `date_range_value`. +type QueryParameter_ParameterValue_DateRangeValue struct { + DateRangeValue DateRangeValue +} + +func (*QueryParameter_ParameterValue_DateRangeValue) isQueryParameter_ParameterValue() {} + +// QueryParameter_ParameterValue_QueryBackedValue selects QueryBackedValue for QueryParameter.ParameterValue. +// Query-based dropdown query parameter value. +type QueryParameter_ParameterValue_QueryBackedValue struct { + QueryBackedValue QueryBackedValue +} + +func (*QueryParameter_ParameterValue_QueryBackedValue) isQueryParameter_ParameterValue() {} + +type TextValue struct { + Value *string +} + +type TrashQueryRequest struct { + Id *string +} + +type UpdateQueryRequest struct { + Query *UpdateQueryRequestQuery + UpdateMask *types.FieldMask[UpdateQueryRequestQuery] + Id *string + // If true, automatically resolve alert display name conflicts. Otherwise, fail + // the request if the alert's display name conflicts with an existing alert's + // display name. + AutoResolveDisplayName *bool +} + +type UpdateQueryRequestQuery struct { + // UUID identifying the query. + Id *string `fieldmask:"id"` + // Display name of the query that appears in list views, widget headings, and on + // the query page. + DisplayName *string `fieldmask:"display_name"` + // General description that conveys additional information about this query such + // as usage notes. + Description *string `fieldmask:"description"` + // Username of the user that owns the query. + OwnerUserName *string `fieldmask:"owner_user_name"` + // ID of the SQL warehouse attached to the query. + WarehouseId *string `fieldmask:"warehouse_id"` + // Text of the query to be run. + QueryText *string `fieldmask:"query_text"` + // Sets the "Run as" role for the object. + RunAsMode RunAsMode `fieldmask:"run_as_mode"` + // Indicates whether the query is trashed. + LifecycleState LifecycleState `fieldmask:"lifecycle_state"` + // Username of the user who last saved changes to this query. + LastModifierUserName *string `fieldmask:"last_modifier_user_name"` + // Workspace path of the workspace folder containing the object. + ParentPath *string `fieldmask:"parent_path"` + Tags []string `fieldmask:"tags"` + // Timestamp when this query was created. + CreateTime *types.Time `fieldmask:"create_time"` + // Timestamp when this query was last updated. + UpdateTime *types.Time `fieldmask:"update_time"` + // List of query parameter definitions. + Parameters []QueryParameter `fieldmask:"parameters"` + // Whether to apply a 1000 row limit to the query result. + ApplyAutoLimit *bool `fieldmask:"apply_auto_limit"` + // Name of the catalog where this query will be executed. + Catalog *string `fieldmask:"catalog"` + // Name of the schema where this query will be executed. + Schema *string `fieldmask:"schema"` +} + +type Visualization struct { + // UUID identifying the visualization. + Id *string + // The display name of the visualization. + DisplayName *string + // The type of visualization: counter, table, funnel, and so on. + Type *string + // The timestamp indicating when the visualization was created. + CreateTime *types.Time + // The timestamp indicating when the visualization was updated. + UpdateTime *types.Time + // The visualization query plan varies widely from one visualization type to the + // next and is unsupported. Databricks does not recommend modifying the + // visualization query plan directly. + SerializedQueryPlan *string + // The visualization options varies widely from one visualization type to the + // next and is unsupported. Databricks does not recommend modifying + // visualization options directly. + SerializedOptions *string + // UUID of the query that the visualization is attached to. + QueryId *string +} diff --git a/queries/v1/wire.go b/queries/v1/wire.go new file mode 100755 index 0000000..77260fb --- /dev/null +++ b/queries/v1/wire.go @@ -0,0 +1,823 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package queries + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createQueryRequestWire struct { + Query *createQueryRequestQueryWire `json:"query,omitempty"` + AutoResolveDisplayName *bool `json:"auto_resolve_display_name,omitempty"` +} + +func createQueryRequestToWire(v *CreateQueryRequest) (*createQueryRequestWire, error) { + if v == nil { + return nil, nil + } + queryWireValue, err := createQueryRequestQueryToWire(v.Query) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateQueryRequest.Query", err) + } + return &createQueryRequestWire{ + Query: queryWireValue, + AutoResolveDisplayName: v.AutoResolveDisplayName, + }, nil +} + +type createQueryRequestQueryWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Description *string `json:"description,omitempty"` + OwnerUserName *string `json:"owner_user_name,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + QueryText *string `json:"query_text,omitempty"` + RunAsMode RunAsMode `json:"run_as_mode,omitempty"` + LifecycleState LifecycleState `json:"lifecycle_state,omitempty"` + LastModifierUserName *string `json:"last_modifier_user_name,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + Tags []string `json:"tags,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Parameters []queryParameterWire `json:"parameters,omitempty"` + ApplyAutoLimit *bool `json:"apply_auto_limit,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Schema *string `json:"schema,omitempty"` +} + +func createQueryRequestQueryToWire(v *CreateQueryRequestQuery) (*createQueryRequestQueryWire, error) { + if v == nil { + return nil, nil + } + parametersWireValue, err := convertSlice(v.Parameters, queryParameterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateQueryRequestQuery.Parameters", err) + } + return &createQueryRequestQueryWire{ + Id: v.Id, + DisplayName: v.DisplayName, + Description: v.Description, + OwnerUserName: v.OwnerUserName, + WarehouseId: v.WarehouseId, + QueryText: v.QueryText, + RunAsMode: v.RunAsMode, + LifecycleState: v.LifecycleState, + LastModifierUserName: v.LastModifierUserName, + ParentPath: v.ParentPath, + Tags: v.Tags, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + Parameters: parametersWireValue, + ApplyAutoLimit: v.ApplyAutoLimit, + Catalog: v.Catalog, + Schema: v.Schema, + }, nil +} + +type dateRangeWire struct { + Start *string `json:"start,omitempty"` + End *string `json:"end,omitempty"` +} + +func dateRangeToWire(v *DateRange) (*dateRangeWire, error) { + if v == nil { + return nil, nil + } + return &dateRangeWire{ + Start: v.Start, + End: v.End, + }, nil +} + +func dateRangeFromWire(w *dateRangeWire) (*DateRange, error) { + if w == nil { + return nil, nil + } + return &DateRange{ + Start: w.Start, + End: w.End, + }, nil +} + +type dateRangeValueWire struct { + DynamicDateRangeValue DateRangeValue_DynamicDateRange `json:"dynamic_date_range_value,omitempty"` + DateRangeValue *dateRangeWire `json:"date_range_value,omitempty"` + Precision DatePrecision `json:"precision,omitempty"` + StartDayOfWeek *int `json:"start_day_of_week,omitempty"` +} + +func dateRangeValueToWire(v *DateRangeValue) (*dateRangeValueWire, error) { + if v == nil { + return nil, nil + } + var valueDynamicDateRangeValueWire DateRangeValue_DynamicDateRange + var valueDateRangeValueWire *dateRangeWire + switch value := v.Value.(type) { + case nil: + case *DateRangeValue_Value_DynamicDateRangeValue: + if value != nil { + valueDynamicDateRangeValueWire = value.DynamicDateRangeValue + } + case *DateRangeValue_Value_DateRangeValue: + if value != nil { + valueDateRangeValueConverted, err := dateRangeToWire(&value.DateRangeValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DateRangeValue.Value.DateRangeValue", err) + } + valueDateRangeValueWire = valueDateRangeValueConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "DateRangeValue.Value", value) + } + return &dateRangeValueWire{ + DynamicDateRangeValue: valueDynamicDateRangeValueWire, + DateRangeValue: valueDateRangeValueWire, + Precision: v.Precision, + StartDayOfWeek: v.StartDayOfWeek, + }, nil +} + +func dateRangeValueFromWire(w *dateRangeValueWire) (*DateRangeValue, error) { + if w == nil { + return nil, nil + } + valueMembers := 0 + if w.DynamicDateRangeValue != "" { + valueMembers++ + } + if w.DateRangeValue != nil { + valueMembers++ + } + if valueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "DateRangeValue.Value") + } + var valueSelection isDateRangeValue_Value + switch { + case w.DynamicDateRangeValue != "": + valueSelection = &DateRangeValue_Value_DynamicDateRangeValue{DynamicDateRangeValue: w.DynamicDateRangeValue} + case w.DateRangeValue != nil: + valueDateRangeValueConverted, err := dateRangeFromWire(w.DateRangeValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DateRangeValue.Value.DateRangeValue", err) + } + valueSelection = &DateRangeValue_Value_DateRangeValue{DateRangeValue: *valueDateRangeValueConverted} + } + return &DateRangeValue{ + Precision: w.Precision, + StartDayOfWeek: w.StartDayOfWeek, + Value: valueSelection, + }, nil +} + +type dateValueWire struct { + DynamicDateValue DateValue_DynamicDate `json:"dynamic_date_value,omitempty"` + DateValue *string `json:"date_value,omitempty"` + Precision DatePrecision `json:"precision,omitempty"` +} + +func dateValueToWire(v *DateValue) (*dateValueWire, error) { + if v == nil { + return nil, nil + } + var valueDynamicDateValueWire DateValue_DynamicDate + var valueDateValueWire *string + switch value := v.Value.(type) { + case nil: + case *DateValue_Value_DynamicDateValue: + if value != nil { + valueDynamicDateValueWire = value.DynamicDateValue + } + case *DateValue_Value_DateValue: + if value != nil { + valueDateValueWire = new(value.DateValue) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "DateValue.Value", value) + } + return &dateValueWire{ + DynamicDateValue: valueDynamicDateValueWire, + DateValue: valueDateValueWire, + Precision: v.Precision, + }, nil +} + +func dateValueFromWire(w *dateValueWire) (*DateValue, error) { + if w == nil { + return nil, nil + } + valueMembers := 0 + if w.DynamicDateValue != "" { + valueMembers++ + } + if w.DateValue != nil { + valueMembers++ + } + if valueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "DateValue.Value") + } + var valueSelection isDateValue_Value + switch { + case w.DynamicDateValue != "": + valueSelection = &DateValue_Value_DynamicDateValue{DynamicDateValue: w.DynamicDateValue} + case w.DateValue != nil: + valueSelection = &DateValue_Value_DateValue{DateValue: *w.DateValue} + } + return &DateValue{ + Precision: w.Precision, + Value: valueSelection, + }, nil +} + +type enumValueWire struct { + Values []string `json:"values,omitempty"` + EnumOptions *string `json:"enum_options,omitempty"` + MultiValuesOptions *multiValuesOptionsWire `json:"multi_values_options,omitempty"` +} + +func enumValueToWire(v *EnumValue) (*enumValueWire, error) { + if v == nil { + return nil, nil + } + multiValuesOptionsWireValue, err := multiValuesOptionsToWire(v.MultiValuesOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnumValue.MultiValuesOptions", err) + } + return &enumValueWire{ + Values: v.Values, + EnumOptions: v.EnumOptions, + MultiValuesOptions: multiValuesOptionsWireValue, + }, nil +} + +func enumValueFromWire(w *enumValueWire) (*EnumValue, error) { + if w == nil { + return nil, nil + } + multiValuesOptionsPublicValue, err := multiValuesOptionsFromWire(w.MultiValuesOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EnumValue.MultiValuesOptions", err) + } + return &EnumValue{ + Values: w.Values, + EnumOptions: w.EnumOptions, + MultiValuesOptions: multiValuesOptionsPublicValue, + }, nil +} + +type listQueriesRequestWire struct { + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listQueriesRequestToWire(v *ListQueriesRequest) (*listQueriesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listQueriesRequestWire{ + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listQueriesResponseWire struct { + Results []listQueryObjectsResponseQueryWire `json:"results,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listQueriesResponseFromWire(w *listQueriesResponseWire) (*ListQueriesResponse, error) { + if w == nil { + return nil, nil + } + resultsPublicValue, err := convertSlice(w.Results, listQueryObjectsResponseQueryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListQueriesResponse.Results", err) + } + return &ListQueriesResponse{ + Results: resultsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listQueryObjectsResponseQueryWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Description *string `json:"description,omitempty"` + OwnerUserName *string `json:"owner_user_name,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + QueryText *string `json:"query_text,omitempty"` + RunAsMode RunAsMode `json:"run_as_mode,omitempty"` + LifecycleState LifecycleState `json:"lifecycle_state,omitempty"` + LastModifierUserName *string `json:"last_modifier_user_name,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + Tags []string `json:"tags,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Parameters []queryParameterWire `json:"parameters,omitempty"` + ApplyAutoLimit *bool `json:"apply_auto_limit,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Schema *string `json:"schema,omitempty"` +} + +func listQueryObjectsResponseQueryFromWire(w *listQueryObjectsResponseQueryWire) (*ListQueryObjectsResponseQuery, error) { + if w == nil { + return nil, nil + } + parametersPublicValue, err := convertSlice(w.Parameters, queryParameterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListQueryObjectsResponseQuery.Parameters", err) + } + return &ListQueryObjectsResponseQuery{ + Id: w.Id, + DisplayName: w.DisplayName, + Description: w.Description, + OwnerUserName: w.OwnerUserName, + WarehouseId: w.WarehouseId, + QueryText: w.QueryText, + RunAsMode: w.RunAsMode, + LifecycleState: w.LifecycleState, + LastModifierUserName: w.LastModifierUserName, + ParentPath: w.ParentPath, + Tags: w.Tags, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Parameters: parametersPublicValue, + ApplyAutoLimit: w.ApplyAutoLimit, + Catalog: w.Catalog, + Schema: w.Schema, + }, nil +} + +type listVisualizationsForQueryRequestWire struct { + Id *string `json:"id,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listVisualizationsForQueryRequestToWire(v *ListVisualizationsForQueryRequest) (*listVisualizationsForQueryRequestWire, error) { + if v == nil { + return nil, nil + } + return &listVisualizationsForQueryRequestWire{ + Id: v.Id, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listVisualizationsForQueryResponseWire struct { + Results []visualizationWire `json:"results,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listVisualizationsForQueryResponseFromWire(w *listVisualizationsForQueryResponseWire) (*ListVisualizationsForQueryResponse, error) { + if w == nil { + return nil, nil + } + resultsPublicValue, err := convertSlice(w.Results, visualizationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListVisualizationsForQueryResponse.Results", err) + } + return &ListVisualizationsForQueryResponse{ + Results: resultsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type multiValuesOptionsWire struct { + Prefix *string `json:"prefix,omitempty"` + Separator *string `json:"separator,omitempty"` + Suffix *string `json:"suffix,omitempty"` +} + +func multiValuesOptionsToWire(v *MultiValuesOptions) (*multiValuesOptionsWire, error) { + if v == nil { + return nil, nil + } + return &multiValuesOptionsWire{ + Prefix: v.Prefix, + Separator: v.Separator, + Suffix: v.Suffix, + }, nil +} + +func multiValuesOptionsFromWire(w *multiValuesOptionsWire) (*MultiValuesOptions, error) { + if w == nil { + return nil, nil + } + return &MultiValuesOptions{ + Prefix: w.Prefix, + Separator: w.Separator, + Suffix: w.Suffix, + }, nil +} + +type numericValueWire struct { + Value *float64 `json:"value,omitempty"` +} + +func numericValueToWire(v *NumericValue) (*numericValueWire, error) { + if v == nil { + return nil, nil + } + return &numericValueWire{ + Value: v.Value, + }, nil +} + +func numericValueFromWire(w *numericValueWire) (*NumericValue, error) { + if w == nil { + return nil, nil + } + return &NumericValue{ + Value: w.Value, + }, nil +} + +type queryWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Description *string `json:"description,omitempty"` + OwnerUserName *string `json:"owner_user_name,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + QueryText *string `json:"query_text,omitempty"` + RunAsMode RunAsMode `json:"run_as_mode,omitempty"` + LifecycleState LifecycleState `json:"lifecycle_state,omitempty"` + LastModifierUserName *string `json:"last_modifier_user_name,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + Tags []string `json:"tags,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Parameters []queryParameterWire `json:"parameters,omitempty"` + ApplyAutoLimit *bool `json:"apply_auto_limit,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Schema *string `json:"schema,omitempty"` +} + +func queryFromWire(w *queryWire) (*Query, error) { + if w == nil { + return nil, nil + } + parametersPublicValue, err := convertSlice(w.Parameters, queryParameterFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Query.Parameters", err) + } + return &Query{ + Id: w.Id, + DisplayName: w.DisplayName, + Description: w.Description, + OwnerUserName: w.OwnerUserName, + WarehouseId: w.WarehouseId, + QueryText: w.QueryText, + RunAsMode: w.RunAsMode, + LifecycleState: w.LifecycleState, + LastModifierUserName: w.LastModifierUserName, + ParentPath: w.ParentPath, + Tags: w.Tags, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + Parameters: parametersPublicValue, + ApplyAutoLimit: w.ApplyAutoLimit, + Catalog: w.Catalog, + Schema: w.Schema, + }, nil +} + +type queryBackedValueWire struct { + Values []string `json:"values,omitempty"` + QueryId *string `json:"query_id,omitempty"` + MultiValuesOptions *multiValuesOptionsWire `json:"multi_values_options,omitempty"` +} + +func queryBackedValueToWire(v *QueryBackedValue) (*queryBackedValueWire, error) { + if v == nil { + return nil, nil + } + multiValuesOptionsWireValue, err := multiValuesOptionsToWire(v.MultiValuesOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryBackedValue.MultiValuesOptions", err) + } + return &queryBackedValueWire{ + Values: v.Values, + QueryId: v.QueryId, + MultiValuesOptions: multiValuesOptionsWireValue, + }, nil +} + +func queryBackedValueFromWire(w *queryBackedValueWire) (*QueryBackedValue, error) { + if w == nil { + return nil, nil + } + multiValuesOptionsPublicValue, err := multiValuesOptionsFromWire(w.MultiValuesOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryBackedValue.MultiValuesOptions", err) + } + return &QueryBackedValue{ + Values: w.Values, + QueryId: w.QueryId, + MultiValuesOptions: multiValuesOptionsPublicValue, + }, nil +} + +type queryParameterWire struct { + Title *string `json:"title,omitempty"` + Name *string `json:"name,omitempty"` + TextValue *textValueWire `json:"text_value,omitempty"` + NumericValue *numericValueWire `json:"numeric_value,omitempty"` + EnumValue *enumValueWire `json:"enum_value,omitempty"` + DateValue *dateValueWire `json:"date_value,omitempty"` + DateRangeValue *dateRangeValueWire `json:"date_range_value,omitempty"` + QueryBackedValue *queryBackedValueWire `json:"query_backed_value,omitempty"` +} + +func queryParameterToWire(v *QueryParameter) (*queryParameterWire, error) { + if v == nil { + return nil, nil + } + var parameterValueTextValueWire *textValueWire + var parameterValueNumericValueWire *numericValueWire + var parameterValueEnumValueWire *enumValueWire + var parameterValueDateValueWire *dateValueWire + var parameterValueDateRangeValueWire *dateRangeValueWire + var parameterValueQueryBackedValueWire *queryBackedValueWire + switch value := v.ParameterValue.(type) { + case nil: + case *QueryParameter_ParameterValue_TextValue: + if value != nil { + parameterValueTextValueConverted, err := textValueToWire(&value.TextValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.TextValue", err) + } + parameterValueTextValueWire = parameterValueTextValueConverted + } + case *QueryParameter_ParameterValue_NumericValue: + if value != nil { + parameterValueNumericValueConverted, err := numericValueToWire(&value.NumericValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.NumericValue", err) + } + parameterValueNumericValueWire = parameterValueNumericValueConverted + } + case *QueryParameter_ParameterValue_EnumValue: + if value != nil { + parameterValueEnumValueConverted, err := enumValueToWire(&value.EnumValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.EnumValue", err) + } + parameterValueEnumValueWire = parameterValueEnumValueConverted + } + case *QueryParameter_ParameterValue_DateValue: + if value != nil { + parameterValueDateValueConverted, err := dateValueToWire(&value.DateValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.DateValue", err) + } + parameterValueDateValueWire = parameterValueDateValueConverted + } + case *QueryParameter_ParameterValue_DateRangeValue: + if value != nil { + parameterValueDateRangeValueConverted, err := dateRangeValueToWire(&value.DateRangeValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.DateRangeValue", err) + } + parameterValueDateRangeValueWire = parameterValueDateRangeValueConverted + } + case *QueryParameter_ParameterValue_QueryBackedValue: + if value != nil { + parameterValueQueryBackedValueConverted, err := queryBackedValueToWire(&value.QueryBackedValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.QueryBackedValue", err) + } + parameterValueQueryBackedValueWire = parameterValueQueryBackedValueConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "QueryParameter.ParameterValue", value) + } + return &queryParameterWire{ + Title: v.Title, + Name: v.Name, + TextValue: parameterValueTextValueWire, + NumericValue: parameterValueNumericValueWire, + EnumValue: parameterValueEnumValueWire, + DateValue: parameterValueDateValueWire, + DateRangeValue: parameterValueDateRangeValueWire, + QueryBackedValue: parameterValueQueryBackedValueWire, + }, nil +} + +func queryParameterFromWire(w *queryParameterWire) (*QueryParameter, error) { + if w == nil { + return nil, nil + } + parameterValueMembers := 0 + if w.TextValue != nil { + parameterValueMembers++ + } + if w.NumericValue != nil { + parameterValueMembers++ + } + if w.EnumValue != nil { + parameterValueMembers++ + } + if w.DateValue != nil { + parameterValueMembers++ + } + if w.DateRangeValue != nil { + parameterValueMembers++ + } + if w.QueryBackedValue != nil { + parameterValueMembers++ + } + if parameterValueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "QueryParameter.ParameterValue") + } + var parameterValueSelection isQueryParameter_ParameterValue + switch { + case w.TextValue != nil: + parameterValueTextValueConverted, err := textValueFromWire(w.TextValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.TextValue", err) + } + parameterValueSelection = &QueryParameter_ParameterValue_TextValue{TextValue: *parameterValueTextValueConverted} + case w.NumericValue != nil: + parameterValueNumericValueConverted, err := numericValueFromWire(w.NumericValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.NumericValue", err) + } + parameterValueSelection = &QueryParameter_ParameterValue_NumericValue{NumericValue: *parameterValueNumericValueConverted} + case w.EnumValue != nil: + parameterValueEnumValueConverted, err := enumValueFromWire(w.EnumValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.EnumValue", err) + } + parameterValueSelection = &QueryParameter_ParameterValue_EnumValue{EnumValue: *parameterValueEnumValueConverted} + case w.DateValue != nil: + parameterValueDateValueConverted, err := dateValueFromWire(w.DateValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.DateValue", err) + } + parameterValueSelection = &QueryParameter_ParameterValue_DateValue{DateValue: *parameterValueDateValueConverted} + case w.DateRangeValue != nil: + parameterValueDateRangeValueConverted, err := dateRangeValueFromWire(w.DateRangeValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.DateRangeValue", err) + } + parameterValueSelection = &QueryParameter_ParameterValue_DateRangeValue{DateRangeValue: *parameterValueDateRangeValueConverted} + case w.QueryBackedValue != nil: + parameterValueQueryBackedValueConverted, err := queryBackedValueFromWire(w.QueryBackedValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryParameter.ParameterValue.QueryBackedValue", err) + } + parameterValueSelection = &QueryParameter_ParameterValue_QueryBackedValue{QueryBackedValue: *parameterValueQueryBackedValueConverted} + } + return &QueryParameter{ + Title: w.Title, + Name: w.Name, + ParameterValue: parameterValueSelection, + }, nil +} + +type textValueWire struct { + Value *string `json:"value,omitempty"` +} + +func textValueToWire(v *TextValue) (*textValueWire, error) { + if v == nil { + return nil, nil + } + return &textValueWire{ + Value: v.Value, + }, nil +} + +func textValueFromWire(w *textValueWire) (*TextValue, error) { + if w == nil { + return nil, nil + } + return &TextValue{ + Value: w.Value, + }, nil +} + +type updateQueryRequestWire struct { + Query *updateQueryRequestQueryWire `json:"query,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` + Id *string `json:"id,omitempty"` + AutoResolveDisplayName *bool `json:"auto_resolve_display_name,omitempty"` +} + +func updateQueryRequestToWire(v *UpdateQueryRequest) (*updateQueryRequestWire, error) { + if v == nil { + return nil, nil + } + queryWireValue, err := updateQueryRequestQueryToWire(v.Query) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateQueryRequest.Query", err) + } + return &updateQueryRequestWire{ + Query: queryWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + Id: v.Id, + AutoResolveDisplayName: v.AutoResolveDisplayName, + }, nil +} + +type updateQueryRequestQueryWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Description *string `json:"description,omitempty"` + OwnerUserName *string `json:"owner_user_name,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + QueryText *string `json:"query_text,omitempty"` + RunAsMode RunAsMode `json:"run_as_mode,omitempty"` + LifecycleState LifecycleState `json:"lifecycle_state,omitempty"` + LastModifierUserName *string `json:"last_modifier_user_name,omitempty"` + ParentPath *string `json:"parent_path,omitempty"` + Tags []string `json:"tags,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Parameters []queryParameterWire `json:"parameters,omitempty"` + ApplyAutoLimit *bool `json:"apply_auto_limit,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Schema *string `json:"schema,omitempty"` +} + +func updateQueryRequestQueryToWire(v *UpdateQueryRequestQuery) (*updateQueryRequestQueryWire, error) { + if v == nil { + return nil, nil + } + parametersWireValue, err := convertSlice(v.Parameters, queryParameterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateQueryRequestQuery.Parameters", err) + } + return &updateQueryRequestQueryWire{ + Id: v.Id, + DisplayName: v.DisplayName, + Description: v.Description, + OwnerUserName: v.OwnerUserName, + WarehouseId: v.WarehouseId, + QueryText: v.QueryText, + RunAsMode: v.RunAsMode, + LifecycleState: v.LifecycleState, + LastModifierUserName: v.LastModifierUserName, + ParentPath: v.ParentPath, + Tags: v.Tags, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + Parameters: parametersWireValue, + ApplyAutoLimit: v.ApplyAutoLimit, + Catalog: v.Catalog, + Schema: v.Schema, + }, nil +} + +type visualizationWire struct { + Id *string `json:"id,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Type *string `json:"type,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + SerializedQueryPlan *string `json:"serialized_query_plan,omitempty"` + SerializedOptions *string `json:"serialized_options,omitempty"` + QueryId *string `json:"query_id,omitempty"` +} + +func visualizationFromWire(w *visualizationWire) (*Visualization, error) { + if w == nil { + return nil, nil + } + return &Visualization{ + Id: w.Id, + DisplayName: w.DisplayName, + Type: w.Type, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + SerializedQueryPlan: w.SerializedQueryPlan, + SerializedOptions: w.SerializedOptions, + QueryId: w.QueryId, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/queryhistory/.package.json b/queryhistory/.package.json new file mode 100644 index 0000000..c705397 --- /dev/null +++ b/queryhistory/.package.json @@ -0,0 +1,3 @@ +{ + "package": "queryhistory" +} diff --git a/queryhistory/CHANGELOG.md b/queryhistory/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/queryhistory/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/queryhistory/README.md b/queryhistory/README.md new file mode 100644 index 0000000..b75e4e4 --- /dev/null +++ b/queryhistory/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/queryhistory + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/queryhistory@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/queryhistory/v1" + +client, err := queryhistory.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/queryhistory/go.mod b/queryhistory/go.mod new file mode 100644 index 0000000..9e2167f --- /dev/null +++ b/queryhistory/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/queryhistory + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/queryhistory/internal/version.go b/queryhistory/internal/version.go new file mode 100644 index 0000000..77e6a94 --- /dev/null +++ b/queryhistory/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-queryhistory" + +const Version = "0.0.1-dev.1" diff --git a/queryhistory/v1/client.go b/queryhistory/v1/client.go new file mode 100755 index 0000000..2045f0c --- /dev/null +++ b/queryhistory/v1/client.go @@ -0,0 +1,151 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package queryhistory + +import ( + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/queryhistory/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// List the history of queries through SQL warehouses, and serverless compute. +// +// You can filter by user ID, warehouse ID, status, and time range. Most +// recently started queries are returned first (up to max_results in request). +// The pagination token returned in response can be used to list subsequent +// query statuses. +func (c *internalClient) ListQueries(ctx context.Context, req *ListQueriesRequest, opts ...call.Option) (*ListQueriesResponse, error) { + wireReq, err := listQueriesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/sql/history/queries" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "filter_by", wireReq.FilterBy); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_metrics", wireReq.IncludeMetrics); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListQueriesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listQueriesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listQueriesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/queryhistory/v1/genhelper.go b/queryhistory/v1/genhelper.go new file mode 100755 index 0000000..70ab0a1 --- /dev/null +++ b/queryhistory/v1/genhelper.go @@ -0,0 +1,178 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package queryhistory + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} diff --git a/queryhistory/v1/model.go b/queryhistory/v1/model.go new file mode 100755 index 0000000..2160426 --- /dev/null +++ b/queryhistory/v1/model.go @@ -0,0 +1,353 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package queryhistory + +type ChannelName string + +const ( + ChannelName_Unspecified ChannelName = "" + ChannelName_ChannelNamePreview ChannelName = "CHANNEL_NAME_PREVIEW" + ChannelName_ChannelNameCurrent ChannelName = "CHANNEL_NAME_CURRENT" + ChannelName_ChannelNamePrevious ChannelName = "CHANNEL_NAME_PREVIOUS" + ChannelName_ChannelNameCustom ChannelName = "CHANNEL_NAME_CUSTOM" +) + +// Possible Reasons for which we have not saved plans in the database +type PlansState string + +const ( + PlansState_Unspecified PlansState = "" + // Execution time of the query was smaller than the min required to save plans + PlansState_IgnoredSmallDuration PlansState = "IGNORED_SMALL_DURATION" + // Size of plans is larger than the limit defined in config + PlansState_IgnoredLargePlansSize PlansState = "IGNORED_LARGE_PLANS_SIZE" + // If plans exist and are stored in the DB + PlansState_Exists PlansState = "EXISTS" + // Catchall for unknown states in graphql, to prevent it from crashing when it + // received an unknown enum type that is defined here but not in the graphql + // schema of the object. + PlansState_Unknown PlansState = "UNKNOWN" + // When the query has no plans by default + PlansState_Empty PlansState = "EMPTY" + // When plans are filtered out in history backend because it is + // isIgnoredSparkPlanType, isIgnoredSparkPlanName or isDeltaLogScan + PlansState_IgnoredSparkPlanType PlansState = "IGNORED_SPARK_PLAN_TYPE" +) + +type QueryStatementType string + +const ( + QueryStatementType_Unspecified QueryStatementType = "" + QueryStatementType_Alter QueryStatementType = "ALTER" + QueryStatementType_Analyze QueryStatementType = "ANALYZE" + QueryStatementType_Copy QueryStatementType = "COPY" + QueryStatementType_Create QueryStatementType = "CREATE" + QueryStatementType_Delete QueryStatementType = "DELETE" + QueryStatementType_Describe QueryStatementType = "DESCRIBE" + QueryStatementType_Drop QueryStatementType = "DROP" + QueryStatementType_Explain QueryStatementType = "EXPLAIN" + QueryStatementType_Grant QueryStatementType = "GRANT" + QueryStatementType_Insert QueryStatementType = "INSERT" + QueryStatementType_Merge QueryStatementType = "MERGE" + QueryStatementType_Optimize QueryStatementType = "OPTIMIZE" + QueryStatementType_Refresh QueryStatementType = "REFRESH" + QueryStatementType_Replace QueryStatementType = "REPLACE" + QueryStatementType_Revoke QueryStatementType = "REVOKE" + QueryStatementType_Select QueryStatementType = "SELECT" + QueryStatementType_Set QueryStatementType = "SET" + QueryStatementType_Show QueryStatementType = "SHOW" + QueryStatementType_Truncate QueryStatementType = "TRUNCATE" + QueryStatementType_Update QueryStatementType = "UPDATE" + QueryStatementType_Use QueryStatementType = "USE" +) + +// Statuses which are also used by OperationStatus in runtime. When adding a new +// QueryStatus, make sure to update +// com.databricks.sqlgateway.history.QueryStatusOrdering +type QueryStatus string + +const ( + QueryStatus_Unspecified QueryStatus = "" + // query has been received and queued + QueryStatus_Queued QueryStatus = "QUEUED" + // query has been received and started by the driver DEPRECATED: to be removed + // once runtime side change is picked up. + QueryStatus_Started QueryStatus = "STARTED" + // query compilation has been started This isn't currently used. We will soon + // use this. + QueryStatus_Compiling QueryStatus = "COMPILING" + // query has been compiled DEPRECATED: to be removed once runtime side change is + // picked up. + QueryStatus_Compiled QueryStatus = "COMPILED" + // currently execution has been started (spark jobs for this query has been + // started running) detail ui is available from this state + QueryStatus_Running QueryStatus = "RUNNING" + // query has been cancelled by the user + QueryStatus_Canceled QueryStatus = "CANCELED" + // query has failed + QueryStatus_Failed QueryStatus = "FAILED" + // query execution has been completed + QueryStatus_Finished QueryStatus = "FINISHED" +) + +// Details about a Channel.. +type ChannelInfo struct { + // Name of the channel + Name ChannelName + // DB SQL Version the Channel is mapped to. + DbsqlVersion *string +} + +type ExternalQuerySource struct { + // The canonical identifier for this Lakeview dashboard + DashboardId *string + // The canonical identifier for this legacy dashboard + LegacyDashboardId *string + // The canonical identifier for this SQL alert + AlertId *string + // The canonical identifier for this notebook + NotebookId *string + // The canonical identifier for this SQL query + SqlQueryId *string + JobInfo *ExternalQuerySource_JobInfo + // The canonical identifier for this Genie space + GenieSpaceId *string +} + +type ExternalQuerySource_JobInfo struct { + // The canonical identifier for this job. + JobId *string + // The canonical identifier of the run. This ID is unique across all runs of all + // jobs. + JobRunId *string + // The canonical identifier of the task run. + JobTaskRunId *string +} + +// Fetches a list of queries conforming to the provided set of query filters. +// +// If the number of queries to return takes > 10 seconds, the request will +// timeout. In that case, please reduce the time range to ensure ListQueries +// conforms to the 10 second max query time limit.. +type ListQueriesRequest struct { + // An optional filter object to limit query history results. Accepts parameters + // such as user IDs, endpoint IDs, and statuses to narrow the returned data. In + // a URL, the parameters of this filter are specified with dot notation. For + // example: `filter_by.statement_ids`. + FilterBy *QueryFilter + // Limit the number of results returned in one page. Must be less than 1000 and + // the default is 100. + MaxResults *int + // A token that can be used to get the next page of results. The token can + // contains characters that need to be encoded before using it in a URL. For + // example, the character '+' needs to be replaced by %2B. This field is + // optional. + PageToken *string + // Whether to include the query metrics with each query. Only use this for a + // small subset of queries (max_results). Defaults to false. + IncludeMetrics *bool +} + +type ListQueriesResponse struct { + // A token that can be used to get the next page of results. + NextPageToken *string + // Whether there is another page of results. + HasNextPage *bool + Res []QueryInfo +} + +type QueryFilter struct { + // A range filter for query submitted time. The time range must be less than or + // equal to 30 days. + QueryStartTimeRange *TimeRange + // A list of user IDs who ran the queries. + UserIds []int64 + // A list of statuses (QUEUED, RUNNING, CANCELED, FAILED, FINISHED) to match + // query results. Corresponds to the `status` field in the response. Filtering + // for multiple statuses is not recommended. Instead, opt to filter by a single + // status multiple times and then combine the results. + Statuses []QueryStatus + // A list of warehouse IDs. + WarehouseIds []string + // A list of statement IDs. + StatementIds []string +} + +type QueryInfo struct { + // The query ID. + QueryId *string + // Query status with one the following values: - `QUEUED`: Query has been + // received and queued. - `RUNNING`: Query has started. - `CANCELED`: Query has + // been cancelled by the user. - `FAILED`: Query has failed. - `FINISHED`: Query + // has completed. + Status QueryStatus + // The text of the query. + QueryText *string + // The time the query started. + QueryStartTimeMs *int64 + // The time execution of the query ended. + ExecutionEndTimeMs *int64 + // The time the query ended. + QueryEndTimeMs *int64 + // The ID of the user who ran the query. + UserId *int64 + // The email address or username of the user who ran the query. + UserName *string + // URL to the Spark UI query plan. + SparkUiUrl *string + // Alias for `warehouse_id`. + EndpointId *string + // The number of results returned by the query. + RowsProduced *int64 + // Message describing why the query could not complete. + ErrorMessage *string + // A key that can be used to look up query details. + LookupKey *string + // Metrics about query execution. + Metrics *QueryMetrics + // The ID of the user whose credentials were used to run the query. + ExecutedAsUserId *int64 + // The email address or username of the user whose credentials were used to run + // the query. + ExecutedAsUserName *string + // The spark session UUID that query ran on. This is either the Spark Connect, + // DBSQL, or SDP session ID. + SessionId *string + // Whether more updates for the query are expected. + IsFinal *bool + // SQL Warehouse channel information at the time of query execution + ChannelUsed *ChannelInfo + // Whether plans exist for the execution, or the reason why they are missing + PlansState PlansState + // Type of statement for this query + StatementType QueryStatementType + // Warehouse ID. + WarehouseId *string + // Total time of the statement execution. This value does not include the time + // taken to retrieve the results, which can result in a discrepancy between this + // value and the start-to-finish wall-clock time. + Duration *int64 + // Client application that ran the statement. For example: Databricks SQL + // Editor, Tableau, and Power BI. This field is derived from information + // provided by client applications. While values are expected to remain static + // over time, this cannot be guaranteed. + ClientApplication *string + // A struct that contains key-value pairs representing entities + // that were involved in the execution of this statement, such as jobs, + // notebooks, or dashboards. This field only records entities. + QuerySource *ExternalQuerySource + // The ID of the cached query if this result retrieved from cache + CacheQueryId *string + // A query execution can be optionally annotated with query tags + QueryTags []QueryTag +} + +// A query metric that encapsulates a set of measurements for a single query. +// Metrics come from the driver and are stored in the history service database.. +type QueryMetrics struct { + // Total execution time of the query from the client’s point of view, in + // milliseconds. + TotalTimeMs *int64 + // Total size of data read by the query, in bytes. + ReadBytes *int64 + // Total number of rows returned by the query. + RowsProducedCount *int64 + // Time spent loading metadata and optimizing the query, in milliseconds. + CompilationTimeMs *int64 + // Time spent executing the query, in milliseconds. + ExecutionTimeMs *int64 + // Size of persistent data read from cloud object storage on your cloud tenant, + // in bytes. + ReadRemoteBytes *int64 + // Size pf persistent data written to cloud object storage in your cloud tenant, + // in bytes. + WriteRemoteBytes *int64 + // Size of persistent data read from the cache, in bytes. + ReadCacheBytes *int64 + // Size of data temporarily written to disk while executing the query, in bytes. + SpillToDiskBytes *int64 + // Sum of execution time for all of the query’s tasks, in milliseconds. + TaskTotalTimeMs *int64 + // Number of files read after pruning + ReadFilesCount *int64 + // Number of partitions read after pruning. + ReadPartitionsCount *int64 + // Total execution time for all individual Photon query engine tasks in the + // query, in milliseconds. + PhotonTotalTimeMs *int64 + // Total number of rows read by the query. + RowsReadCount *int64 + // Time spent fetching the query results after the execution finished, in + // milliseconds. + ResultFetchTimeMs *int64 + // Total amount of data sent over the network between executor nodes during + // shuffle, in bytes. + NetworkSentBytes *int64 + // `true` if the query result was fetched from cache, `false` otherwise. + ResultFromCache *bool + // Total number of file bytes in all tables not read due to pruning + PrunedBytes *int64 + // Total number of files from all tables not read due to pruning + PrunedFilesCount *int64 + // Timestamp of when the query was enqueued waiting for a cluster to be + // provisioned for the warehouse. This field is optional and will not appear if + // the query skipped the provisioning queue. + ProvisioningQueueStartTimestamp *int64 + // Timestamp of when the query was enqueued waiting while the warehouse was at + // max load. This field is optional and will not appear if the query skipped the + // overloading queue. + OverloadingQueueStartTimestamp *int64 + // Timestamp of when the underlying compute started compilation of the query. + QueryCompilationStartTimestamp *int64 + // sum of task times completed in a range of wall clock time, approximated to a + // configurable number of points aggregated over all stages and jobs in the + // query (based on task_total_time_ms) + TaskTimeOverTimeRange *TaskTimeOverRange + // remaining work to be done across all stages in the query, calculated by + // autoscaler StatementAnalysis.scala, in milliseconds deprecated: using + // projected_remaining_task_total_time_ms instead + WorkToBeDone *int64 + // number of remaining tasks to complete, calculated by autoscaler + // StatementAnalysis.scala deprecated: use remaining_task_count instead + RunnableTasks *int64 + // projected remaining work to be done aggregated across all stages in the + // query, in milliseconds + ProjectedRemainingTaskTotalTimeMs *int64 + // number of remaining tasks to complete this is based on the current status and + // could be bigger or smaller in the future based on future updates + RemainingTaskCount *int64 + // projected lower bound on remaining total task time based on + // projected_remaining_task_total_time_ms / maximum concurrency + ProjectedRemainingWallclockTimeMs *int64 + // Total number of file bytes in all tables read + ReadFilesBytes *int64 +} + +// * A query execution can be annotated with an optional key-value pair to allow +// users to attribute the executions by key and optional value to filter by. +// QueryTag is the user-facing representation.. +type QueryTag struct { + Key *string + Value *string +} + +type TaskTimeOverRange struct { + Entries []TaskTimeOverRangeEntry + // interval length for all entries (difference in start time and end time of an + // entry range) the same for all entries start time of first interval is + // query_start_time_ms + Interval *int64 +} + +type TaskTimeOverRangeEntry struct { + // total task completion time in this time range, aggregated over all stages and + // jobs in the query + TaskCompletedTimeMs *int64 +} + +type TimeRange struct { + // The start time in milliseconds. + StartTimeMs *int64 + // The end time in milliseconds. + EndTimeMs *int64 +} diff --git a/queryhistory/v1/wire.go b/queryhistory/v1/wire.go new file mode 100755 index 0000000..f1369fa --- /dev/null +++ b/queryhistory/v1/wire.go @@ -0,0 +1,368 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package queryhistory + +import ( + "fmt" +) + +type channelInfoWire struct { + Name ChannelName `json:"name,omitempty"` + DbsqlVersion *string `json:"dbsql_version,omitempty"` +} + +func channelInfoFromWire(w *channelInfoWire) (*ChannelInfo, error) { + if w == nil { + return nil, nil + } + return &ChannelInfo{ + Name: w.Name, + DbsqlVersion: w.DbsqlVersion, + }, nil +} + +type externalQuerySourceWire struct { + DashboardId *string `json:"dashboard_id,omitempty"` + LegacyDashboardId *string `json:"legacy_dashboard_id,omitempty"` + AlertId *string `json:"alert_id,omitempty"` + NotebookId *string `json:"notebook_id,omitempty"` + SqlQueryId *string `json:"sql_query_id,omitempty"` + JobInfo *externalQuerySource_JobInfoWire `json:"job_info,omitempty"` + GenieSpaceId *string `json:"genie_space_id,omitempty"` +} + +func externalQuerySourceFromWire(w *externalQuerySourceWire) (*ExternalQuerySource, error) { + if w == nil { + return nil, nil + } + jobInfoPublicValue, err := externalQuerySource_JobInfoFromWire(w.JobInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalQuerySource.JobInfo", err) + } + return &ExternalQuerySource{ + DashboardId: w.DashboardId, + LegacyDashboardId: w.LegacyDashboardId, + AlertId: w.AlertId, + NotebookId: w.NotebookId, + SqlQueryId: w.SqlQueryId, + JobInfo: jobInfoPublicValue, + GenieSpaceId: w.GenieSpaceId, + }, nil +} + +type externalQuerySource_JobInfoWire struct { + JobId *string `json:"job_id,omitempty"` + JobRunId *string `json:"job_run_id,omitempty"` + JobTaskRunId *string `json:"job_task_run_id,omitempty"` +} + +func externalQuerySource_JobInfoFromWire(w *externalQuerySource_JobInfoWire) (*ExternalQuerySource_JobInfo, error) { + if w == nil { + return nil, nil + } + return &ExternalQuerySource_JobInfo{ + JobId: w.JobId, + JobRunId: w.JobRunId, + JobTaskRunId: w.JobTaskRunId, + }, nil +} + +type listQueriesRequestWire struct { + FilterBy *queryFilterWire `json:"filter_by,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` + IncludeMetrics *bool `json:"include_metrics,omitempty"` +} + +func listQueriesRequestToWire(v *ListQueriesRequest) (*listQueriesRequestWire, error) { + if v == nil { + return nil, nil + } + filterByWireValue, err := queryFilterToWire(v.FilterBy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListQueriesRequest.FilterBy", err) + } + return &listQueriesRequestWire{ + FilterBy: filterByWireValue, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + IncludeMetrics: v.IncludeMetrics, + }, nil +} + +type listQueriesResponseWire struct { + NextPageToken *string `json:"next_page_token,omitempty"` + HasNextPage *bool `json:"has_next_page,omitempty"` + Res []queryInfoWire `json:"res,omitempty"` +} + +func listQueriesResponseFromWire(w *listQueriesResponseWire) (*ListQueriesResponse, error) { + if w == nil { + return nil, nil + } + resPublicValue, err := convertSlice(w.Res, queryInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListQueriesResponse.Res", err) + } + return &ListQueriesResponse{ + NextPageToken: w.NextPageToken, + HasNextPage: w.HasNextPage, + Res: resPublicValue, + }, nil +} + +type queryFilterWire struct { + QueryStartTimeRange *timeRangeWire `json:"query_start_time_range,omitempty"` + UserIds []int64 `json:"user_ids,omitempty"` + Statuses []QueryStatus `json:"statuses,omitempty"` + WarehouseIds []string `json:"warehouse_ids,omitempty"` + StatementIds []string `json:"statement_ids,omitempty"` +} + +func queryFilterToWire(v *QueryFilter) (*queryFilterWire, error) { + if v == nil { + return nil, nil + } + queryStartTimeRangeWireValue, err := timeRangeToWire(v.QueryStartTimeRange) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryFilter.QueryStartTimeRange", err) + } + return &queryFilterWire{ + QueryStartTimeRange: queryStartTimeRangeWireValue, + UserIds: v.UserIds, + Statuses: v.Statuses, + WarehouseIds: v.WarehouseIds, + StatementIds: v.StatementIds, + }, nil +} + +type queryInfoWire struct { + QueryId *string `json:"query_id,omitempty"` + Status QueryStatus `json:"status,omitempty"` + QueryText *string `json:"query_text,omitempty"` + QueryStartTimeMs *int64 `json:"query_start_time_ms,omitempty"` + ExecutionEndTimeMs *int64 `json:"execution_end_time_ms,omitempty"` + QueryEndTimeMs *int64 `json:"query_end_time_ms,omitempty"` + UserId *int64 `json:"user_id,omitempty"` + UserName *string `json:"user_name,omitempty"` + SparkUiUrl *string `json:"spark_ui_url,omitempty"` + EndpointId *string `json:"endpoint_id,omitempty"` + RowsProduced *int64 `json:"rows_produced,omitempty"` + ErrorMessage *string `json:"error_message,omitempty"` + LookupKey *string `json:"lookup_key,omitempty"` + Metrics *queryMetricsWire `json:"metrics,omitempty"` + ExecutedAsUserId *int64 `json:"executed_as_user_id,omitempty"` + ExecutedAsUserName *string `json:"executed_as_user_name,omitempty"` + SessionId *string `json:"session_id,omitempty"` + IsFinal *bool `json:"is_final,omitempty"` + ChannelUsed *channelInfoWire `json:"channel_used,omitempty"` + PlansState PlansState `json:"plans_state,omitempty"` + StatementType QueryStatementType `json:"statement_type,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + Duration *int64 `json:"duration,omitempty"` + ClientApplication *string `json:"client_application,omitempty"` + QuerySource *externalQuerySourceWire `json:"query_source,omitempty"` + CacheQueryId *string `json:"cache_query_id,omitempty"` + QueryTags []queryTagWire `json:"query_tags,omitempty"` +} + +func queryInfoFromWire(w *queryInfoWire) (*QueryInfo, error) { + if w == nil { + return nil, nil + } + metricsPublicValue, err := queryMetricsFromWire(w.Metrics) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryInfo.Metrics", err) + } + channelUsedPublicValue, err := channelInfoFromWire(w.ChannelUsed) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryInfo.ChannelUsed", err) + } + querySourcePublicValue, err := externalQuerySourceFromWire(w.QuerySource) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryInfo.QuerySource", err) + } + queryTagsPublicValue, err := convertSlice(w.QueryTags, queryTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryInfo.QueryTags", err) + } + return &QueryInfo{ + QueryId: w.QueryId, + Status: w.Status, + QueryText: w.QueryText, + QueryStartTimeMs: w.QueryStartTimeMs, + ExecutionEndTimeMs: w.ExecutionEndTimeMs, + QueryEndTimeMs: w.QueryEndTimeMs, + UserId: w.UserId, + UserName: w.UserName, + SparkUiUrl: w.SparkUiUrl, + EndpointId: w.EndpointId, + RowsProduced: w.RowsProduced, + ErrorMessage: w.ErrorMessage, + LookupKey: w.LookupKey, + Metrics: metricsPublicValue, + ExecutedAsUserId: w.ExecutedAsUserId, + ExecutedAsUserName: w.ExecutedAsUserName, + SessionId: w.SessionId, + IsFinal: w.IsFinal, + ChannelUsed: channelUsedPublicValue, + PlansState: w.PlansState, + StatementType: w.StatementType, + WarehouseId: w.WarehouseId, + Duration: w.Duration, + ClientApplication: w.ClientApplication, + QuerySource: querySourcePublicValue, + CacheQueryId: w.CacheQueryId, + QueryTags: queryTagsPublicValue, + }, nil +} + +type queryMetricsWire struct { + TotalTimeMs *int64 `json:"total_time_ms,omitempty"` + ReadBytes *int64 `json:"read_bytes,omitempty"` + RowsProducedCount *int64 `json:"rows_produced_count,omitempty"` + CompilationTimeMs *int64 `json:"compilation_time_ms,omitempty"` + ExecutionTimeMs *int64 `json:"execution_time_ms,omitempty"` + ReadRemoteBytes *int64 `json:"read_remote_bytes,omitempty"` + WriteRemoteBytes *int64 `json:"write_remote_bytes,omitempty"` + ReadCacheBytes *int64 `json:"read_cache_bytes,omitempty"` + SpillToDiskBytes *int64 `json:"spill_to_disk_bytes,omitempty"` + TaskTotalTimeMs *int64 `json:"task_total_time_ms,omitempty"` + ReadFilesCount *int64 `json:"read_files_count,omitempty"` + ReadPartitionsCount *int64 `json:"read_partitions_count,omitempty"` + PhotonTotalTimeMs *int64 `json:"photon_total_time_ms,omitempty"` + RowsReadCount *int64 `json:"rows_read_count,omitempty"` + ResultFetchTimeMs *int64 `json:"result_fetch_time_ms,omitempty"` + NetworkSentBytes *int64 `json:"network_sent_bytes,omitempty"` + ResultFromCache *bool `json:"result_from_cache,omitempty"` + PrunedBytes *int64 `json:"pruned_bytes,omitempty"` + PrunedFilesCount *int64 `json:"pruned_files_count,omitempty"` + ProvisioningQueueStartTimestamp *int64 `json:"provisioning_queue_start_timestamp,omitempty"` + OverloadingQueueStartTimestamp *int64 `json:"overloading_queue_start_timestamp,omitempty"` + QueryCompilationStartTimestamp *int64 `json:"query_compilation_start_timestamp,omitempty"` + TaskTimeOverTimeRange *taskTimeOverRangeWire `json:"task_time_over_time_range,omitempty"` + WorkToBeDone *int64 `json:"work_to_be_done,omitempty"` + RunnableTasks *int64 `json:"runnable_tasks,omitempty"` + ProjectedRemainingTaskTotalTimeMs *int64 `json:"projected_remaining_task_total_time_ms,omitempty"` + RemainingTaskCount *int64 `json:"remaining_task_count,omitempty"` + ProjectedRemainingWallclockTimeMs *int64 `json:"projected_remaining_wallclock_time_ms,omitempty"` + ReadFilesBytes *int64 `json:"read_files_bytes,omitempty"` +} + +func queryMetricsFromWire(w *queryMetricsWire) (*QueryMetrics, error) { + if w == nil { + return nil, nil + } + taskTimeOverTimeRangePublicValue, err := taskTimeOverRangeFromWire(w.TaskTimeOverTimeRange) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryMetrics.TaskTimeOverTimeRange", err) + } + return &QueryMetrics{ + TotalTimeMs: w.TotalTimeMs, + ReadBytes: w.ReadBytes, + RowsProducedCount: w.RowsProducedCount, + CompilationTimeMs: w.CompilationTimeMs, + ExecutionTimeMs: w.ExecutionTimeMs, + ReadRemoteBytes: w.ReadRemoteBytes, + WriteRemoteBytes: w.WriteRemoteBytes, + ReadCacheBytes: w.ReadCacheBytes, + SpillToDiskBytes: w.SpillToDiskBytes, + TaskTotalTimeMs: w.TaskTotalTimeMs, + ReadFilesCount: w.ReadFilesCount, + ReadPartitionsCount: w.ReadPartitionsCount, + PhotonTotalTimeMs: w.PhotonTotalTimeMs, + RowsReadCount: w.RowsReadCount, + ResultFetchTimeMs: w.ResultFetchTimeMs, + NetworkSentBytes: w.NetworkSentBytes, + ResultFromCache: w.ResultFromCache, + PrunedBytes: w.PrunedBytes, + PrunedFilesCount: w.PrunedFilesCount, + ProvisioningQueueStartTimestamp: w.ProvisioningQueueStartTimestamp, + OverloadingQueueStartTimestamp: w.OverloadingQueueStartTimestamp, + QueryCompilationStartTimestamp: w.QueryCompilationStartTimestamp, + TaskTimeOverTimeRange: taskTimeOverTimeRangePublicValue, + WorkToBeDone: w.WorkToBeDone, + RunnableTasks: w.RunnableTasks, + ProjectedRemainingTaskTotalTimeMs: w.ProjectedRemainingTaskTotalTimeMs, + RemainingTaskCount: w.RemainingTaskCount, + ProjectedRemainingWallclockTimeMs: w.ProjectedRemainingWallclockTimeMs, + ReadFilesBytes: w.ReadFilesBytes, + }, nil +} + +type queryTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func queryTagFromWire(w *queryTagWire) (*QueryTag, error) { + if w == nil { + return nil, nil + } + return &QueryTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type taskTimeOverRangeWire struct { + Entries []taskTimeOverRangeEntryWire `json:"entries,omitempty"` + Interval *int64 `json:"interval,omitempty"` +} + +func taskTimeOverRangeFromWire(w *taskTimeOverRangeWire) (*TaskTimeOverRange, error) { + if w == nil { + return nil, nil + } + entriesPublicValue, err := convertSlice(w.Entries, taskTimeOverRangeEntryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TaskTimeOverRange.Entries", err) + } + return &TaskTimeOverRange{ + Entries: entriesPublicValue, + Interval: w.Interval, + }, nil +} + +type taskTimeOverRangeEntryWire struct { + TaskCompletedTimeMs *int64 `json:"task_completed_time_ms,omitempty"` +} + +func taskTimeOverRangeEntryFromWire(w *taskTimeOverRangeEntryWire) (*TaskTimeOverRangeEntry, error) { + if w == nil { + return nil, nil + } + return &TaskTimeOverRangeEntry{ + TaskCompletedTimeMs: w.TaskCompletedTimeMs, + }, nil +} + +type timeRangeWire struct { + StartTimeMs *int64 `json:"start_time_ms,omitempty"` + EndTimeMs *int64 `json:"end_time_ms,omitempty"` +} + +func timeRangeToWire(v *TimeRange) (*timeRangeWire, error) { + if v == nil { + return nil, nil + } + return &timeRangeWire{ + StartTimeMs: v.StartTimeMs, + EndTimeMs: v.EndTimeMs, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/repos/.package.json b/repos/.package.json new file mode 100644 index 0000000..8e69cd8 --- /dev/null +++ b/repos/.package.json @@ -0,0 +1,3 @@ +{ + "package": "repos" +} diff --git a/repos/CHANGELOG.md b/repos/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/repos/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/repos/README.md b/repos/README.md new file mode 100644 index 0000000..0a36152 --- /dev/null +++ b/repos/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/repos + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/repos@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/repos/v1" + +client, err := repos.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/repos/go.mod b/repos/go.mod new file mode 100644 index 0000000..71f518e --- /dev/null +++ b/repos/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/repos + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/repos/internal/version.go b/repos/internal/version.go new file mode 100644 index 0000000..9ecd0f9 --- /dev/null +++ b/repos/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-repos" + +const Version = "0.0.1-dev.1" diff --git a/repos/v1/client.go b/repos/v1/client.go new file mode 100755 index 0000000..963b5fd --- /dev/null +++ b/repos/v1/client.go @@ -0,0 +1,438 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package repos + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/repos/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a repo in the workspace and links it to the remote Git repo +// specified. Note that repos created programmatically must be linked to a +// remote Git repo, unlike repos created in the browser. +func (c *internalClient) CreateRepo(ctx context.Context, req *CreateRepoRequest, opts ...call.Option) (*CreateRepoResponse, error) { + wireReq, err := createRepoRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/repos" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateRepoResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createRepoResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createRepoResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the specified repo. +func (c *internalClient) DeleteRepo(ctx context.Context, req *DeleteRepoRequest, opts ...call.Option) (*DeleteRepoResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/repos/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteRepoResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteRepoResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns the repo with the given repo ID. +func (c *internalClient) GetRepo(ctx context.Context, req *GetRepoRequest, opts ...call.Option) (*GetRepoResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/repos/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetRepoResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getRepoResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getRepoResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns repos that the calling user has Manage permissions on. Use +// `next_page_token` to iterate through additional pages. +// +// Deprecated: This operation does not return a complete list of the repos in +// the workspace, because repos with the Git CLI enabled are not included in its +// results. Instead, use the Repos and Workspace APIs to find repos and their +// associated metadata in the workspace. +func (c *internalClient) ListRepos(ctx context.Context, req *ListReposRequest, opts ...call.Option) (*ListReposResponse, error) { + wireReq, err := listReposRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/repos" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "path_prefix", wireReq.PathPrefix); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "next_page_token", wireReq.NextPageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListReposResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listReposResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listReposResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListReposIter returns an iterator that iterates +// over the results of ListRepos. +// +// For example: +// +// for item, err := range c.ListReposIter(ctx, &ListReposRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListRepos call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListRepos directly. +func (c *internalClient) ListReposIter(ctx context.Context, req *ListReposRequest, opts ...call.Option) iter.Seq2[*RepoInfo, error] { + return func(yield func(*RepoInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListReposRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListRepos(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Repos { + if !yield(&resp.Repos[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.NextPageToken = resp.NextPageToken + } + } +} + +// Updates the repo to a different branch or tag, or updates the repo to the +// latest commit on the same branch. +func (c *internalClient) UpdateRepo(ctx context.Context, req *UpdateRepoRequest, opts ...call.Option) (*UpdateRepoResponse, error) { + wireReq, err := updateRepoRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/repos/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateRepoResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateRepoResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/repos/v1/genhelper.go b/repos/v1/genhelper.go new file mode 100755 index 0000000..9521e86 --- /dev/null +++ b/repos/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package repos + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/repos/v1/model.go b/repos/v1/model.go new file mode 100755 index 0000000..d285273 --- /dev/null +++ b/repos/v1/model.go @@ -0,0 +1,166 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package repos + +type CreateRepoRequest struct { + // URL of the Git repository to be linked. + Url *string + // Git provider. This field is case-insensitive. The available Git providers are + // `gitHub`, `bitbucketCloud`, `gitLab`, `azureDevOpsServices` (Azure DevOps + // Services, including Microsoft Entra ID authentication), `gitHubEnterprise`, + // `bitbucketServer` (Bitbucket Data Center), `gitLabEnterpriseEdition` (GitLab + // Self-Managed), and `awsCodeCommit`. + Provider *string + // Desired path for the repo in the workspace. Almost any path in the workspace + // can be chosen. If repo is created in `/Repos`, path must be in the format + // `/Repos/{folder}/{repo-name}`. + Path *string + // If specified, the repo will be created with sparse checkout enabled. You + // cannot enable/disable sparse checkout after the repo is created. + SparseCheckout *SparseCheckout + // Git credential ID to use when cloning the repository. The Git credential must + // be configured for the current user. + GitCredentialId *int64 +} + +type CreateRepoResponse struct { + // ID of the Git folder (repo) object in the workspace. + Id *int64 + // Path of the Git folder (repo) in the workspace. + Path *string + // URL of the linked Git repository. + Url *string + // Git provider of the linked Git repository, e.g. `gitHub`, + // `azureDevOpsServices`, `bitbucketServer` (Bitbucket Data Center), + // `gitLabEnterpriseEdition` (GitLab Self-Managed), or `awsCodeCommit`. + Provider *string + // Branch that the Git folder (repo) is checked out to. + Branch *string + // SHA-1 hash representing the commit ID of the current HEAD of the Git folder + // (repo). + HeadCommitId *string + // Sparse checkout settings for the Git folder (repo). + SparseCheckout *SparseCheckout +} + +type DeleteRepoRequest struct { + // The ID for the corresponding repo to delete. + Id *int64 +} + +type DeleteRepoResponse struct { +} + +type GetRepoRequest struct { + // ID of the Git folder (repo) object in the workspace. + Id *int64 +} + +type GetRepoResponse struct { + // ID of the Git folder (repo) object in the workspace. + Id *int64 + // Path of the Git folder (repo) in the workspace. + Path *string + // URL of the linked Git repository. + Url *string + // Git provider of the linked Git repository, e.g. `gitHub`, + // `azureDevOpsServices`, `bitbucketServer` (Bitbucket Data Center), + // `gitLabEnterpriseEdition` (GitLab Self-Managed), or `awsCodeCommit`. + Provider *string + // Branch that the local version of the repo is checked out to. + Branch *string + // SHA-1 hash representing the commit ID of the current HEAD of the repo. + HeadCommitId *string + // Sparse checkout settings for the Git folder (repo). + SparseCheckout *SparseCheckout + // Whether the Git CLI is enabled for this Git folder (repo). When true, Git + // commands can be run directly against this Git folder using the Git CLI. + GitCliEnabled *bool +} + +type ListReposRequest struct { + // Filters repos that have paths starting with the given path prefix. If not + // provided or when provided an effectively empty prefix (`/` or `/Workspace`) + // Git folders (repos) from `/Workspace/Repos` will be served. + PathPrefix *string + // Token used to get the next page of results. If not specified, returns the + // first page of results as well as a next page token if there are more results. + NextPageToken *string +} + +type ListReposResponse struct { + // List of Git folders (repos). + Repos []RepoInfo + // Token that can be specified as a query parameter to the `GET /repos` endpoint + // to retrieve the next page of results. + NextPageToken *string +} + +// Git folder (repo) information.. +type RepoInfo struct { + // Id of the git folder (repo) in the Workspace. + Id *int64 + // Root path of the git folder (repo) in the Workspace. + Path *string + // URL of the remote git repository. + Url *string + // Git provider of the remote git repository, e.g. `gitHub`, + // `azureDevOpsServices`, `bitbucketServer` (Bitbucket Data Center), + // `gitLabEnterpriseEdition` (GitLab Self-Managed), or `awsCodeCommit`. + Provider *string + // Name of the current git branch of the git folder (repo). + Branch *string + // Current git commit id of the git folder (repo). + HeadCommitId *string + // Sparse checkout config for the git folder (repo). + SparseCheckout *SparseCheckout +} + +// Sparse checkout configuration, it contains options like cone patterns.. +type SparseCheckout struct { + // List of sparse checkout cone patterns, see [cone mode handling] for details. + // + // [cone mode handling]: https://git-scm.com/docs/git-sparse-checkout#_internalscone_mode_handling + Patterns []string +} + +// Sparse checkout configuration, it contains options like cone patterns.. +type SparseCheckoutUpdate struct { + // List of sparse checkout cone patterns, see [cone mode handling] for details. + // + // [cone mode handling]: https://git-scm.com/docs/git-sparse-checkout#_internalscone_mode_handling + Patterns []string +} + +type UpdateRepoRequest struct { + // ID of the Git folder (repo) object in the workspace. + Id *int64 + // Branch that the local version of the repo is checked out to. + Branch *string + // Tag that the local version of the repo is checked out to. Updating the repo + // to a tag puts the repo in a detached HEAD state. Before committing new + // changes, you must update the repo to a branch instead of the detached HEAD. + Tag *string + // If specified, update the sparse checkout settings. The update will fail if + // sparse checkout is not enabled for the repo. + SparseCheckout *SparseCheckoutUpdate + // WARNING: DESTRUCTIVE AND IRREVERSIBLE. If true, permanently deletes ALL + // uncommitted changes in the Git folder — staged, unstaged, and untracked + // files — before updating. Lost data CANNOT be recovered. + // + // NEVER use this on Git folders where users author or edit files. This flag is + // intended ONLY for automated jobs that treat the Git folder as a read-only + // mirror of a remote branch and need to force-sync it. If any user has + // uncommitted work in the Git folder, that work will be permanently destroyed + // without warning. + // + // Local commits that have been made but not yet pushed to the remote are + // preserved. + DangerouslyForceDiscardAll *bool + // Git credential ID to use for this update operation. The Git credential must + // be configured for the current user. + GitCredentialId *int64 +} + +type UpdateRepoResponse struct { +} diff --git a/repos/v1/wire.go b/repos/v1/wire.go new file mode 100755 index 0000000..645bd86 --- /dev/null +++ b/repos/v1/wire.go @@ -0,0 +1,232 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package repos + +import ( + "fmt" +) + +type createRepoRequestWire struct { + Url *string `json:"url,omitempty"` + Provider *string `json:"provider,omitempty"` + Path *string `json:"path,omitempty"` + SparseCheckout *sparseCheckoutWire `json:"sparse_checkout,omitempty"` + GitCredentialId *int64 `json:"git_credential_id,omitempty"` +} + +func createRepoRequestToWire(v *CreateRepoRequest) (*createRepoRequestWire, error) { + if v == nil { + return nil, nil + } + sparseCheckoutWireValue, err := sparseCheckoutToWire(v.SparseCheckout) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRepoRequest.SparseCheckout", err) + } + return &createRepoRequestWire{ + Url: v.Url, + Provider: v.Provider, + Path: v.Path, + SparseCheckout: sparseCheckoutWireValue, + GitCredentialId: v.GitCredentialId, + }, nil +} + +type createRepoResponseWire struct { + Id *int64 `json:"id,omitempty"` + Path *string `json:"path,omitempty"` + Url *string `json:"url,omitempty"` + Provider *string `json:"provider,omitempty"` + Branch *string `json:"branch,omitempty"` + HeadCommitId *string `json:"head_commit_id,omitempty"` + SparseCheckout *sparseCheckoutWire `json:"sparse_checkout,omitempty"` +} + +func createRepoResponseFromWire(w *createRepoResponseWire) (*CreateRepoResponse, error) { + if w == nil { + return nil, nil + } + sparseCheckoutPublicValue, err := sparseCheckoutFromWire(w.SparseCheckout) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRepoResponse.SparseCheckout", err) + } + return &CreateRepoResponse{ + Id: w.Id, + Path: w.Path, + Url: w.Url, + Provider: w.Provider, + Branch: w.Branch, + HeadCommitId: w.HeadCommitId, + SparseCheckout: sparseCheckoutPublicValue, + }, nil +} + +type getRepoResponseWire struct { + Id *int64 `json:"id,omitempty"` + Path *string `json:"path,omitempty"` + Url *string `json:"url,omitempty"` + Provider *string `json:"provider,omitempty"` + Branch *string `json:"branch,omitempty"` + HeadCommitId *string `json:"head_commit_id,omitempty"` + SparseCheckout *sparseCheckoutWire `json:"sparse_checkout,omitempty"` + GitCliEnabled *bool `json:"git_cli_enabled,omitempty"` +} + +func getRepoResponseFromWire(w *getRepoResponseWire) (*GetRepoResponse, error) { + if w == nil { + return nil, nil + } + sparseCheckoutPublicValue, err := sparseCheckoutFromWire(w.SparseCheckout) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRepoResponse.SparseCheckout", err) + } + return &GetRepoResponse{ + Id: w.Id, + Path: w.Path, + Url: w.Url, + Provider: w.Provider, + Branch: w.Branch, + HeadCommitId: w.HeadCommitId, + SparseCheckout: sparseCheckoutPublicValue, + GitCliEnabled: w.GitCliEnabled, + }, nil +} + +type listReposRequestWire struct { + PathPrefix *string `json:"path_prefix,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listReposRequestToWire(v *ListReposRequest) (*listReposRequestWire, error) { + if v == nil { + return nil, nil + } + return &listReposRequestWire{ + PathPrefix: v.PathPrefix, + NextPageToken: v.NextPageToken, + }, nil +} + +type listReposResponseWire struct { + Repos []repoInfoWire `json:"repos,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listReposResponseFromWire(w *listReposResponseWire) (*ListReposResponse, error) { + if w == nil { + return nil, nil + } + reposPublicValue, err := convertSlice(w.Repos, repoInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListReposResponse.Repos", err) + } + return &ListReposResponse{ + Repos: reposPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type repoInfoWire struct { + Id *int64 `json:"id,omitempty"` + Path *string `json:"path,omitempty"` + Url *string `json:"url,omitempty"` + Provider *string `json:"provider,omitempty"` + Branch *string `json:"branch,omitempty"` + HeadCommitId *string `json:"head_commit_id,omitempty"` + SparseCheckout *sparseCheckoutWire `json:"sparse_checkout,omitempty"` +} + +func repoInfoFromWire(w *repoInfoWire) (*RepoInfo, error) { + if w == nil { + return nil, nil + } + sparseCheckoutPublicValue, err := sparseCheckoutFromWire(w.SparseCheckout) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RepoInfo.SparseCheckout", err) + } + return &RepoInfo{ + Id: w.Id, + Path: w.Path, + Url: w.Url, + Provider: w.Provider, + Branch: w.Branch, + HeadCommitId: w.HeadCommitId, + SparseCheckout: sparseCheckoutPublicValue, + }, nil +} + +type sparseCheckoutWire struct { + Patterns []string `json:"patterns,omitempty"` +} + +func sparseCheckoutToWire(v *SparseCheckout) (*sparseCheckoutWire, error) { + if v == nil { + return nil, nil + } + return &sparseCheckoutWire{ + Patterns: v.Patterns, + }, nil +} + +func sparseCheckoutFromWire(w *sparseCheckoutWire) (*SparseCheckout, error) { + if w == nil { + return nil, nil + } + return &SparseCheckout{ + Patterns: w.Patterns, + }, nil +} + +type sparseCheckoutUpdateWire struct { + Patterns []string `json:"patterns,omitempty"` +} + +func sparseCheckoutUpdateToWire(v *SparseCheckoutUpdate) (*sparseCheckoutUpdateWire, error) { + if v == nil { + return nil, nil + } + return &sparseCheckoutUpdateWire{ + Patterns: v.Patterns, + }, nil +} + +type updateRepoRequestWire struct { + Id *int64 `json:"id,omitempty"` + Branch *string `json:"branch,omitempty"` + Tag *string `json:"tag,omitempty"` + SparseCheckout *sparseCheckoutUpdateWire `json:"sparse_checkout,omitempty"` + DangerouslyForceDiscardAll *bool `json:"dangerously_force_discard_all,omitempty"` + GitCredentialId *int64 `json:"git_credential_id,omitempty"` +} + +func updateRepoRequestToWire(v *UpdateRepoRequest) (*updateRepoRequestWire, error) { + if v == nil { + return nil, nil + } + sparseCheckoutWireValue, err := sparseCheckoutUpdateToWire(v.SparseCheckout) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRepoRequest.SparseCheckout", err) + } + return &updateRepoRequestWire{ + Id: v.Id, + Branch: v.Branch, + Tag: v.Tag, + SparseCheckout: sparseCheckoutWireValue, + DangerouslyForceDiscardAll: v.DangerouslyForceDiscardAll, + GitCredentialId: v.GitCredentialId, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/scim/.package.json b/scim/.package.json new file mode 100644 index 0000000..1e0e31d --- /dev/null +++ b/scim/.package.json @@ -0,0 +1,3 @@ +{ + "package": "scim" +} diff --git a/scim/CHANGELOG.md b/scim/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/scim/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/scim/README.md b/scim/README.md new file mode 100644 index 0000000..888bf06 --- /dev/null +++ b/scim/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/scim + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/scim@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/scim/v1" + +client, err := scim.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/scim/go.mod b/scim/go.mod new file mode 100644 index 0000000..44e6d32 --- /dev/null +++ b/scim/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/scim + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/scim/internal/version.go b/scim/internal/version.go new file mode 100644 index 0000000..8242554 --- /dev/null +++ b/scim/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-scim" + +const Version = "0.0.1-dev.1" diff --git a/scim/v1/client.go b/scim/v1/client.go new file mode 100755 index 0000000..fed7749 --- /dev/null +++ b/scim/v1/client.go @@ -0,0 +1,3136 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package scim + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/scim/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a group in the account with a unique name, using the +// supplied group details. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateAccountGroup(ctx context.Context, req *CreateAccountGroupRequest, opts ...call.Option) (*AccountGroup, error) { + wireReq, err := createAccountGroupRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Groups") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountGroup + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountGroupWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountGroupFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a group from the account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteAccountGroup(ctx context.Context, req *DeleteAccountGroupRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Groups/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets the information for a specific group in the account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetAccountGroup(ctx context.Context, req *GetAccountGroupRequest, opts ...call.Option) (*AccountGroup, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Groups/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountGroup + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountGroupWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountGroupFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets all details of the groups associated with the account. As +// of 08/22/2025, this endpoint will no longer return members. Instead, members +// should be retrieved by iterating through `Get group details`. Existing +// accounts that rely on this attribute will not be impacted and will continue +// receiving member data as before. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListAccountGroups(ctx context.Context, req *ListAccountGroupsRequest, opts ...call.Option) (*ListAccountGroupsResponse, error) { + wireReq, err := listAccountGroupsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Groups") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "attributes", wireReq.Attributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "excludedAttributes", wireReq.ExcludedAttributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "startIndex", wireReq.StartIndex); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "count", wireReq.Count); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "sortBy", wireReq.SortBy); err != nil { + return nil, err + } + if wireReq.SortOrder != "" { + if err := addQueryValue(queryParams, "sortOrder", wireReq.SortOrder); err != nil { + return nil, err + } + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAccountGroupsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAccountGroupsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAccountGroupsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListAccountGroupsIter returns an iterator that iterates +// over the results of ListAccountGroups. +// +// For example: +// +// for item, err := range c.ListAccountGroupsIter(ctx, &ListAccountGroupsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListAccountGroups call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListAccountGroups directly. +func (c *internalClient) ListAccountGroupsIter(ctx context.Context, req *ListAccountGroupsRequest, opts ...call.Option) iter.Seq2[*AccountGroup, error] { + return func(yield func(*AccountGroup, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListAccountGroupsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListAccountGroups(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + items := resp.Resources + for i := range items { + if !yield(&items[i], nil) { + return + } + } + if len(items) == 0 { + return + } + nextOffset := int64(len(items)) + if resp.StartIndex != nil { + nextOffset += *resp.StartIndex + } + pageReq.StartIndex = new(nextOffset) + } + } +} + +// Partially updates the details of a group. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) PatchAccountGroup(ctx context.Context, req *PatchAccountGroupRequest, opts ...call.Option) error { + wireReq, err := patchAccountGroupRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Groups/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Updates the details of a group by replacing the entire group entity. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateAccountGroup(ctx context.Context, req *UpdateAccountGroupRequest, opts ...call.Option) error { + wireReq, err := updateAccountGroupRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Groups/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Creates a new service principal in the account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateAccountServicePrincipal(ctx context.Context, req *CreateAccountServicePrincipalRequest, opts ...call.Option) (*AccountServicePrincipal, error) { + wireReq, err := createAccountServicePrincipalRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/ServicePrincipals") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountServicePrincipal + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountServicePrincipalWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountServicePrincipalFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a single service principal in the account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteAccountServicePrincipal(ctx context.Context, req *DeleteAccountServicePrincipalRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/ServicePrincipals/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets the details for a single service principal define in the +// account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetAccountServicePrincipal(ctx context.Context, req *GetAccountServicePrincipalRequest, opts ...call.Option) (*AccountServicePrincipal, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/ServicePrincipals/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountServicePrincipal + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountServicePrincipalWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountServicePrincipalFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the set of service principals associated with a account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListAccountServicePrincipals(ctx context.Context, req *ListAccountServicePrincipalsRequest, opts ...call.Option) (*ListAccountServicePrincipalsResponse, error) { + wireReq, err := listAccountServicePrincipalsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/ServicePrincipals") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "attributes", wireReq.Attributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "count", wireReq.Count); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "excludedAttributes", wireReq.ExcludedAttributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "sortBy", wireReq.SortBy); err != nil { + return nil, err + } + if wireReq.SortOrder != "" { + if err := addQueryValue(queryParams, "sortOrder", wireReq.SortOrder); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "startIndex", wireReq.StartIndex); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAccountServicePrincipalsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAccountServicePrincipalsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAccountServicePrincipalsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListAccountServicePrincipalsIter returns an iterator that iterates +// over the results of ListAccountServicePrincipals. +// +// For example: +// +// for item, err := range c.ListAccountServicePrincipalsIter(ctx, &ListAccountServicePrincipalsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListAccountServicePrincipals call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListAccountServicePrincipals directly. +func (c *internalClient) ListAccountServicePrincipalsIter(ctx context.Context, req *ListAccountServicePrincipalsRequest, opts ...call.Option) iter.Seq2[*AccountServicePrincipal, error] { + return func(yield func(*AccountServicePrincipal, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListAccountServicePrincipalsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListAccountServicePrincipals(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + items := resp.Resources + for i := range items { + if !yield(&items[i], nil) { + return + } + } + if len(items) == 0 { + return + } + nextOffset := int64(len(items)) + if resp.StartIndex != nil { + nextOffset += *resp.StartIndex + } + pageReq.StartIndex = new(nextOffset) + } + } +} + +// Partially updates the details of a single service principal in the +// account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) PatchAccountServicePrincipal(ctx context.Context, req *PatchAccountServicePrincipalRequest, opts ...call.Option) error { + wireReq, err := patchAccountServicePrincipalRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/ServicePrincipals/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Updates the details of a single service principal. +// +// This action replaces the existing service principal with the same name. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateAccountServicePrincipal(ctx context.Context, req *UpdateAccountServicePrincipalRequest, opts ...call.Option) error { + wireReq, err := updateAccountServicePrincipalRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/ServicePrincipals/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Creates a new user in the account. This new user will also be +// added to the account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateAccountUser(ctx context.Context, req *CreateAccountUserRequest, opts ...call.Option) (*AccountUser, error) { + wireReq, err := createAccountUserRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Users") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountUser + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountUserWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountUserFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a user. Deleting a user from a account also removes +// objects associated with the user. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteAccountUser(ctx context.Context, req *DeleteAccountUserRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Users/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets information for a specific user in account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetAccountUser(ctx context.Context, req *GetAccountUserRequest, opts ...call.Option) (*AccountUser, error) { + wireReq, err := getAccountUserRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Users/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "attributes", wireReq.Attributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "count", wireReq.Count); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "excludedAttributes", wireReq.ExcludedAttributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "sortBy", wireReq.SortBy); err != nil { + return nil, err + } + if wireReq.SortOrder != "" { + if err := addQueryValue(queryParams, "sortOrder", wireReq.SortOrder); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "startIndex", wireReq.StartIndex); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountUser + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountUserWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountUserFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets details for all the users associated with a account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListAccountUsers(ctx context.Context, req *ListAccountUsersRequest, opts ...call.Option) (*ListAccountUsersResponse, error) { + wireReq, err := listAccountUsersRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Users") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "attributes", wireReq.Attributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "count", wireReq.Count); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "excludedAttributes", wireReq.ExcludedAttributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "sortBy", wireReq.SortBy); err != nil { + return nil, err + } + if wireReq.SortOrder != "" { + if err := addQueryValue(queryParams, "sortOrder", wireReq.SortOrder); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "startIndex", wireReq.StartIndex); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAccountUsersResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAccountUsersResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAccountUsersResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListAccountUsersIter returns an iterator that iterates +// over the results of ListAccountUsers. +// +// For example: +// +// for item, err := range c.ListAccountUsersIter(ctx, &ListAccountUsersRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListAccountUsers call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListAccountUsers directly. +func (c *internalClient) ListAccountUsersIter(ctx context.Context, req *ListAccountUsersRequest, opts ...call.Option) iter.Seq2[*AccountUser, error] { + return func(yield func(*AccountUser, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListAccountUsersRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListAccountUsers(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + items := resp.Resources + for i := range items { + if !yield(&items[i], nil) { + return + } + } + if len(items) == 0 { + return + } + nextOffset := int64(len(items)) + if resp.StartIndex != nil { + nextOffset += *resp.StartIndex + } + pageReq.StartIndex = new(nextOffset) + } + } +} + +// Partially updates a user resource by applying the supplied operations on +// specific user attributes. The `userName` and `emails` attributes cannot be +// updated through this API; any supplied changes to them are ignored (no-op). +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) PatchAccountUser(ctx context.Context, req *PatchAccountUserRequest, opts ...call.Option) error { + wireReq, err := patchAccountUserRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Users/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Replaces a user's information with the data supplied in request. The +// `userName` and `emails` attributes cannot be updated through this API; any +// supplied changes to them are ignored (no-op). +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateAccountUser(ctx context.Context, req *UpdateAccountUserRequest, opts ...call.Option) error { + wireReq, err := updateAccountUserRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/scim/v2/Users/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Get details about the current method caller's identity. +func (c *internalClient) Me(ctx context.Context, req *MeRequest, opts ...call.Option) (*User, error) { + wireReq, err := meRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/preview/scim/v2/Me" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "attributes", wireReq.Attributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "excludedAttributes", wireReq.ExcludedAttributes); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *User + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp userWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = userFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a group in the workspace with a unique name, using the +// supplied group details. +func (c *internalClient) CreateGroup(ctx context.Context, req *CreateGroupRequest, opts ...call.Option) (*Group, error) { + wireReq, err := createGroupRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/preview/scim/v2/Groups" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Group + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp groupWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = groupFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a group from the workspace. +func (c *internalClient) DeleteGroup(ctx context.Context, req *DeleteGroupRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/Groups/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets the information for a specific group in the workspace. +func (c *internalClient) GetGroup(ctx context.Context, req *GetGroupRequest, opts ...call.Option) (*Group, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/Groups/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Group + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp groupWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = groupFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets all details of the groups associated with the workspace. +func (c *internalClient) ListGroups(ctx context.Context, req *ListGroupsRequest, opts ...call.Option) (*ListGroupsResponse, error) { + wireReq, err := listGroupsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/preview/scim/v2/Groups" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "attributes", wireReq.Attributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "excludedAttributes", wireReq.ExcludedAttributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "startIndex", wireReq.StartIndex); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "count", wireReq.Count); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "sortBy", wireReq.SortBy); err != nil { + return nil, err + } + if wireReq.SortOrder != "" { + if err := addQueryValue(queryParams, "sortOrder", wireReq.SortOrder); err != nil { + return nil, err + } + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListGroupsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listGroupsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listGroupsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListGroupsIter returns an iterator that iterates +// over the results of ListGroups. +// +// For example: +// +// for item, err := range c.ListGroupsIter(ctx, &ListGroupsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListGroups call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListGroups directly. +func (c *internalClient) ListGroupsIter(ctx context.Context, req *ListGroupsRequest, opts ...call.Option) iter.Seq2[*Group, error] { + return func(yield func(*Group, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListGroupsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListGroups(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + items := resp.Resources + for i := range items { + if !yield(&items[i], nil) { + return + } + } + if len(items) == 0 { + return + } + nextOffset := int64(len(items)) + if resp.StartIndex != nil { + nextOffset += *resp.StartIndex + } + pageReq.StartIndex = new(nextOffset) + } + } +} + +// Partially updates the details of a group. +func (c *internalClient) PatchGroup(ctx context.Context, req *PatchGroupRequest, opts ...call.Option) error { + wireReq, err := patchGroupRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/Groups/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Updates the details of a group by replacing the entire group entity. +func (c *internalClient) UpdateGroup(ctx context.Context, req *UpdateGroupRequest, opts ...call.Option) error { + wireReq, err := updateGroupRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/Groups/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Creates a new service principal in the workspace. +func (c *internalClient) CreateServicePrincipal(ctx context.Context, req *CreateServicePrincipalRequest, opts ...call.Option) (*ServicePrincipal, error) { + wireReq, err := createServicePrincipalRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/preview/scim/v2/ServicePrincipals" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ServicePrincipal + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp servicePrincipalWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = servicePrincipalFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a single service principal in the workspace. +func (c *internalClient) DeleteServicePrincipal(ctx context.Context, req *DeleteServicePrincipalRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/ServicePrincipals/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets the details for a single service principal define in the +// workspace. +func (c *internalClient) GetServicePrincipal(ctx context.Context, req *GetServicePrincipalRequest, opts ...call.Option) (*ServicePrincipal, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/ServicePrincipals/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ServicePrincipal + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp servicePrincipalWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = servicePrincipalFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the set of service principals associated with a workspace. +func (c *internalClient) ListServicePrincipals(ctx context.Context, req *ListServicePrincipalsRequest, opts ...call.Option) (*ListServicePrincipalResponse, error) { + wireReq, err := listServicePrincipalsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/preview/scim/v2/ServicePrincipals" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "attributes", wireReq.Attributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "count", wireReq.Count); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "excludedAttributes", wireReq.ExcludedAttributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "sortBy", wireReq.SortBy); err != nil { + return nil, err + } + if wireReq.SortOrder != "" { + if err := addQueryValue(queryParams, "sortOrder", wireReq.SortOrder); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "startIndex", wireReq.StartIndex); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListServicePrincipalResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listServicePrincipalResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listServicePrincipalResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListServicePrincipalsIter returns an iterator that iterates +// over the results of ListServicePrincipals. +// +// For example: +// +// for item, err := range c.ListServicePrincipalsIter(ctx, &ListServicePrincipalsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListServicePrincipals call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListServicePrincipals directly. +func (c *internalClient) ListServicePrincipalsIter(ctx context.Context, req *ListServicePrincipalsRequest, opts ...call.Option) iter.Seq2[*ServicePrincipal, error] { + return func(yield func(*ServicePrincipal, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListServicePrincipalsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListServicePrincipals(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + items := resp.Resources + for i := range items { + if !yield(&items[i], nil) { + return + } + } + if len(items) == 0 { + return + } + nextOffset := int64(len(items)) + if resp.StartIndex != nil { + nextOffset += *resp.StartIndex + } + pageReq.StartIndex = new(nextOffset) + } + } +} + +// Partially updates the details of a single service principal in the +// workspace. +func (c *internalClient) PatchServicePrincipal(ctx context.Context, req *PatchServicePrincipalRequest, opts ...call.Option) error { + wireReq, err := patchServicePrincipalRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/ServicePrincipals/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Updates the details of a single service principal. +// +// This action replaces the existing service principal with the same name. +func (c *internalClient) UpdateServicePrincipal(ctx context.Context, req *UpdateServicePrincipalRequest, opts ...call.Option) error { + wireReq, err := updateServicePrincipalRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/ServicePrincipals/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Creates a new user in the workspace. This new user will also be +// added to the account. +func (c *internalClient) CreateUser(ctx context.Context, req *CreateUserRequest, opts ...call.Option) (*User, error) { + wireReq, err := createUserRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/preview/scim/v2/Users" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *User + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp userWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = userFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a user. Deleting a user from a workspace also removes +// objects associated with the user. +func (c *internalClient) DeleteUser(ctx context.Context, req *DeleteUserRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/Users/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets the permission levels that a user can have on an object. +func (c *internalClient) GetPermissionLevels(ctx context.Context, req *GetPasswordPermissionLevelsRequest, opts ...call.Option) (*GetPasswordPermissionLevelsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/permissions/authorization/passwords/permissionLevels" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPasswordPermissionLevelsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPasswordPermissionLevelsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPasswordPermissionLevelsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the permissions of all passwords. Passwords can inherit permissions from +// their root object. +func (c *internalClient) GetPermissions(ctx context.Context, req *GetPasswordPermissionsRequest, opts ...call.Option) (*PasswordPermissions, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/permissions/authorization/passwords" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PasswordPermissions + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp passwordPermissionsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = passwordPermissionsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets information for a specific user in workspace. +func (c *internalClient) GetUser(ctx context.Context, req *GetUserRequest, opts ...call.Option) (*User, error) { + wireReq, err := getUserRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/Users/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "attributes", wireReq.Attributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "count", wireReq.Count); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "excludedAttributes", wireReq.ExcludedAttributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "sortBy", wireReq.SortBy); err != nil { + return nil, err + } + if wireReq.SortOrder != "" { + if err := addQueryValue(queryParams, "sortOrder", wireReq.SortOrder); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "startIndex", wireReq.StartIndex); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *User + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp userWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = userFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets details for all the users associated with a workspace. +func (c *internalClient) ListUsers(ctx context.Context, req *ListUsersRequest, opts ...call.Option) (*ListUsersResponse, error) { + wireReq, err := listUsersRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/preview/scim/v2/Users" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "attributes", wireReq.Attributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "count", wireReq.Count); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "excludedAttributes", wireReq.ExcludedAttributes); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "filter", wireReq.Filter); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "sortBy", wireReq.SortBy); err != nil { + return nil, err + } + if wireReq.SortOrder != "" { + if err := addQueryValue(queryParams, "sortOrder", wireReq.SortOrder); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "startIndex", wireReq.StartIndex); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListUsersResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listUsersResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listUsersResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListUsersIter returns an iterator that iterates +// over the results of ListUsers. +// +// For example: +// +// for item, err := range c.ListUsersIter(ctx, &ListUsersRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListUsers call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListUsers directly. +func (c *internalClient) ListUsersIter(ctx context.Context, req *ListUsersRequest, opts ...call.Option) iter.Seq2[*User, error] { + return func(yield func(*User, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListUsersRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListUsers(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + items := resp.Resources + for i := range items { + if !yield(&items[i], nil) { + return + } + } + if len(items) == 0 { + return + } + nextOffset := int64(len(items)) + if resp.StartIndex != nil { + nextOffset += *resp.StartIndex + } + pageReq.StartIndex = new(nextOffset) + } + } +} + +// Partially updates a user resource by applying the supplied operations on +// specific user attributes. The `userName` and `emails` attributes cannot be +// updated through this API; any supplied changes to them are ignored (no-op). +func (c *internalClient) PatchUser(ctx context.Context, req *PatchUserRequest, opts ...call.Option) error { + wireReq, err := patchUserRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/Users/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Sets permissions on an object, replacing existing permissions if they exist. +// Deletes all direct permissions if none are specified. Objects can inherit +// permissions from their root object. +func (c *internalClient) SetPermissions(ctx context.Context, req *PasswordPermissionsRequest, opts ...call.Option) (*PasswordPermissions, error) { + wireReq, err := passwordPermissionsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/permissions/authorization/passwords" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PasswordPermissions + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp passwordPermissionsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = passwordPermissionsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the permissions on all passwords. Passwords can inherit permissions +// from their root object. +func (c *internalClient) UpdatePermissions(ctx context.Context, req *PasswordPermissionsRequest, opts ...call.Option) (*PasswordPermissions, error) { + wireReq, err := passwordPermissionsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/permissions/authorization/passwords" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PasswordPermissions + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp passwordPermissionsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = passwordPermissionsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Replaces a user's information with the data supplied in request. The +// `userName` and `emails` attributes cannot be updated through this API; any +// supplied changes to them are ignored (no-op). +func (c *internalClient) UpdateUser(ctx context.Context, req *UpdateUserRequest, opts ...call.Option) error { + wireReq, err := updateUserRequestToWire(req) + if err != nil { + return err + } + body, err := json.Marshal(wireReq) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/preview/scim/v2/Users/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} diff --git a/scim/v1/genhelper.go b/scim/v1/genhelper.go new file mode 100755 index 0000000..2984f40 --- /dev/null +++ b/scim/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package scim + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/scim/v1/model.go b/scim/v1/model.go new file mode 100755 index 0000000..ece2ca7 --- /dev/null +++ b/scim/v1/model.go @@ -0,0 +1,1061 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package scim + +import "encoding/json" + +type GetSortOrder string + +const ( + GetSortOrder_Unspecified GetSortOrder = "" + GetSortOrder_Ascending GetSortOrder = "ascending" + GetSortOrder_Descending GetSortOrder = "descending" +) + +type GroupSchema string + +const ( + GroupSchema_Unspecified GroupSchema = "" + GroupSchema_UrnIetfParamsScimSchemasCore20Group GroupSchema = "urn:ietf:params:scim:schemas:core:2.0:Group" +) + +type ListResponseSchema string + +const ( + ListResponseSchema_Unspecified ListResponseSchema = "" + ListResponseSchema_UrnIetfParamsScimApiMessages20ListResponse ListResponseSchema = "urn:ietf:params:scim:api:messages:2.0:ListResponse" +) + +// Type of patch operation. +type PatchOp string + +const ( + PatchOp_Unspecified PatchOp = "" + PatchOp_Add PatchOp = "add" + PatchOp_Remove PatchOp = "remove" + PatchOp_Replace PatchOp = "replace" +) + +type PatchSchema string + +const ( + PatchSchema_Unspecified PatchSchema = "" + PatchSchema_UrnIetfParamsScimApiMessages20PatchOp PatchSchema = "urn:ietf:params:scim:api:messages:2.0:PatchOp" +) + +type ServicePrincipalSchema string + +const ( + ServicePrincipalSchema_Unspecified ServicePrincipalSchema = "" + ServicePrincipalSchema_UrnIetfParamsScimSchemasCore20ServicePrincipal ServicePrincipalSchema = "urn:ietf:params:scim:schemas:core:2.0:ServicePrincipal" +) + +type UserSchema string + +const ( + UserSchema_Unspecified UserSchema = "" + UserSchema_UrnIetfParamsScimSchemasCore20User UserSchema = "urn:ietf:params:scim:schemas:core:2.0:User" + UserSchema_UrnIetfParamsScimSchemasExtensionWorkspace20User UserSchema = "urn:ietf:params:scim:schemas:extension:workspace:2.0:User" +) + +type AccountGetSortOrder_GetSortOrder string + +const ( + AccountGetSortOrder_GetSortOrder_Unspecified AccountGetSortOrder_GetSortOrder = "" + AccountGetSortOrder_GetSortOrder_Ascending AccountGetSortOrder_GetSortOrder = "ascending" + AccountGetSortOrder_GetSortOrder_Descending AccountGetSortOrder_GetSortOrder = "descending" +) + +type AccountListSort_Order string + +const ( + AccountListSort_Order_Unspecified AccountListSort_Order = "" + AccountListSort_Order_Ascending AccountListSort_Order = "ascending" + AccountListSort_Order_Descending AccountListSort_Order = "descending" +) + +// Type of patch operation. +type AccountPatchOp_PatchOp string + +const ( + AccountPatchOp_PatchOp_Unspecified AccountPatchOp_PatchOp = "" + AccountPatchOp_PatchOp_Add AccountPatchOp_PatchOp = "add" + AccountPatchOp_PatchOp_Remove AccountPatchOp_PatchOp = "remove" + AccountPatchOp_PatchOp_Replace AccountPatchOp_PatchOp = "replace" +) + +type AccountPatchSchema_PatchSchema string + +const ( + AccountPatchSchema_PatchSchema_Unspecified AccountPatchSchema_PatchSchema = "" + AccountPatchSchema_PatchSchema_UrnIetfParamsScimApiMessages20PatchOp AccountPatchSchema_PatchSchema = "urn:ietf:params:scim:api:messages:2.0:PatchOp" +) + +type ListSort_Order string + +const ( + ListSort_Order_Unspecified ListSort_Order = "" + ListSort_Order_Ascending ListSort_Order = "ascending" + ListSort_Order_Descending ListSort_Order = "descending" +) + +// Permission level +type PasswordPermission_Level string + +const ( + PasswordPermission_Level_Unspecified PasswordPermission_Level = "" + PasswordPermission_Level_CanUse PasswordPermission_Level = "CAN_USE" +) + +type AccountComplexValue struct { + Display *string + Primary *bool + Ref *string + Type *string + Value *string +} + +type AccountGetSortOrder struct { +} + +type AccountGroup struct { + // String that represents a human-readable group name + DisplayName *string + // external_id should be unique for identifying groups + ExternalId *string + // group ID + Id *string + Members []AccountComplexValue + // Container for the group identifier. Workspace local versus account. + Meta *AccountResourceMeta + // Indicates if the group has the admin role. + Roles []AccountComplexValue + // account ID + AccountId *string +} + +// ListSortOrder and GetSortOrder share enum values, which is not supported. We +// use nesting as a workaround.. +type AccountListSort struct { +} + +type AccountName struct { + // Family name of the user. + FamilyName *string + // Given name of the user. + GivenName *string +} + +type AccountPatch struct { + // Type of patch operation. + Op AccountPatchOp_PatchOp + // Selection of patch operation + Path *string + // Value to modify + Value json.RawMessage +} + +type AccountPatchOp struct { +} + +type AccountPatchSchema struct { +} + +type AccountResourceMeta struct { + // Identifier for group type. Can be local workspace group (`WorkspaceGroup`) or + // account group (`Group`). + ResourceType *string +} + +type AccountServicePrincipal struct { + // If this user is active + Active *bool + // UUID relating to the service principal + ApplicationId *string + // String that represents a concatenation of given and family names. + DisplayName *string + ExternalId *string + // service principal ID. + Id *string + // Indicates if the group has the admin role. + Roles []AccountComplexValue + // account ID + AccountId *string +} + +type AccountUser struct { + // If this user is active + Active *bool + // String that represents a concatenation of given and family names. For example + // `John Smith`. + DisplayName *string + // All the emails associated with the user. This attribute cannot + // be updated through the SCIM PATCH or PUT APIs; any supplied change is + // ignored. + Emails []AccountComplexValue + // External ID is not currently supported. It is reserved for future use. + ExternalId *string + // user ID. + Id *string + Name *AccountName + // Indicates if the group has the admin role. + Roles []AccountComplexValue + // Email address of the user. This attribute cannot be updated + // through the SCIM PATCH or PUT APIs; any supplied change is ignored. + UserName *string + // account ID + AccountId *string +} + +type ComplexValue struct { + Display *string + Primary *bool + Ref *string + Type *string + Value *string +} + +type CreateAccountGroupRequest struct { + // String that represents a human-readable group name + DisplayName *string + ExternalId *string + // group ID + Id *string + Members []AccountComplexValue + // Container for the group identifier. Workspace local versus account. + Meta *AccountResourceMeta + // Indicates if the group has the admin role. + Roles []AccountComplexValue + // account ID + AccountId *string +} + +type CreateAccountServicePrincipalRequest struct { + // If this user is active + Active *bool + // UUID relating to the service principal + ApplicationId *string + // String that represents a concatenation of given and family names. + DisplayName *string + ExternalId *string + // service principal ID. + Id *string + // Indicates if the group has the admin role. + Roles []AccountComplexValue + // account ID + AccountId *string +} + +type CreateAccountUserRequest struct { + // If this user is active + Active *bool + // String that represents a concatenation of given and family names. For example + // `John Smith`. + DisplayName *string + // All the emails associated with the user. + Emails []AccountComplexValue + // External ID is not currently supported. It is reserved for future use. + ExternalId *string + // user ID. + Id *string + Name *AccountName + // Indicates if the group has the admin role. + Roles []AccountComplexValue + // Email address of the user. + UserName *string + // account ID + AccountId *string +} + +type CreateGroupRequest struct { + // String that represents a human-readable group name + DisplayName *string + // Entitlements assigned to the group. See [assigning entitlements] for a full + // list of supported values. + // + // [assigning entitlements]: https://docs.databricks.com/administration-guide/users-groups/index.html#assigning-entitlements + Entitlements []ComplexValue + ExternalId *string + Groups []ComplexValue + // group ID + Id *string + Members []ComplexValue + // Container for the group identifier. Workspace local versus account. + Meta *ResourceMeta + // Corresponds to AWS instance profile/arn role. + Roles []ComplexValue + // The schema of the group. + Schemas []GroupSchema +} + +type CreateServicePrincipalRequest struct { + // If this user is active + Active *bool + // UUID relating to the service principal + ApplicationId *string + // String that represents a concatenation of given and family names. + DisplayName *string + // Entitlements assigned to the service principal. See [assigning entitlements] + // for a full list of supported values. + // + // [assigning entitlements]: https://docs.databricks.com/administration-guide/users-groups/index.html#assigning-entitlements + Entitlements []ComplexValue + ExternalId *string + Groups []ComplexValue + // service principal ID. + Id *string + // Corresponds to AWS instance profile/arn role. + Roles []ComplexValue + // The schema of the List response. + Schemas []ServicePrincipalSchema +} + +type CreateUserRequest struct { + // If this user is active + Active *bool + // String that represents a concatenation of given and family names. For example + // `John Smith`. This field cannot be updated through the Workspace SCIM APIs + // when [identity federation is enabled]. Use Account SCIM APIs to update + // `displayName`. + // + // [identity federation is enabled]: https://docs.databricks.com/administration-guide/users-groups/best-practices.html#enable-identity-federation + DisplayName *string + // All the emails associated with the user. + Emails []ComplexValue + // Entitlements assigned to the user. See [assigning entitlements] for a full + // list of supported values. + // + // [assigning entitlements]: https://docs.databricks.com/administration-guide/users-groups/index.html#assigning-entitlements + Entitlements []ComplexValue + // External ID is not currently supported. It is reserved for future use. + ExternalId *string + Groups []ComplexValue + // user ID. + Id *string + Name *Name + // Corresponds to AWS instance profile/arn role. + Roles []ComplexValue + // The schema of the user. + Schemas []UserSchema + // Email address of the user. + UserName *string +} + +// Delete a group. +type DeleteAccountGroupRequest struct { + // Unique ID for a group in the account. + Id *string + // account ID + AccountId *string +} + +// Delete a service principal. +type DeleteAccountServicePrincipalRequest struct { + // Unique ID for a service principal in the account. + Id *string + // account ID + AccountId *string +} + +// Delete a user. +type DeleteAccountUserRequest struct { + // Unique ID for a user in the account. + Id *string + // account ID + AccountId *string +} + +// Delete a group. +type DeleteGroupRequest struct { + // Unique ID for a group in the workspace. + Id *string +} + +// Delete a service principal. +type DeleteServicePrincipalRequest struct { + // Unique ID for a service principal in the workspace. + Id *string +} + +// Delete a user. +type DeleteUserRequest struct { + // Unique ID for a user in the workspace. + Id *string +} + +// Get group details. +type GetAccountGroupRequest struct { + // Unique ID for a group in the account. + Id *string + // account ID + AccountId *string +} + +// Get service principal details. +type GetAccountServicePrincipalRequest struct { + // Unique ID for a service principal in the account. + Id *string + // account ID + AccountId *string +} + +// Get user details. +type GetAccountUserRequest struct { + // Comma-separated list of attributes to return in response. + Attributes *string + // Desired number of results per page. Default is 10000. + Count *int + // Comma-separated list of attributes to exclude in response. + ExcludedAttributes *string + // Query by which the results have to be filtered. Supported operators are + // equals(`eq`), contains(`co`), starts with(`sw`) and not equals(`ne`). + // Additionally, simple expressions can be formed using logical operators - + // `and` and `or`. The [SCIM RFC] has more details but we currently only support + // simple expressions. + // + // [SCIM RFC]: https://tools.ietf.org/html/rfc7644#section-3.4.2.2 + Filter *string + // Unique ID for a user in the account. + Id *string + // Attribute to sort the results. Multi-part paths are supported. For example, + // `userName`, `name.givenName`, and `emails`. + SortBy *string + // The order to sort the results. + SortOrder AccountGetSortOrder_GetSortOrder + // Specifies the index of the first result. First item is number 1. + StartIndex *int + // account ID + AccountId *string +} + +// Get group details. +type GetGroupRequest struct { + // Unique ID for a group in the workspace. + Id *string +} + +// Get object permission levels. +type GetPasswordPermissionLevelsRequest struct { +} + +type GetPasswordPermissionLevelsResponse struct { + // Specific permission levels + PermissionLevels []PasswordPermissionsDescription +} + +type GetPasswordPermissionsRequest struct { +} + +// Get service principal details. +type GetServicePrincipalRequest struct { + // Unique ID for a service principal in the workspace. + Id *string +} + +// Get user details. +type GetUserRequest struct { + // Comma-separated list of attributes to return in response. + Attributes *string + // Desired number of results per page. + Count *int + // Comma-separated list of attributes to exclude in response. + ExcludedAttributes *string + // Query by which the results have to be filtered. Supported operators are + // equals(`eq`), contains(`co`), starts with(`sw`) and not equals(`ne`). + // Additionally, simple expressions can be formed using logical operators - + // `and` and `or`. The [SCIM RFC] has more details but we currently only support + // simple expressions. + // + // [SCIM RFC]: https://tools.ietf.org/html/rfc7644#section-3.4.2.2 + Filter *string + // Unique ID for a user in the workspace. + Id *string + // Attribute to sort the results. Multi-part paths are supported. For example, + // `userName`, `name.givenName`, and `emails`. + SortBy *string + // The order to sort the results. + SortOrder GetSortOrder + // Specifies the index of the first result. First item is number 1. + StartIndex *int +} + +type Group struct { + // String that represents a human-readable group name + DisplayName *string + // Entitlements assigned to the group. See [assigning entitlements] for a full + // list of supported values. + // + // [assigning entitlements]: https://docs.databricks.com/administration-guide/users-groups/index.html#assigning-entitlements + Entitlements []ComplexValue + // external_id should be unique for identifying groups + ExternalId *string + Groups []ComplexValue + // group ID + Id *string + Members []ComplexValue + // Container for the group identifier. Workspace local versus account. + Meta *ResourceMeta + // Corresponds to AWS instance profile/arn role. + Roles []ComplexValue + // The schema of the group. + Schemas []GroupSchema +} + +// List group details. +type ListAccountGroupsRequest struct { + // account ID + AccountId *string + // Query by which the results have to be filtered. Supported operators are + // equals(`eq`), contains(`co`), starts with(`sw`) and not equals(`ne`). + // Additionally, simple expressions can be formed using logical operators - + // `and` and `or`. The [SCIM RFC] has more details but we currently only support + // simple expressions. + // + // [SCIM RFC]: https://tools.ietf.org/html/rfc7644#section-3.4.2.2 + Filter *string + // Comma-separated list of attributes to return in response. + Attributes *string + // Comma-separated list of attributes to exclude in response. + ExcludedAttributes *string + // Specifies the index of the first result. First item is number 1. + StartIndex *int64 + // Desired number of results per page. Default is 10000. + Count *int64 + // Attribute to sort the results. + SortBy *string + // The order to sort the results. + SortOrder AccountListSort_Order +} + +type ListAccountGroupsResponse struct { + // Total results returned in the response. + ItemsPerPage *int + // User objects returned in the response. + Resources []AccountGroup + // Starting index of all the results that matched the request filters. First + // item is number 1. + StartIndex *int64 + // Total results that match the request filters. + TotalResults *int +} + +// List service principals. +type ListAccountServicePrincipalsRequest struct { + // Comma-separated list of attributes to return in response. + Attributes *string + // Desired number of results per page. Default is 10000. + Count *int64 + // Comma-separated list of attributes to exclude in response. + ExcludedAttributes *string + // Query by which the results have to be filtered. Supported operators are + // equals(`eq`), contains(`co`), starts with(`sw`) and not equals(`ne`). + // Additionally, simple expressions can be formed using logical operators - + // `and` and `or`. The [SCIM RFC] has more details but we currently only support + // simple expressions. + // + // [SCIM RFC]: https://tools.ietf.org/html/rfc7644#section-3.4.2.2 + Filter *string + // Attribute to sort the results. + SortBy *string + // The order to sort the results. + SortOrder AccountListSort_Order + // Specifies the index of the first result. First item is number 1. + StartIndex *int64 + // account ID + AccountId *string +} + +type ListAccountServicePrincipalsResponse struct { + // Total results returned in the response. + ItemsPerPage *int + // User objects returned in the response. + Resources []AccountServicePrincipal + // Starting index of all the results that matched the request filters. First + // item is number 1. + StartIndex *int64 + // Total results that match the request filters. + TotalResults *int +} + +// List users. +type ListAccountUsersRequest struct { + // Comma-separated list of attributes to return in response. + Attributes *string + // Desired number of results per page. Default is 10000. + Count *int64 + // Comma-separated list of attributes to exclude in response. + ExcludedAttributes *string + // Query by which the results have to be filtered. Supported operators are + // equals(`eq`), contains(`co`), starts with(`sw`) and not equals(`ne`). + // Additionally, simple expressions can be formed using logical operators - + // `and` and `or`. The [SCIM RFC] has more details but we currently only support + // simple expressions. + // + // [SCIM RFC]: https://tools.ietf.org/html/rfc7644#section-3.4.2.2 + Filter *string + // Attribute to sort the results. Multi-part paths are supported. For example, + // `userName`, `name.givenName`, and `emails`. + SortBy *string + // The order to sort the results. + SortOrder AccountListSort_Order + // Specifies the index of the first result. First item is number 1. + StartIndex *int64 + // account ID + AccountId *string +} + +type ListAccountUsersResponse struct { + // Total results returned in the response. + ItemsPerPage *int + // User objects returned in the response. + Resources []AccountUser + // Starting index of all the results that matched the request filters. First + // item is number 1. + StartIndex *int64 + // Total results that match the request filters. + TotalResults *int +} + +// List group details. +type ListGroupsRequest struct { + // Query by which the results have to be filtered. Supported operators are + // equals(`eq`), contains(`co`), starts with(`sw`) and not equals(`ne`). + // Additionally, simple expressions can be formed using logical operators - + // `and` and `or`. The [SCIM RFC] has more details but we currently only support + // simple expressions. + // + // [SCIM RFC]: https://tools.ietf.org/html/rfc7644#section-3.4.2.2 + Filter *string + // Comma-separated list of attributes to return in response. + Attributes *string + // Comma-separated list of attributes to exclude in response. + ExcludedAttributes *string + // Specifies the index of the first result. First item is number 1. + StartIndex *int64 + // Desired number of results per page. + Count *int64 + // Attribute to sort the results. + SortBy *string + // The order to sort the results. + SortOrder ListSort_Order +} + +type ListGroupsResponse struct { + // Total results returned in the response. + ItemsPerPage *int + // User objects returned in the response. + Resources []Group + // The schema of the service principal. + Schemas []ListResponseSchema + // Starting index of all the results that matched the request filters. First + // item is number 1. + StartIndex *int64 + // Total results that match the request filters. + TotalResults *int +} + +type ListServicePrincipalResponse struct { + // Total results returned in the response. + ItemsPerPage *int + // User objects returned in the response. + Resources []ServicePrincipal + // The schema of the List response. + Schemas []ListResponseSchema + // Starting index of all the results that matched the request filters. First + // item is number 1. + StartIndex *int64 + // Total results that match the request filters. + TotalResults *int +} + +// List service principals. +type ListServicePrincipalsRequest struct { + // Comma-separated list of attributes to return in response. + Attributes *string + // Desired number of results per page. + Count *int64 + // Comma-separated list of attributes to exclude in response. + ExcludedAttributes *string + // Query by which the results have to be filtered. Supported operators are + // equals(`eq`), contains(`co`), starts with(`sw`) and not equals(`ne`). + // Additionally, simple expressions can be formed using logical operators - + // `and` and `or`. The [SCIM RFC] has more details but we currently only support + // simple expressions. + // + // [SCIM RFC]: https://tools.ietf.org/html/rfc7644#section-3.4.2.2 + Filter *string + // Attribute to sort the results. + SortBy *string + // The order to sort the results. + SortOrder ListSort_Order + // Specifies the index of the first result. First item is number 1. + StartIndex *int64 +} + +// ListSortOrder and GetSortOrder share enum values, which is not supported. We +// use nesting as a workaround.. +type ListSort struct { +} + +// List users. +type ListUsersRequest struct { + // Comma-separated list of attributes to return in response. + Attributes *string + // Desired number of results per page. + Count *int64 + // Comma-separated list of attributes to exclude in response. + ExcludedAttributes *string + // Query by which the results have to be filtered. Supported operators are + // equals(`eq`), contains(`co`), starts with(`sw`) and not equals(`ne`). + // Additionally, simple expressions can be formed using logical operators - + // `and` and `or`. The [SCIM RFC] has more details but we currently only support + // simple expressions. + // + // [SCIM RFC]: https://tools.ietf.org/html/rfc7644#section-3.4.2.2 + Filter *string + // Attribute to sort the results. Multi-part paths are supported. For example, + // `userName`, `name.givenName`, and `emails`. + SortBy *string + // The order to sort the results. + SortOrder ListSort_Order + // Specifies the index of the first result. First item is number 1. + StartIndex *int64 +} + +type ListUsersResponse struct { + // Total results returned in the response. + ItemsPerPage *int + // User objects returned in the response. + Resources []User + // The schema of the List response. + Schemas []ListResponseSchema + // Starting index of all the results that matched the request filters. First + // item is number 1. + StartIndex *int64 + // Total results that match the request filters. + TotalResults *int +} + +type MeRequest struct { + // Comma-separated list of attributes to return in response. + Attributes *string + // Comma-separated list of attributes to exclude in response. + ExcludedAttributes *string +} + +type Name struct { + // Family name of the user. + FamilyName *string + // Given name of the user. + GivenName *string +} + +type PasswordAccessControlRequest struct { + // name of the group + GroupName *string + // Permission level + PermissionLevel PasswordPermission_Level + // application ID of a service principal + ServicePrincipalName *string + // name of the user + UserName *string +} + +type PasswordAccessControlResponse struct { + // All permissions. + AllPermissions []PasswordPermission + // Display name of the user or service principal. + DisplayName *string + // name of the group + GroupName *string + // Name of the service principal. + ServicePrincipalName *string + // name of the user + UserName *string +} + +type PasswordPermission struct { + Inherited *bool + InheritedFromObject []string + // Permission level + PermissionLevel PasswordPermission_Level +} + +type PasswordPermissions struct { + AccessControlList []PasswordAccessControlResponse + ObjectId *string + ObjectType *string +} + +type PasswordPermissionsDescription struct { + Description *string + // Permission level + PermissionLevel PasswordPermission_Level +} + +type PasswordPermissionsRequest struct { + AccessControlList []PasswordAccessControlRequest +} + +type Patch struct { + // Type of patch operation. + Op PatchOp + // Selection of patch operation + Path *string + // Value to modify + Value json.RawMessage +} + +type PatchAccountGroupRequest struct { + // Unique ID in the workspace. + Id *string + Operations []AccountPatch + // The schema of the patch request. Must be + // ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]. + Schemas []AccountPatchSchema_PatchSchema + // account ID + AccountId *string +} + +type PatchAccountServicePrincipalRequest struct { + // Unique ID in the workspace. + Id *string + Operations []AccountPatch + // The schema of the patch request. Must be + // ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]. + Schemas []AccountPatchSchema_PatchSchema + // account ID + AccountId *string +} + +type PatchAccountUserRequest struct { + // Unique ID in the workspace. + Id *string + Operations []AccountPatch + // The schema of the patch request. Must be + // ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]. + Schemas []AccountPatchSchema_PatchSchema + // account ID + AccountId *string +} + +type PatchGroupRequest struct { + // Unique ID in the workspace. + Id *string + Operations []Patch + // The schema of the patch request. Must be + // ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]. + Schemas []PatchSchema +} + +type PatchServicePrincipalRequest struct { + // Unique ID in the workspace. + Id *string + Operations []Patch + // The schema of the patch request. Must be + // ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]. + Schemas []PatchSchema +} + +type PatchUserRequest struct { + // Unique ID in the workspace. + Id *string + Operations []Patch + // The schema of the patch request. Must be + // ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]. + Schemas []PatchSchema +} + +type ResourceMeta struct { + // Identifier for group type. Can be local workspace group (`WorkspaceGroup`) or + // account group (`Group`). + ResourceType *string +} + +type ServicePrincipal struct { + // If this user is active + Active *bool + // UUID relating to the service principal + ApplicationId *string + // String that represents a concatenation of given and family names. + DisplayName *string + // Entitlements assigned to the service principal. See [assigning entitlements] + // for a full list of supported values. + // + // [assigning entitlements]: https://docs.databricks.com/administration-guide/users-groups/index.html#assigning-entitlements + Entitlements []ComplexValue + ExternalId *string + Groups []ComplexValue + // service principal ID. + Id *string + // Corresponds to AWS instance profile/arn role. + Roles []ComplexValue + // The schema of the List response. + Schemas []ServicePrincipalSchema +} + +type UpdateAccountGroupRequest struct { + // String that represents a human-readable group name + DisplayName *string + ExternalId *string + // group ID + Id *string + Members []AccountComplexValue + // Container for the group identifier. Workspace local versus account. + Meta *AccountResourceMeta + // Indicates if the group has the admin role. + Roles []AccountComplexValue + // account ID + AccountId *string +} + +type UpdateAccountServicePrincipalRequest struct { + // If this user is active + Active *bool + // UUID relating to the service principal + ApplicationId *string + // String that represents a concatenation of given and family names. + DisplayName *string + ExternalId *string + // service principal ID. + Id *string + // Indicates if the group has the admin role. + Roles []AccountComplexValue + // account ID + AccountId *string +} + +type UpdateAccountUserRequest struct { + // If this user is active + Active *bool + // String that represents a concatenation of given and family names. For example + // `John Smith`. + DisplayName *string + // All the emails associated with the user. This attribute cannot + // be updated through the SCIM PATCH or PUT APIs; any supplied change is + // ignored. + Emails []AccountComplexValue + // External ID is not currently supported. It is reserved for future use. + ExternalId *string + // user ID. + Id *string + Name *AccountName + // Indicates if the group has the admin role. + Roles []AccountComplexValue + // Email address of the user. This attribute cannot be updated + // through the SCIM PATCH or PUT APIs; any supplied change is ignored. + UserName *string + // account ID + AccountId *string +} + +type UpdateGroupRequest struct { + // String that represents a human-readable group name + DisplayName *string + // Entitlements assigned to the group. See [assigning entitlements] for a full + // list of supported values. + // + // [assigning entitlements]: https://docs.databricks.com/administration-guide/users-groups/index.html#assigning-entitlements + Entitlements []ComplexValue + ExternalId *string + Groups []ComplexValue + // group ID + Id *string + Members []ComplexValue + // Container for the group identifier. Workspace local versus account. + Meta *ResourceMeta + // Corresponds to AWS instance profile/arn role. + Roles []ComplexValue + // The schema of the group. + Schemas []GroupSchema +} + +type UpdateServicePrincipalRequest struct { + // If this user is active + Active *bool + // UUID relating to the service principal + ApplicationId *string + // String that represents a concatenation of given and family names. + DisplayName *string + // Entitlements assigned to the service principal. See [assigning entitlements] + // for a full list of supported values. + // + // [assigning entitlements]: https://docs.databricks.com/administration-guide/users-groups/index.html#assigning-entitlements + Entitlements []ComplexValue + ExternalId *string + Groups []ComplexValue + // service principal ID. + Id *string + // Corresponds to AWS instance profile/arn role. + Roles []ComplexValue + // The schema of the List response. + Schemas []ServicePrincipalSchema +} + +type UpdateUserRequest struct { + // If this user is active + Active *bool + // String that represents a concatenation of given and family names. For example + // `John Smith`. This field cannot be updated through the Workspace SCIM APIs + // when [identity federation is enabled]. Use Account SCIM APIs to update + // `displayName`. + // + // [identity federation is enabled]: https://docs.databricks.com/administration-guide/users-groups/best-practices.html#enable-identity-federation + DisplayName *string + // All the emails associated with the user. This attribute cannot + // be updated through the SCIM PATCH or PUT APIs; any supplied change is + // ignored. + Emails []ComplexValue + // Entitlements assigned to the user. See [assigning entitlements] for a full + // list of supported values. + // + // [assigning entitlements]: https://docs.databricks.com/administration-guide/users-groups/index.html#assigning-entitlements + Entitlements []ComplexValue + // External ID is not currently supported. It is reserved for future use. + ExternalId *string + Groups []ComplexValue + // user ID. + Id *string + Name *Name + // Corresponds to AWS instance profile/arn role. + Roles []ComplexValue + // The schema of the user. + Schemas []UserSchema + // Email address of the user. This attribute cannot be updated + // through the SCIM PATCH or PUT APIs; any supplied change is ignored. + UserName *string +} + +type User struct { + // If this user is active + Active *bool + // String that represents a concatenation of given and family names. For example + // `John Smith`. This field cannot be updated through the Workspace SCIM APIs + // when [identity federation is enabled]. Use Account SCIM APIs to update + // `displayName`. + // + // [identity federation is enabled]: https://docs.databricks.com/administration-guide/users-groups/best-practices.html#enable-identity-federation + DisplayName *string + // All the emails associated with the user. This attribute cannot + // be updated through the SCIM PATCH or PUT APIs; any supplied change is + // ignored. + Emails []ComplexValue + // Entitlements assigned to the user. See [assigning entitlements] for a full + // list of supported values. + // + // [assigning entitlements]: https://docs.databricks.com/administration-guide/users-groups/index.html#assigning-entitlements + Entitlements []ComplexValue + // External ID is not currently supported. It is reserved for future use. + ExternalId *string + Groups []ComplexValue + // user ID. + Id *string + Name *Name + // Corresponds to AWS instance profile/arn role. + Roles []ComplexValue + // The schema of the user. + Schemas []UserSchema + // Email address of the user. This attribute cannot be updated + // through the SCIM PATCH or PUT APIs; any supplied change is ignored. + UserName *string +} diff --git a/scim/v1/wire.go b/scim/v1/wire.go new file mode 100755 index 0000000..e9fc474 --- /dev/null +++ b/scim/v1/wire.go @@ -0,0 +1,1603 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package scim + +import ( + "encoding/json" + "fmt" +) + +type accountComplexValueWire struct { + Display *string `json:"display,omitempty"` + Primary *bool `json:"primary,omitempty"` + Ref *string `json:"$ref,omitempty"` + Type *string `json:"type,omitempty"` + Value *string `json:"value,omitempty"` +} + +func accountComplexValueToWire(v *AccountComplexValue) (*accountComplexValueWire, error) { + if v == nil { + return nil, nil + } + return &accountComplexValueWire{ + Display: v.Display, + Primary: v.Primary, + Ref: v.Ref, + Type: v.Type, + Value: v.Value, + }, nil +} + +func accountComplexValueFromWire(w *accountComplexValueWire) (*AccountComplexValue, error) { + if w == nil { + return nil, nil + } + return &AccountComplexValue{ + Display: w.Display, + Primary: w.Primary, + Ref: w.Ref, + Type: w.Type, + Value: w.Value, + }, nil +} + +type accountGroupWire struct { + DisplayName *string `json:"displayName,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Id *string `json:"id,omitempty"` + Members []accountComplexValueWire `json:"members,omitempty"` + Meta *accountResourceMetaWire `json:"meta,omitempty"` + Roles []accountComplexValueWire `json:"roles,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func accountGroupFromWire(w *accountGroupWire) (*AccountGroup, error) { + if w == nil { + return nil, nil + } + membersPublicValue, err := convertSlice(w.Members, accountComplexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountGroup.Members", err) + } + metaPublicValue, err := accountResourceMetaFromWire(w.Meta) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountGroup.Meta", err) + } + rolesPublicValue, err := convertSlice(w.Roles, accountComplexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountGroup.Roles", err) + } + return &AccountGroup{ + DisplayName: w.DisplayName, + ExternalId: w.ExternalId, + Id: w.Id, + Members: membersPublicValue, + Meta: metaPublicValue, + Roles: rolesPublicValue, + AccountId: w.AccountId, + }, nil +} + +type accountNameWire struct { + FamilyName *string `json:"familyName,omitempty"` + GivenName *string `json:"givenName,omitempty"` +} + +func accountNameToWire(v *AccountName) (*accountNameWire, error) { + if v == nil { + return nil, nil + } + return &accountNameWire{ + FamilyName: v.FamilyName, + GivenName: v.GivenName, + }, nil +} + +func accountNameFromWire(w *accountNameWire) (*AccountName, error) { + if w == nil { + return nil, nil + } + return &AccountName{ + FamilyName: w.FamilyName, + GivenName: w.GivenName, + }, nil +} + +type accountPatchWire struct { + Op AccountPatchOp_PatchOp `json:"op,omitempty"` + Path *string `json:"path,omitempty"` + Value json.RawMessage `json:"value,omitempty"` +} + +func accountPatchToWire(v *AccountPatch) (*accountPatchWire, error) { + if v == nil { + return nil, nil + } + return &accountPatchWire{ + Op: v.Op, + Path: v.Path, + Value: v.Value, + }, nil +} + +type accountResourceMetaWire struct { + ResourceType *string `json:"resourceType,omitempty"` +} + +func accountResourceMetaToWire(v *AccountResourceMeta) (*accountResourceMetaWire, error) { + if v == nil { + return nil, nil + } + return &accountResourceMetaWire{ + ResourceType: v.ResourceType, + }, nil +} + +func accountResourceMetaFromWire(w *accountResourceMetaWire) (*AccountResourceMeta, error) { + if w == nil { + return nil, nil + } + return &AccountResourceMeta{ + ResourceType: w.ResourceType, + }, nil +} + +type accountServicePrincipalWire struct { + Active *bool `json:"active,omitempty"` + ApplicationId *string `json:"applicationId,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Id *string `json:"id,omitempty"` + Roles []accountComplexValueWire `json:"roles,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func accountServicePrincipalFromWire(w *accountServicePrincipalWire) (*AccountServicePrincipal, error) { + if w == nil { + return nil, nil + } + rolesPublicValue, err := convertSlice(w.Roles, accountComplexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountServicePrincipal.Roles", err) + } + return &AccountServicePrincipal{ + Active: w.Active, + ApplicationId: w.ApplicationId, + DisplayName: w.DisplayName, + ExternalId: w.ExternalId, + Id: w.Id, + Roles: rolesPublicValue, + AccountId: w.AccountId, + }, nil +} + +type accountUserWire struct { + Active *bool `json:"active,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Emails []accountComplexValueWire `json:"emails,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Id *string `json:"id,omitempty"` + Name *accountNameWire `json:"name,omitempty"` + Roles []accountComplexValueWire `json:"roles,omitempty"` + UserName *string `json:"userName,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func accountUserFromWire(w *accountUserWire) (*AccountUser, error) { + if w == nil { + return nil, nil + } + emailsPublicValue, err := convertSlice(w.Emails, accountComplexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountUser.Emails", err) + } + namePublicValue, err := accountNameFromWire(w.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountUser.Name", err) + } + rolesPublicValue, err := convertSlice(w.Roles, accountComplexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountUser.Roles", err) + } + return &AccountUser{ + Active: w.Active, + DisplayName: w.DisplayName, + Emails: emailsPublicValue, + ExternalId: w.ExternalId, + Id: w.Id, + Name: namePublicValue, + Roles: rolesPublicValue, + UserName: w.UserName, + AccountId: w.AccountId, + }, nil +} + +type complexValueWire struct { + Display *string `json:"display,omitempty"` + Primary *bool `json:"primary,omitempty"` + Ref *string `json:"$ref,omitempty"` + Type *string `json:"type,omitempty"` + Value *string `json:"value,omitempty"` +} + +func complexValueToWire(v *ComplexValue) (*complexValueWire, error) { + if v == nil { + return nil, nil + } + return &complexValueWire{ + Display: v.Display, + Primary: v.Primary, + Ref: v.Ref, + Type: v.Type, + Value: v.Value, + }, nil +} + +func complexValueFromWire(w *complexValueWire) (*ComplexValue, error) { + if w == nil { + return nil, nil + } + return &ComplexValue{ + Display: w.Display, + Primary: w.Primary, + Ref: w.Ref, + Type: w.Type, + Value: w.Value, + }, nil +} + +type createAccountGroupRequestWire struct { + DisplayName *string `json:"displayName,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Id *string `json:"id,omitempty"` + Members []accountComplexValueWire `json:"members,omitempty"` + Meta *accountResourceMetaWire `json:"meta,omitempty"` + Roles []accountComplexValueWire `json:"roles,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func createAccountGroupRequestToWire(v *CreateAccountGroupRequest) (*createAccountGroupRequestWire, error) { + if v == nil { + return nil, nil + } + membersWireValue, err := convertSlice(v.Members, accountComplexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountGroupRequest.Members", err) + } + metaWireValue, err := accountResourceMetaToWire(v.Meta) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountGroupRequest.Meta", err) + } + rolesWireValue, err := convertSlice(v.Roles, accountComplexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountGroupRequest.Roles", err) + } + return &createAccountGroupRequestWire{ + DisplayName: v.DisplayName, + ExternalId: v.ExternalId, + Id: v.Id, + Members: membersWireValue, + Meta: metaWireValue, + Roles: rolesWireValue, + AccountId: v.AccountId, + }, nil +} + +type createAccountServicePrincipalRequestWire struct { + Active *bool `json:"active,omitempty"` + ApplicationId *string `json:"applicationId,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Id *string `json:"id,omitempty"` + Roles []accountComplexValueWire `json:"roles,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func createAccountServicePrincipalRequestToWire(v *CreateAccountServicePrincipalRequest) (*createAccountServicePrincipalRequestWire, error) { + if v == nil { + return nil, nil + } + rolesWireValue, err := convertSlice(v.Roles, accountComplexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountServicePrincipalRequest.Roles", err) + } + return &createAccountServicePrincipalRequestWire{ + Active: v.Active, + ApplicationId: v.ApplicationId, + DisplayName: v.DisplayName, + ExternalId: v.ExternalId, + Id: v.Id, + Roles: rolesWireValue, + AccountId: v.AccountId, + }, nil +} + +type createAccountUserRequestWire struct { + Active *bool `json:"active,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Emails []accountComplexValueWire `json:"emails,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Id *string `json:"id,omitempty"` + Name *accountNameWire `json:"name,omitempty"` + Roles []accountComplexValueWire `json:"roles,omitempty"` + UserName *string `json:"userName,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func createAccountUserRequestToWire(v *CreateAccountUserRequest) (*createAccountUserRequestWire, error) { + if v == nil { + return nil, nil + } + emailsWireValue, err := convertSlice(v.Emails, accountComplexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountUserRequest.Emails", err) + } + nameWireValue, err := accountNameToWire(v.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountUserRequest.Name", err) + } + rolesWireValue, err := convertSlice(v.Roles, accountComplexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountUserRequest.Roles", err) + } + return &createAccountUserRequestWire{ + Active: v.Active, + DisplayName: v.DisplayName, + Emails: emailsWireValue, + ExternalId: v.ExternalId, + Id: v.Id, + Name: nameWireValue, + Roles: rolesWireValue, + UserName: v.UserName, + AccountId: v.AccountId, + }, nil +} + +type createGroupRequestWire struct { + DisplayName *string `json:"displayName,omitempty"` + Entitlements []complexValueWire `json:"entitlements,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Groups []complexValueWire `json:"groups,omitempty"` + Id *string `json:"id,omitempty"` + Members []complexValueWire `json:"members,omitempty"` + Meta *resourceMetaWire `json:"meta,omitempty"` + Roles []complexValueWire `json:"roles,omitempty"` + Schemas []GroupSchema `json:"schemas,omitempty"` +} + +func createGroupRequestToWire(v *CreateGroupRequest) (*createGroupRequestWire, error) { + if v == nil { + return nil, nil + } + entitlementsWireValue, err := convertSlice(v.Entitlements, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateGroupRequest.Entitlements", err) + } + groupsWireValue, err := convertSlice(v.Groups, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateGroupRequest.Groups", err) + } + membersWireValue, err := convertSlice(v.Members, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateGroupRequest.Members", err) + } + metaWireValue, err := resourceMetaToWire(v.Meta) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateGroupRequest.Meta", err) + } + rolesWireValue, err := convertSlice(v.Roles, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateGroupRequest.Roles", err) + } + return &createGroupRequestWire{ + DisplayName: v.DisplayName, + Entitlements: entitlementsWireValue, + ExternalId: v.ExternalId, + Groups: groupsWireValue, + Id: v.Id, + Members: membersWireValue, + Meta: metaWireValue, + Roles: rolesWireValue, + Schemas: v.Schemas, + }, nil +} + +type createServicePrincipalRequestWire struct { + Active *bool `json:"active,omitempty"` + ApplicationId *string `json:"applicationId,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Entitlements []complexValueWire `json:"entitlements,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Groups []complexValueWire `json:"groups,omitempty"` + Id *string `json:"id,omitempty"` + Roles []complexValueWire `json:"roles,omitempty"` + Schemas []ServicePrincipalSchema `json:"schemas,omitempty"` +} + +func createServicePrincipalRequestToWire(v *CreateServicePrincipalRequest) (*createServicePrincipalRequestWire, error) { + if v == nil { + return nil, nil + } + entitlementsWireValue, err := convertSlice(v.Entitlements, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateServicePrincipalRequest.Entitlements", err) + } + groupsWireValue, err := convertSlice(v.Groups, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateServicePrincipalRequest.Groups", err) + } + rolesWireValue, err := convertSlice(v.Roles, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateServicePrincipalRequest.Roles", err) + } + return &createServicePrincipalRequestWire{ + Active: v.Active, + ApplicationId: v.ApplicationId, + DisplayName: v.DisplayName, + Entitlements: entitlementsWireValue, + ExternalId: v.ExternalId, + Groups: groupsWireValue, + Id: v.Id, + Roles: rolesWireValue, + Schemas: v.Schemas, + }, nil +} + +type createUserRequestWire struct { + Active *bool `json:"active,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Emails []complexValueWire `json:"emails,omitempty"` + Entitlements []complexValueWire `json:"entitlements,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Groups []complexValueWire `json:"groups,omitempty"` + Id *string `json:"id,omitempty"` + Name *nameWire `json:"name,omitempty"` + Roles []complexValueWire `json:"roles,omitempty"` + Schemas []UserSchema `json:"schemas,omitempty"` + UserName *string `json:"userName,omitempty"` +} + +func createUserRequestToWire(v *CreateUserRequest) (*createUserRequestWire, error) { + if v == nil { + return nil, nil + } + emailsWireValue, err := convertSlice(v.Emails, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateUserRequest.Emails", err) + } + entitlementsWireValue, err := convertSlice(v.Entitlements, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateUserRequest.Entitlements", err) + } + groupsWireValue, err := convertSlice(v.Groups, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateUserRequest.Groups", err) + } + nameWireValue, err := nameToWire(v.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateUserRequest.Name", err) + } + rolesWireValue, err := convertSlice(v.Roles, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateUserRequest.Roles", err) + } + return &createUserRequestWire{ + Active: v.Active, + DisplayName: v.DisplayName, + Emails: emailsWireValue, + Entitlements: entitlementsWireValue, + ExternalId: v.ExternalId, + Groups: groupsWireValue, + Id: v.Id, + Name: nameWireValue, + Roles: rolesWireValue, + Schemas: v.Schemas, + UserName: v.UserName, + }, nil +} + +type getAccountUserRequestWire struct { + Attributes *string `json:"attributes,omitempty"` + Count *int `json:"count,omitempty"` + ExcludedAttributes *string `json:"excludedAttributes,omitempty"` + Filter *string `json:"filter,omitempty"` + Id *string `json:"id,omitempty"` + SortBy *string `json:"sortBy,omitempty"` + SortOrder AccountGetSortOrder_GetSortOrder `json:"sortOrder,omitempty"` + StartIndex *int `json:"startIndex,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func getAccountUserRequestToWire(v *GetAccountUserRequest) (*getAccountUserRequestWire, error) { + if v == nil { + return nil, nil + } + return &getAccountUserRequestWire{ + Attributes: v.Attributes, + Count: v.Count, + ExcludedAttributes: v.ExcludedAttributes, + Filter: v.Filter, + Id: v.Id, + SortBy: v.SortBy, + SortOrder: v.SortOrder, + StartIndex: v.StartIndex, + AccountId: v.AccountId, + }, nil +} + +type getPasswordPermissionLevelsResponseWire struct { + PermissionLevels []passwordPermissionsDescriptionWire `json:"permission_levels,omitempty"` +} + +func getPasswordPermissionLevelsResponseFromWire(w *getPasswordPermissionLevelsResponseWire) (*GetPasswordPermissionLevelsResponse, error) { + if w == nil { + return nil, nil + } + permissionLevelsPublicValue, err := convertSlice(w.PermissionLevels, passwordPermissionsDescriptionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPasswordPermissionLevelsResponse.PermissionLevels", err) + } + return &GetPasswordPermissionLevelsResponse{ + PermissionLevels: permissionLevelsPublicValue, + }, nil +} + +type getUserRequestWire struct { + Attributes *string `json:"attributes,omitempty"` + Count *int `json:"count,omitempty"` + ExcludedAttributes *string `json:"excludedAttributes,omitempty"` + Filter *string `json:"filter,omitempty"` + Id *string `json:"id,omitempty"` + SortBy *string `json:"sortBy,omitempty"` + SortOrder GetSortOrder `json:"sortOrder,omitempty"` + StartIndex *int `json:"startIndex,omitempty"` +} + +func getUserRequestToWire(v *GetUserRequest) (*getUserRequestWire, error) { + if v == nil { + return nil, nil + } + return &getUserRequestWire{ + Attributes: v.Attributes, + Count: v.Count, + ExcludedAttributes: v.ExcludedAttributes, + Filter: v.Filter, + Id: v.Id, + SortBy: v.SortBy, + SortOrder: v.SortOrder, + StartIndex: v.StartIndex, + }, nil +} + +type groupWire struct { + DisplayName *string `json:"displayName,omitempty"` + Entitlements []complexValueWire `json:"entitlements,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Groups []complexValueWire `json:"groups,omitempty"` + Id *string `json:"id,omitempty"` + Members []complexValueWire `json:"members,omitempty"` + Meta *resourceMetaWire `json:"meta,omitempty"` + Roles []complexValueWire `json:"roles,omitempty"` + Schemas []GroupSchema `json:"schemas,omitempty"` +} + +func groupFromWire(w *groupWire) (*Group, error) { + if w == nil { + return nil, nil + } + entitlementsPublicValue, err := convertSlice(w.Entitlements, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Group.Entitlements", err) + } + groupsPublicValue, err := convertSlice(w.Groups, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Group.Groups", err) + } + membersPublicValue, err := convertSlice(w.Members, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Group.Members", err) + } + metaPublicValue, err := resourceMetaFromWire(w.Meta) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Group.Meta", err) + } + rolesPublicValue, err := convertSlice(w.Roles, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Group.Roles", err) + } + return &Group{ + DisplayName: w.DisplayName, + Entitlements: entitlementsPublicValue, + ExternalId: w.ExternalId, + Groups: groupsPublicValue, + Id: w.Id, + Members: membersPublicValue, + Meta: metaPublicValue, + Roles: rolesPublicValue, + Schemas: w.Schemas, + }, nil +} + +type listAccountGroupsRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + Filter *string `json:"filter,omitempty"` + Attributes *string `json:"attributes,omitempty"` + ExcludedAttributes *string `json:"excludedAttributes,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` + Count *int64 `json:"count,omitempty"` + SortBy *string `json:"sortBy,omitempty"` + SortOrder AccountListSort_Order `json:"sortOrder,omitempty"` +} + +func listAccountGroupsRequestToWire(v *ListAccountGroupsRequest) (*listAccountGroupsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAccountGroupsRequestWire{ + AccountId: v.AccountId, + Filter: v.Filter, + Attributes: v.Attributes, + ExcludedAttributes: v.ExcludedAttributes, + StartIndex: v.StartIndex, + Count: v.Count, + SortBy: v.SortBy, + SortOrder: v.SortOrder, + }, nil +} + +type listAccountGroupsResponseWire struct { + ItemsPerPage *int `json:"itemsPerPage,omitempty"` + Resources []accountGroupWire `json:"Resources,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` + TotalResults *int `json:"totalResults,omitempty"` +} + +func listAccountGroupsResponseFromWire(w *listAccountGroupsResponseWire) (*ListAccountGroupsResponse, error) { + if w == nil { + return nil, nil + } + resourcesPublicValue, err := convertSlice(w.Resources, accountGroupFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAccountGroupsResponse.Resources", err) + } + return &ListAccountGroupsResponse{ + ItemsPerPage: w.ItemsPerPage, + Resources: resourcesPublicValue, + StartIndex: w.StartIndex, + TotalResults: w.TotalResults, + }, nil +} + +type listAccountServicePrincipalsRequestWire struct { + Attributes *string `json:"attributes,omitempty"` + Count *int64 `json:"count,omitempty"` + ExcludedAttributes *string `json:"excludedAttributes,omitempty"` + Filter *string `json:"filter,omitempty"` + SortBy *string `json:"sortBy,omitempty"` + SortOrder AccountListSort_Order `json:"sortOrder,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func listAccountServicePrincipalsRequestToWire(v *ListAccountServicePrincipalsRequest) (*listAccountServicePrincipalsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAccountServicePrincipalsRequestWire{ + Attributes: v.Attributes, + Count: v.Count, + ExcludedAttributes: v.ExcludedAttributes, + Filter: v.Filter, + SortBy: v.SortBy, + SortOrder: v.SortOrder, + StartIndex: v.StartIndex, + AccountId: v.AccountId, + }, nil +} + +type listAccountServicePrincipalsResponseWire struct { + ItemsPerPage *int `json:"itemsPerPage,omitempty"` + Resources []accountServicePrincipalWire `json:"Resources,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` + TotalResults *int `json:"totalResults,omitempty"` +} + +func listAccountServicePrincipalsResponseFromWire(w *listAccountServicePrincipalsResponseWire) (*ListAccountServicePrincipalsResponse, error) { + if w == nil { + return nil, nil + } + resourcesPublicValue, err := convertSlice(w.Resources, accountServicePrincipalFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAccountServicePrincipalsResponse.Resources", err) + } + return &ListAccountServicePrincipalsResponse{ + ItemsPerPage: w.ItemsPerPage, + Resources: resourcesPublicValue, + StartIndex: w.StartIndex, + TotalResults: w.TotalResults, + }, nil +} + +type listAccountUsersRequestWire struct { + Attributes *string `json:"attributes,omitempty"` + Count *int64 `json:"count,omitempty"` + ExcludedAttributes *string `json:"excludedAttributes,omitempty"` + Filter *string `json:"filter,omitempty"` + SortBy *string `json:"sortBy,omitempty"` + SortOrder AccountListSort_Order `json:"sortOrder,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func listAccountUsersRequestToWire(v *ListAccountUsersRequest) (*listAccountUsersRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAccountUsersRequestWire{ + Attributes: v.Attributes, + Count: v.Count, + ExcludedAttributes: v.ExcludedAttributes, + Filter: v.Filter, + SortBy: v.SortBy, + SortOrder: v.SortOrder, + StartIndex: v.StartIndex, + AccountId: v.AccountId, + }, nil +} + +type listAccountUsersResponseWire struct { + ItemsPerPage *int `json:"itemsPerPage,omitempty"` + Resources []accountUserWire `json:"Resources,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` + TotalResults *int `json:"totalResults,omitempty"` +} + +func listAccountUsersResponseFromWire(w *listAccountUsersResponseWire) (*ListAccountUsersResponse, error) { + if w == nil { + return nil, nil + } + resourcesPublicValue, err := convertSlice(w.Resources, accountUserFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAccountUsersResponse.Resources", err) + } + return &ListAccountUsersResponse{ + ItemsPerPage: w.ItemsPerPage, + Resources: resourcesPublicValue, + StartIndex: w.StartIndex, + TotalResults: w.TotalResults, + }, nil +} + +type listGroupsRequestWire struct { + Filter *string `json:"filter,omitempty"` + Attributes *string `json:"attributes,omitempty"` + ExcludedAttributes *string `json:"excludedAttributes,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` + Count *int64 `json:"count,omitempty"` + SortBy *string `json:"sortBy,omitempty"` + SortOrder ListSort_Order `json:"sortOrder,omitempty"` +} + +func listGroupsRequestToWire(v *ListGroupsRequest) (*listGroupsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listGroupsRequestWire{ + Filter: v.Filter, + Attributes: v.Attributes, + ExcludedAttributes: v.ExcludedAttributes, + StartIndex: v.StartIndex, + Count: v.Count, + SortBy: v.SortBy, + SortOrder: v.SortOrder, + }, nil +} + +type listGroupsResponseWire struct { + ItemsPerPage *int `json:"itemsPerPage,omitempty"` + Resources []groupWire `json:"Resources,omitempty"` + Schemas []ListResponseSchema `json:"schemas,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` + TotalResults *int `json:"totalResults,omitempty"` +} + +func listGroupsResponseFromWire(w *listGroupsResponseWire) (*ListGroupsResponse, error) { + if w == nil { + return nil, nil + } + resourcesPublicValue, err := convertSlice(w.Resources, groupFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListGroupsResponse.Resources", err) + } + return &ListGroupsResponse{ + ItemsPerPage: w.ItemsPerPage, + Resources: resourcesPublicValue, + Schemas: w.Schemas, + StartIndex: w.StartIndex, + TotalResults: w.TotalResults, + }, nil +} + +type listServicePrincipalResponseWire struct { + ItemsPerPage *int `json:"itemsPerPage,omitempty"` + Resources []servicePrincipalWire `json:"Resources,omitempty"` + Schemas []ListResponseSchema `json:"schemas,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` + TotalResults *int `json:"totalResults,omitempty"` +} + +func listServicePrincipalResponseFromWire(w *listServicePrincipalResponseWire) (*ListServicePrincipalResponse, error) { + if w == nil { + return nil, nil + } + resourcesPublicValue, err := convertSlice(w.Resources, servicePrincipalFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListServicePrincipalResponse.Resources", err) + } + return &ListServicePrincipalResponse{ + ItemsPerPage: w.ItemsPerPage, + Resources: resourcesPublicValue, + Schemas: w.Schemas, + StartIndex: w.StartIndex, + TotalResults: w.TotalResults, + }, nil +} + +type listServicePrincipalsRequestWire struct { + Attributes *string `json:"attributes,omitempty"` + Count *int64 `json:"count,omitempty"` + ExcludedAttributes *string `json:"excludedAttributes,omitempty"` + Filter *string `json:"filter,omitempty"` + SortBy *string `json:"sortBy,omitempty"` + SortOrder ListSort_Order `json:"sortOrder,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` +} + +func listServicePrincipalsRequestToWire(v *ListServicePrincipalsRequest) (*listServicePrincipalsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listServicePrincipalsRequestWire{ + Attributes: v.Attributes, + Count: v.Count, + ExcludedAttributes: v.ExcludedAttributes, + Filter: v.Filter, + SortBy: v.SortBy, + SortOrder: v.SortOrder, + StartIndex: v.StartIndex, + }, nil +} + +type listUsersRequestWire struct { + Attributes *string `json:"attributes,omitempty"` + Count *int64 `json:"count,omitempty"` + ExcludedAttributes *string `json:"excludedAttributes,omitempty"` + Filter *string `json:"filter,omitempty"` + SortBy *string `json:"sortBy,omitempty"` + SortOrder ListSort_Order `json:"sortOrder,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` +} + +func listUsersRequestToWire(v *ListUsersRequest) (*listUsersRequestWire, error) { + if v == nil { + return nil, nil + } + return &listUsersRequestWire{ + Attributes: v.Attributes, + Count: v.Count, + ExcludedAttributes: v.ExcludedAttributes, + Filter: v.Filter, + SortBy: v.SortBy, + SortOrder: v.SortOrder, + StartIndex: v.StartIndex, + }, nil +} + +type listUsersResponseWire struct { + ItemsPerPage *int `json:"itemsPerPage,omitempty"` + Resources []userWire `json:"Resources,omitempty"` + Schemas []ListResponseSchema `json:"schemas,omitempty"` + StartIndex *int64 `json:"startIndex,omitempty"` + TotalResults *int `json:"totalResults,omitempty"` +} + +func listUsersResponseFromWire(w *listUsersResponseWire) (*ListUsersResponse, error) { + if w == nil { + return nil, nil + } + resourcesPublicValue, err := convertSlice(w.Resources, userFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListUsersResponse.Resources", err) + } + return &ListUsersResponse{ + ItemsPerPage: w.ItemsPerPage, + Resources: resourcesPublicValue, + Schemas: w.Schemas, + StartIndex: w.StartIndex, + TotalResults: w.TotalResults, + }, nil +} + +type meRequestWire struct { + Attributes *string `json:"attributes,omitempty"` + ExcludedAttributes *string `json:"excludedAttributes,omitempty"` +} + +func meRequestToWire(v *MeRequest) (*meRequestWire, error) { + if v == nil { + return nil, nil + } + return &meRequestWire{ + Attributes: v.Attributes, + ExcludedAttributes: v.ExcludedAttributes, + }, nil +} + +type nameWire struct { + FamilyName *string `json:"familyName,omitempty"` + GivenName *string `json:"givenName,omitempty"` +} + +func nameToWire(v *Name) (*nameWire, error) { + if v == nil { + return nil, nil + } + return &nameWire{ + FamilyName: v.FamilyName, + GivenName: v.GivenName, + }, nil +} + +func nameFromWire(w *nameWire) (*Name, error) { + if w == nil { + return nil, nil + } + return &Name{ + FamilyName: w.FamilyName, + GivenName: w.GivenName, + }, nil +} + +type passwordAccessControlRequestWire struct { + GroupName *string `json:"group_name,omitempty"` + PermissionLevel PasswordPermission_Level `json:"permission_level,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` + UserName *string `json:"user_name,omitempty"` +} + +func passwordAccessControlRequestToWire(v *PasswordAccessControlRequest) (*passwordAccessControlRequestWire, error) { + if v == nil { + return nil, nil + } + return &passwordAccessControlRequestWire{ + GroupName: v.GroupName, + PermissionLevel: v.PermissionLevel, + ServicePrincipalName: v.ServicePrincipalName, + UserName: v.UserName, + }, nil +} + +type passwordAccessControlResponseWire struct { + AllPermissions []passwordPermissionWire `json:"all_permissions,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + GroupName *string `json:"group_name,omitempty"` + ServicePrincipalName *string `json:"service_principal_name,omitempty"` + UserName *string `json:"user_name,omitempty"` +} + +func passwordAccessControlResponseFromWire(w *passwordAccessControlResponseWire) (*PasswordAccessControlResponse, error) { + if w == nil { + return nil, nil + } + allPermissionsPublicValue, err := convertSlice(w.AllPermissions, passwordPermissionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PasswordAccessControlResponse.AllPermissions", err) + } + return &PasswordAccessControlResponse{ + AllPermissions: allPermissionsPublicValue, + DisplayName: w.DisplayName, + GroupName: w.GroupName, + ServicePrincipalName: w.ServicePrincipalName, + UserName: w.UserName, + }, nil +} + +type passwordPermissionWire struct { + Inherited *bool `json:"inherited,omitempty"` + InheritedFromObject []string `json:"inherited_from_object,omitempty"` + PermissionLevel PasswordPermission_Level `json:"permission_level,omitempty"` +} + +func passwordPermissionFromWire(w *passwordPermissionWire) (*PasswordPermission, error) { + if w == nil { + return nil, nil + } + return &PasswordPermission{ + Inherited: w.Inherited, + InheritedFromObject: w.InheritedFromObject, + PermissionLevel: w.PermissionLevel, + }, nil +} + +type passwordPermissionsWire struct { + AccessControlList []passwordAccessControlResponseWire `json:"access_control_list,omitempty"` + ObjectId *string `json:"object_id,omitempty"` + ObjectType *string `json:"object_type,omitempty"` +} + +func passwordPermissionsFromWire(w *passwordPermissionsWire) (*PasswordPermissions, error) { + if w == nil { + return nil, nil + } + accessControlListPublicValue, err := convertSlice(w.AccessControlList, passwordAccessControlResponseFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PasswordPermissions.AccessControlList", err) + } + return &PasswordPermissions{ + AccessControlList: accessControlListPublicValue, + ObjectId: w.ObjectId, + ObjectType: w.ObjectType, + }, nil +} + +type passwordPermissionsDescriptionWire struct { + Description *string `json:"description,omitempty"` + PermissionLevel PasswordPermission_Level `json:"permission_level,omitempty"` +} + +func passwordPermissionsDescriptionFromWire(w *passwordPermissionsDescriptionWire) (*PasswordPermissionsDescription, error) { + if w == nil { + return nil, nil + } + return &PasswordPermissionsDescription{ + Description: w.Description, + PermissionLevel: w.PermissionLevel, + }, nil +} + +type passwordPermissionsRequestWire struct { + AccessControlList []passwordAccessControlRequestWire `json:"access_control_list,omitempty"` +} + +func passwordPermissionsRequestToWire(v *PasswordPermissionsRequest) (*passwordPermissionsRequestWire, error) { + if v == nil { + return nil, nil + } + accessControlListWireValue, err := convertSlice(v.AccessControlList, passwordAccessControlRequestToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PasswordPermissionsRequest.AccessControlList", err) + } + return &passwordPermissionsRequestWire{ + AccessControlList: accessControlListWireValue, + }, nil +} + +type patchWire struct { + Op PatchOp `json:"op,omitempty"` + Path *string `json:"path,omitempty"` + Value json.RawMessage `json:"value,omitempty"` +} + +func patchToWire(v *Patch) (*patchWire, error) { + if v == nil { + return nil, nil + } + return &patchWire{ + Op: v.Op, + Path: v.Path, + Value: v.Value, + }, nil +} + +type patchAccountGroupRequestWire struct { + Id *string `json:"id,omitempty"` + Operations []accountPatchWire `json:"Operations,omitempty"` + Schemas []AccountPatchSchema_PatchSchema `json:"schemas,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func patchAccountGroupRequestToWire(v *PatchAccountGroupRequest) (*patchAccountGroupRequestWire, error) { + if v == nil { + return nil, nil + } + operationsWireValue, err := convertSlice(v.Operations, accountPatchToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchAccountGroupRequest.Operations", err) + } + return &patchAccountGroupRequestWire{ + Id: v.Id, + Operations: operationsWireValue, + Schemas: v.Schemas, + AccountId: v.AccountId, + }, nil +} + +type patchAccountServicePrincipalRequestWire struct { + Id *string `json:"id,omitempty"` + Operations []accountPatchWire `json:"Operations,omitempty"` + Schemas []AccountPatchSchema_PatchSchema `json:"schemas,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func patchAccountServicePrincipalRequestToWire(v *PatchAccountServicePrincipalRequest) (*patchAccountServicePrincipalRequestWire, error) { + if v == nil { + return nil, nil + } + operationsWireValue, err := convertSlice(v.Operations, accountPatchToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchAccountServicePrincipalRequest.Operations", err) + } + return &patchAccountServicePrincipalRequestWire{ + Id: v.Id, + Operations: operationsWireValue, + Schemas: v.Schemas, + AccountId: v.AccountId, + }, nil +} + +type patchAccountUserRequestWire struct { + Id *string `json:"id,omitempty"` + Operations []accountPatchWire `json:"Operations,omitempty"` + Schemas []AccountPatchSchema_PatchSchema `json:"schemas,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func patchAccountUserRequestToWire(v *PatchAccountUserRequest) (*patchAccountUserRequestWire, error) { + if v == nil { + return nil, nil + } + operationsWireValue, err := convertSlice(v.Operations, accountPatchToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchAccountUserRequest.Operations", err) + } + return &patchAccountUserRequestWire{ + Id: v.Id, + Operations: operationsWireValue, + Schemas: v.Schemas, + AccountId: v.AccountId, + }, nil +} + +type patchGroupRequestWire struct { + Id *string `json:"id,omitempty"` + Operations []patchWire `json:"Operations,omitempty"` + Schemas []PatchSchema `json:"schemas,omitempty"` +} + +func patchGroupRequestToWire(v *PatchGroupRequest) (*patchGroupRequestWire, error) { + if v == nil { + return nil, nil + } + operationsWireValue, err := convertSlice(v.Operations, patchToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchGroupRequest.Operations", err) + } + return &patchGroupRequestWire{ + Id: v.Id, + Operations: operationsWireValue, + Schemas: v.Schemas, + }, nil +} + +type patchServicePrincipalRequestWire struct { + Id *string `json:"id,omitempty"` + Operations []patchWire `json:"Operations,omitempty"` + Schemas []PatchSchema `json:"schemas,omitempty"` +} + +func patchServicePrincipalRequestToWire(v *PatchServicePrincipalRequest) (*patchServicePrincipalRequestWire, error) { + if v == nil { + return nil, nil + } + operationsWireValue, err := convertSlice(v.Operations, patchToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchServicePrincipalRequest.Operations", err) + } + return &patchServicePrincipalRequestWire{ + Id: v.Id, + Operations: operationsWireValue, + Schemas: v.Schemas, + }, nil +} + +type patchUserRequestWire struct { + Id *string `json:"id,omitempty"` + Operations []patchWire `json:"Operations,omitempty"` + Schemas []PatchSchema `json:"schemas,omitempty"` +} + +func patchUserRequestToWire(v *PatchUserRequest) (*patchUserRequestWire, error) { + if v == nil { + return nil, nil + } + operationsWireValue, err := convertSlice(v.Operations, patchToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchUserRequest.Operations", err) + } + return &patchUserRequestWire{ + Id: v.Id, + Operations: operationsWireValue, + Schemas: v.Schemas, + }, nil +} + +type resourceMetaWire struct { + ResourceType *string `json:"resourceType,omitempty"` +} + +func resourceMetaToWire(v *ResourceMeta) (*resourceMetaWire, error) { + if v == nil { + return nil, nil + } + return &resourceMetaWire{ + ResourceType: v.ResourceType, + }, nil +} + +func resourceMetaFromWire(w *resourceMetaWire) (*ResourceMeta, error) { + if w == nil { + return nil, nil + } + return &ResourceMeta{ + ResourceType: w.ResourceType, + }, nil +} + +type servicePrincipalWire struct { + Active *bool `json:"active,omitempty"` + ApplicationId *string `json:"applicationId,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Entitlements []complexValueWire `json:"entitlements,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Groups []complexValueWire `json:"groups,omitempty"` + Id *string `json:"id,omitempty"` + Roles []complexValueWire `json:"roles,omitempty"` + Schemas []ServicePrincipalSchema `json:"schemas,omitempty"` +} + +func servicePrincipalFromWire(w *servicePrincipalWire) (*ServicePrincipal, error) { + if w == nil { + return nil, nil + } + entitlementsPublicValue, err := convertSlice(w.Entitlements, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServicePrincipal.Entitlements", err) + } + groupsPublicValue, err := convertSlice(w.Groups, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServicePrincipal.Groups", err) + } + rolesPublicValue, err := convertSlice(w.Roles, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ServicePrincipal.Roles", err) + } + return &ServicePrincipal{ + Active: w.Active, + ApplicationId: w.ApplicationId, + DisplayName: w.DisplayName, + Entitlements: entitlementsPublicValue, + ExternalId: w.ExternalId, + Groups: groupsPublicValue, + Id: w.Id, + Roles: rolesPublicValue, + Schemas: w.Schemas, + }, nil +} + +type updateAccountGroupRequestWire struct { + DisplayName *string `json:"displayName,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Id *string `json:"id,omitempty"` + Members []accountComplexValueWire `json:"members,omitempty"` + Meta *accountResourceMetaWire `json:"meta,omitempty"` + Roles []accountComplexValueWire `json:"roles,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func updateAccountGroupRequestToWire(v *UpdateAccountGroupRequest) (*updateAccountGroupRequestWire, error) { + if v == nil { + return nil, nil + } + membersWireValue, err := convertSlice(v.Members, accountComplexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountGroupRequest.Members", err) + } + metaWireValue, err := accountResourceMetaToWire(v.Meta) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountGroupRequest.Meta", err) + } + rolesWireValue, err := convertSlice(v.Roles, accountComplexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountGroupRequest.Roles", err) + } + return &updateAccountGroupRequestWire{ + DisplayName: v.DisplayName, + ExternalId: v.ExternalId, + Id: v.Id, + Members: membersWireValue, + Meta: metaWireValue, + Roles: rolesWireValue, + AccountId: v.AccountId, + }, nil +} + +type updateAccountServicePrincipalRequestWire struct { + Active *bool `json:"active,omitempty"` + ApplicationId *string `json:"applicationId,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Id *string `json:"id,omitempty"` + Roles []accountComplexValueWire `json:"roles,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func updateAccountServicePrincipalRequestToWire(v *UpdateAccountServicePrincipalRequest) (*updateAccountServicePrincipalRequestWire, error) { + if v == nil { + return nil, nil + } + rolesWireValue, err := convertSlice(v.Roles, accountComplexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountServicePrincipalRequest.Roles", err) + } + return &updateAccountServicePrincipalRequestWire{ + Active: v.Active, + ApplicationId: v.ApplicationId, + DisplayName: v.DisplayName, + ExternalId: v.ExternalId, + Id: v.Id, + Roles: rolesWireValue, + AccountId: v.AccountId, + }, nil +} + +type updateAccountUserRequestWire struct { + Active *bool `json:"active,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Emails []accountComplexValueWire `json:"emails,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Id *string `json:"id,omitempty"` + Name *accountNameWire `json:"name,omitempty"` + Roles []accountComplexValueWire `json:"roles,omitempty"` + UserName *string `json:"userName,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func updateAccountUserRequestToWire(v *UpdateAccountUserRequest) (*updateAccountUserRequestWire, error) { + if v == nil { + return nil, nil + } + emailsWireValue, err := convertSlice(v.Emails, accountComplexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountUserRequest.Emails", err) + } + nameWireValue, err := accountNameToWire(v.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountUserRequest.Name", err) + } + rolesWireValue, err := convertSlice(v.Roles, accountComplexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountUserRequest.Roles", err) + } + return &updateAccountUserRequestWire{ + Active: v.Active, + DisplayName: v.DisplayName, + Emails: emailsWireValue, + ExternalId: v.ExternalId, + Id: v.Id, + Name: nameWireValue, + Roles: rolesWireValue, + UserName: v.UserName, + AccountId: v.AccountId, + }, nil +} + +type updateGroupRequestWire struct { + DisplayName *string `json:"displayName,omitempty"` + Entitlements []complexValueWire `json:"entitlements,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Groups []complexValueWire `json:"groups,omitempty"` + Id *string `json:"id,omitempty"` + Members []complexValueWire `json:"members,omitempty"` + Meta *resourceMetaWire `json:"meta,omitempty"` + Roles []complexValueWire `json:"roles,omitempty"` + Schemas []GroupSchema `json:"schemas,omitempty"` +} + +func updateGroupRequestToWire(v *UpdateGroupRequest) (*updateGroupRequestWire, error) { + if v == nil { + return nil, nil + } + entitlementsWireValue, err := convertSlice(v.Entitlements, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateGroupRequest.Entitlements", err) + } + groupsWireValue, err := convertSlice(v.Groups, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateGroupRequest.Groups", err) + } + membersWireValue, err := convertSlice(v.Members, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateGroupRequest.Members", err) + } + metaWireValue, err := resourceMetaToWire(v.Meta) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateGroupRequest.Meta", err) + } + rolesWireValue, err := convertSlice(v.Roles, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateGroupRequest.Roles", err) + } + return &updateGroupRequestWire{ + DisplayName: v.DisplayName, + Entitlements: entitlementsWireValue, + ExternalId: v.ExternalId, + Groups: groupsWireValue, + Id: v.Id, + Members: membersWireValue, + Meta: metaWireValue, + Roles: rolesWireValue, + Schemas: v.Schemas, + }, nil +} + +type updateServicePrincipalRequestWire struct { + Active *bool `json:"active,omitempty"` + ApplicationId *string `json:"applicationId,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Entitlements []complexValueWire `json:"entitlements,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Groups []complexValueWire `json:"groups,omitempty"` + Id *string `json:"id,omitempty"` + Roles []complexValueWire `json:"roles,omitempty"` + Schemas []ServicePrincipalSchema `json:"schemas,omitempty"` +} + +func updateServicePrincipalRequestToWire(v *UpdateServicePrincipalRequest) (*updateServicePrincipalRequestWire, error) { + if v == nil { + return nil, nil + } + entitlementsWireValue, err := convertSlice(v.Entitlements, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateServicePrincipalRequest.Entitlements", err) + } + groupsWireValue, err := convertSlice(v.Groups, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateServicePrincipalRequest.Groups", err) + } + rolesWireValue, err := convertSlice(v.Roles, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateServicePrincipalRequest.Roles", err) + } + return &updateServicePrincipalRequestWire{ + Active: v.Active, + ApplicationId: v.ApplicationId, + DisplayName: v.DisplayName, + Entitlements: entitlementsWireValue, + ExternalId: v.ExternalId, + Groups: groupsWireValue, + Id: v.Id, + Roles: rolesWireValue, + Schemas: v.Schemas, + }, nil +} + +type updateUserRequestWire struct { + Active *bool `json:"active,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Emails []complexValueWire `json:"emails,omitempty"` + Entitlements []complexValueWire `json:"entitlements,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Groups []complexValueWire `json:"groups,omitempty"` + Id *string `json:"id,omitempty"` + Name *nameWire `json:"name,omitempty"` + Roles []complexValueWire `json:"roles,omitempty"` + Schemas []UserSchema `json:"schemas,omitempty"` + UserName *string `json:"userName,omitempty"` +} + +func updateUserRequestToWire(v *UpdateUserRequest) (*updateUserRequestWire, error) { + if v == nil { + return nil, nil + } + emailsWireValue, err := convertSlice(v.Emails, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateUserRequest.Emails", err) + } + entitlementsWireValue, err := convertSlice(v.Entitlements, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateUserRequest.Entitlements", err) + } + groupsWireValue, err := convertSlice(v.Groups, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateUserRequest.Groups", err) + } + nameWireValue, err := nameToWire(v.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateUserRequest.Name", err) + } + rolesWireValue, err := convertSlice(v.Roles, complexValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateUserRequest.Roles", err) + } + return &updateUserRequestWire{ + Active: v.Active, + DisplayName: v.DisplayName, + Emails: emailsWireValue, + Entitlements: entitlementsWireValue, + ExternalId: v.ExternalId, + Groups: groupsWireValue, + Id: v.Id, + Name: nameWireValue, + Roles: rolesWireValue, + Schemas: v.Schemas, + UserName: v.UserName, + }, nil +} + +type userWire struct { + Active *bool `json:"active,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Emails []complexValueWire `json:"emails,omitempty"` + Entitlements []complexValueWire `json:"entitlements,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + Groups []complexValueWire `json:"groups,omitempty"` + Id *string `json:"id,omitempty"` + Name *nameWire `json:"name,omitempty"` + Roles []complexValueWire `json:"roles,omitempty"` + Schemas []UserSchema `json:"schemas,omitempty"` + UserName *string `json:"userName,omitempty"` +} + +func userFromWire(w *userWire) (*User, error) { + if w == nil { + return nil, nil + } + emailsPublicValue, err := convertSlice(w.Emails, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "User.Emails", err) + } + entitlementsPublicValue, err := convertSlice(w.Entitlements, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "User.Entitlements", err) + } + groupsPublicValue, err := convertSlice(w.Groups, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "User.Groups", err) + } + namePublicValue, err := nameFromWire(w.Name) + if err != nil { + return nil, fmt.Errorf("%s: %w", "User.Name", err) + } + rolesPublicValue, err := convertSlice(w.Roles, complexValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "User.Roles", err) + } + return &User{ + Active: w.Active, + DisplayName: w.DisplayName, + Emails: emailsPublicValue, + Entitlements: entitlementsPublicValue, + ExternalId: w.ExternalId, + Groups: groupsPublicValue, + Id: w.Id, + Name: namePublicValue, + Roles: rolesPublicValue, + Schemas: w.Schemas, + UserName: w.UserName, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/secrets/.package.json b/secrets/.package.json new file mode 100644 index 0000000..77e961f --- /dev/null +++ b/secrets/.package.json @@ -0,0 +1,3 @@ +{ + "package": "secrets" +} diff --git a/secrets/CHANGELOG.md b/secrets/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/secrets/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/secrets/README.md b/secrets/README.md new file mode 100644 index 0000000..c76c3c8 --- /dev/null +++ b/secrets/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/secrets + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/secrets@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/secrets/v1" + +client, err := secrets.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/secrets/go.mod b/secrets/go.mod new file mode 100644 index 0000000..10bbfb0 --- /dev/null +++ b/secrets/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/secrets + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/secrets/internal/version.go b/secrets/internal/version.go new file mode 100644 index 0000000..16a2499 --- /dev/null +++ b/secrets/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-secrets" + +const Version = "0.0.1-dev.1" diff --git a/secrets/v1/client.go b/secrets/v1/client.go new file mode 100755 index 0000000..71e2dcc --- /dev/null +++ b/secrets/v1/client.go @@ -0,0 +1,962 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package secrets + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/secrets/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new secret scope. +// +// The scope name must consist of alphanumeric characters, dashes, underscores, +// and periods, and may not exceed 128 characters. +// +// Example request: +// +// .. code:: +// +// { "scope": "my-simple-databricks-scope", "initial_manage_principal": "users" +// "scope_backend_type": "databricks|azure_keyvault", # below is only required +// if scope type is azure_keyvault "backend_azure_keyvault": { "resource_id": +// "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxx/providers/Microsoft.KeyVault/vaults/xxxx", +// "tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "dns_name": +// "https://xxxx.vault.azure.net/", } } +// +// If “initial_manage_principal“ is specified, the initial ACL applied to the +// scope is applied to the supplied principal (user or group) with “MANAGE“ +// permissions. The only supported principal for this option is the group +// “users“, which contains all users in the workspace. If +// “initial_manage_principal“ is not specified, the initial ACL with +// “MANAGE“ permission applied to the scope is assigned to the API request +// issuer's user identity. +// +// If “scope_backend_type“ is “azure_keyvault“, a secret scope is created +// with secrets from a given Azure KeyVault. The caller must provide the +// keyvault_resource_id and the tenant_id for the key vault. If +// “scope_backend_type“ is “databricks“ or is unspecified, an empty secret +// scope is created and stored in 's own storage. +// +// Throws “RESOURCE_ALREADY_EXISTS“ if a scope with the given name already +// exists. Throws “RESOURCE_LIMIT_EXCEEDED“ if maximum number of scopes in the +// workspace is exceeded. Throws “INVALID_PARAMETER_VALUE“ if the scope name +// is invalid. Throws “BAD_REQUEST“ if request violated constraints. Throws +// “CUSTOMER_UNAUTHORIZED“ if normal user attempts to create a scope with name +// reserved for databricks internal usage. Throws “UNAUTHENTICATED“ if unable +// to verify user access permission on Azure KeyVault +func (c *internalClient) CreateScope(ctx context.Context, req *CreateScopeRequest, opts ...call.Option) (*CreateScopeResponse, error) { + wireReq, err := createScopeRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/scopes/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateScopeResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &CreateScopeResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the given ACL on the given scope. +// +// Users must have the “MANAGE“ permission to invoke this API. +// +// Example request: +// +// .. code:: +// +// { "scope": "my-secret-scope", "principal": "data-scientists" } +// +// Throws “RESOURCE_DOES_NOT_EXIST“ if no such secret scope, principal, or ACL +// exists. Throws “PERMISSION_DENIED“ if the user does not have permission to +// make this API call. Throws “INVALID_PARAMETER_VALUE“ if the permission or +// principal is invalid. +func (c *internalClient) DeleteAcl(ctx context.Context, req *DeleteAclRequest, opts ...call.Option) (*DeleteAclResponse, error) { + wireReq, err := deleteAclRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/acls/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteAclResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteAclResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a secret scope. +// +// Example request: +// +// .. code:: +// +// { "scope": "my-secret-scope" } +// +// Throws “RESOURCE_DOES_NOT_EXIST“ if the scope does not exist. Throws +// “PERMISSION_DENIED“ if the user does not have permission to make this API +// call. Throws “BAD_REQUEST“ if system user attempts to delete internal +// secret scope. +func (c *internalClient) DeleteScope(ctx context.Context, req *DeleteScopeRequest, opts ...call.Option) (*DeleteScopeResponse, error) { + wireReq, err := deleteScopeRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/scopes/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteScopeResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteScopeResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the secret stored in this secret scope. You must have “WRITE“ or +// “MANAGE“ permission on the Secret Scope. +// +// Example request: +// +// .. code:: +// +// { "scope": "my-secret-scope", "key": "my-secret-key" } +// +// Throws “RESOURCE_DOES_NOT_EXIST“ if no such secret scope or secret exists. +// Throws “PERMISSION_DENIED“ if the user does not have permission to make +// this API call. Throws “BAD_REQUEST“ if system user attempts to delete an +// internal secret, or request is made against Azure KeyVault backed scope. +func (c *internalClient) DeleteSecret(ctx context.Context, req *DeleteSecretRequest, opts ...call.Option) (*DeleteSecretResponse, error) { + wireReq, err := deleteSecretRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteSecretResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteSecretResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Describes the details about the given ACL, such as the group and permission. +// +// Users must have the “MANAGE“ permission to invoke this API. +// +// Example response: +// +// .. code:: +// +// { "principal": "data-scientists", "permission": "READ" } +// +// Throws “RESOURCE_DOES_NOT_EXIST“ if no such secret scope exists. Throws +// “PERMISSION_DENIED“ if the user does not have permission to make this API +// call. Throws “INVALID_PARAMETER_VALUE“ if the permission or principal is +// invalid. +func (c *internalClient) GetAcl(ctx context.Context, req *GetAclRequest, opts ...call.Option) (*AclItem, error) { + wireReq, err := getAclRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/acls/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "scope", wireReq.Scope); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "principal", wireReq.Principal); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AclItem + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp aclItemWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = aclItemFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a secret for a given key and scope. This API can only be called from the +// DBUtils interface. Users need the READ permission to make this call. +// +// Example response: +// +// .. code:: +// +// { "key": "my-string-key", "value": } +// +// Note that the secret value returned is in bytes. The interpretation of the +// bytes is determined by the caller in DBUtils and the type the data is decoded +// into. +// +// Throws “RESOURCE_DOES_NOT_EXIST“ if no such secret or secret scope exists. +// Throws “PERMISSION_DENIED“ if the user does not have permission to make +// this API call. +// +// Note: This is explicitly an undocumented API. It also doesn't need to be +// supported for the /preview prefix, because it's not a customer-facing API +// (i.e. only used for DBUtils SecretUtils to fetch secrets). +// +// Throws “RESOURCE_DOES_NOT_EXIST“ if no such secret scope or secret exists. +// Throws “BAD_REQUEST“ if normal user calls get secret outside of a notebook. +// AKV specific errors: Throws “INVALID_PARAMETER_VALUE“ if secret name is not +// alphanumeric or too long. Throws “PERMISSION_DENIED“ if secret manager +// cannot access AKV with 403 error Throws “MALFORMED_REQUEST“ if secret +// manager cannot access AKV with any other 4xx error +func (c *internalClient) GetSecret(ctx context.Context, req *GetSecretRequest, opts ...call.Option) (*GetSecretResponse, error) { + wireReq, err := getSecretRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/get" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "scope", wireReq.Scope); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "key", wireReq.Key); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetSecretResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getSecretResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getSecretResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists the ACLs set on the given scope. +// +// Users must have the “MANAGE“ permission to invoke this API. +// +// Example response: +// +// .. code:: +// +// { "acls": [{ "principal": "admins", "permission": "MANAGE" },{ "principal": +// "data-scientists", "permission": "READ" }] } +// +// Throws “RESOURCE_DOES_NOT_EXIST“ if no such secret scope exists. Throws +// “PERMISSION_DENIED“ if the user does not have permission to make this API +// call. +func (c *internalClient) ListAcls(ctx context.Context, req *ListAclsRequest, opts ...call.Option) (*ListAclsResponse, error) { + wireReq, err := listAclsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/acls/list" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "scope", wireReq.Scope); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAclsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAclsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAclsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists all secret scopes available in the workspace. +// +// Example response: +// +// .. code:: +// +// { "scopes": [{ "name": "my-databricks-scope", "backend_type": "DATABRICKS" +// },{ "name": "mount-points", "backend_type": "DATABRICKS" }] } +// +// Throws “PERMISSION_DENIED“ if the user does not have permission to make +// this API call. +func (c *internalClient) ListScopes(ctx context.Context, req *ListScopesRequest, opts ...call.Option) (*ListScopesResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/scopes/list" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListScopesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listScopesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listScopesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists the secret keys that are stored at this scope. This is a metadata-only +// operation; secret data cannot be retrieved using this API. Users need the +// READ permission to make this call. +// +// Example response: +// +// .. code:: +// +// { "secrets": [ { "key": "my-string-key"", "last_updated_timestamp": +// "1520467595000" }, { "key": "my-byte-key", "last_updated_timestamp": +// "1520467595000" }, ] } +// +// The lastUpdatedTimestamp returned is in milliseconds since epoch. +// +// Throws “RESOURCE_DOES_NOT_EXIST“ if no such secret scope exists. Throws +// “PERMISSION_DENIED“ if the user does not have permission to make this API +// call. +func (c *internalClient) ListSecrets(ctx context.Context, req *ListSecretsRequest, opts ...call.Option) (*ListSecretsResponse, error) { + wireReq, err := listSecretsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/list" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "scope", wireReq.Scope); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListSecretsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listSecretsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listSecretsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates or overwrites the ACL associated with the given principal (user or +// group) on the specified scope point. In general, a user or group will use the +// most powerful permission available to them, and permissions are ordered as +// follows: +// +// * “MANAGE“ - Allowed to change ACLs, and read and write to this secret +// scope. * “WRITE“ - Allowed to read and write to this secret scope. * +// “READ“ - Allowed to read this secret scope and list what secrets are +// available. +// +// Note that in general, secret values can only be read from within a command on +// a cluster (for example, through a notebook). There is no API to read the +// actual secret value material outside of a cluster. However, the user's +// permission will be applied based on who is executing the command, and they +// must have at least READ permission. +// +// Users must have the “MANAGE“ permission to invoke this API. +// +// Example request: +// +// .. code:: +// +// { "scope": "my-secret-scope", "principal": "data-scientists", "permission": +// "READ" } +// +// The principal is a user or group name corresponding to an existing +// principal to be granted or revoked access. +// +// Throws “RESOURCE_DOES_NOT_EXIST“ if no such secret scope exists. Throws +// “RESOURCE_ALREADY_EXISTS“ if a permission for the principal already exists. +// Throws “INVALID_PARAMETER_VALUE“ if the permission or principal is invalid. +// Throws “PERMISSION_DENIED“ if the user does not have permission to make +// this API call. +func (c *internalClient) PutAcl(ctx context.Context, req *PutAclRequest, opts ...call.Option) (*PutAclResponse, error) { + wireReq, err := putAclRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/acls/put" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PutAclResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &PutAclResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Inserts a secret under the provided scope with the given name. If a secret +// already exists with the same name, this command overwrites the existing +// secret's value. The server encrypts the secret using the secret scope's +// encryption settings before storing it. You must have “WRITE“ or “MANAGE“ +// permission on the secret scope. +// +// The secret key must consist of alphanumeric characters, dashes, underscores, +// and periods, and cannot exceed 128 characters. The maximum allowed secret +// value size is 128 KB. The maximum number of secrets in a given scope is 1000. +// +// Example request: +// +// .. code:: +// +// { "scope": "my-databricks-scope", "key": "my-string-key", "string_value": +// "foobar" } +// +// The input fields "string_value" or "bytes_value" specify the type of the +// secret, which will determine the value returned when the secret value is +// requested. Exactly one must be specified. +// +// Throws “RESOURCE_DOES_NOT_EXIST“ if no such secret scope exists. Throws +// “RESOURCE_LIMIT_EXCEEDED“ if maximum number of secrets in scope is +// exceeded. Throws “INVALID_PARAMETER_VALUE“ if the request parameters are +// invalid. Throws “PERMISSION_DENIED“ if the user does not have permission to +// make this API call. Throws “MALFORMED_REQUEST“ if request is incorrectly +// formatted or conflicting. Throws “BAD_REQUEST“ if request is made against +// Azure KeyVault backed scope. +func (c *internalClient) PutSecret(ctx context.Context, req *PutSecretRequest, opts ...call.Option) (*PutSecretResponse, error) { + wireReq, err := putSecretRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/secrets/put" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PutSecretResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &PutSecretResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/secrets/v1/genhelper.go b/secrets/v1/genhelper.go new file mode 100755 index 0000000..90ff500 --- /dev/null +++ b/secrets/v1/genhelper.go @@ -0,0 +1,178 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package secrets + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} diff --git a/secrets/v1/model.go b/secrets/v1/model.go new file mode 100755 index 0000000..1ba2422 --- /dev/null +++ b/secrets/v1/model.go @@ -0,0 +1,207 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package secrets + +// The ACL permission levels for Secret ACLs applied to secret scopes. +type AclPermission string + +const ( + AclPermission_Unspecified AclPermission = "" + // Allowed to perform read operations (get, list) on secrets in this scope. + AclPermission_Read AclPermission = "READ" + // Allowed to read and write secrets to this secret scope. + AclPermission_Write AclPermission = "WRITE" + // Allowed to read/write ACLs, and read/write secrets to this secret scope. + AclPermission_Manage AclPermission = "MANAGE" +) + +// The types of secret scope backends in the Secret Manager. Azure KeyVault +// backed secret scopes will be supported in a later release. +type ScopeBackendType string + +const ( + ScopeBackendType_Unspecified ScopeBackendType = "" + // A secret scope in which secrets are stored in Databrick managed storage and + // encrypted with a cloud-based specific encryption key. + ScopeBackendType_Databricks ScopeBackendType = "DATABRICKS" + // A customer Azure KeyVault backed secret scope. Reading secrets from this + // scope will directly read secrets from the customer vault. Only scope and + // secret ACL metadata are stored in Databricks. + ScopeBackendType_AzureKeyvault ScopeBackendType = "AZURE_KEYVAULT" +) + +// An item representing an ACL rule applied to the given principal (user or +// group) on the associated scope point.. +type AclItem struct { + // The principal in which the permission is applied. + Principal *string + // The permission level applied to the principal. + Permission AclPermission +} + +// The metadata of the Azure KeyVault for a secret scope of type +// `AZURE_KEYVAULT`. +type AzureKeyVaultSecretScopeMetadata struct { + // The resource id of the azure KeyVault that user wants to associate the scope + // with. + ResourceId *string + // The DNS of the KeyVault + DnsName *string +} + +type CreateScopeRequest struct { + // Scope name requested by the user. Scope names are unique. + Scope *string + // The principal that is initially granted ``MANAGE`` permission to the created + // scope. + InitialManagePrincipal *string + // The backend type the scope will be created with. If not specified, will + // default to ``DATABRICKS`` + ScopeBackendType ScopeBackendType + // The metadata for the secret scope if the type is ``AZURE_KEYVAULT`` + BackendAzureKeyvault *AzureKeyVaultSecretScopeMetadata +} + +type CreateScopeResponse struct { +} + +type DeleteAclRequest struct { + // The name of the scope to remove permissions from. + Scope *string + // The principal to remove an existing ACL from. + Principal *string +} + +type DeleteAclResponse struct { +} + +type DeleteScopeRequest struct { + // Name of the scope to delete. + Scope *string +} + +type DeleteScopeResponse struct { +} + +type DeleteSecretRequest struct { + // The name of the scope that contains the secret to delete. + Scope *string + // Name of the secret to delete. + Key *string +} + +type DeleteSecretResponse struct { +} + +type GetAclRequest struct { + // The name of the scope to fetch ACL information from. + Scope *string + // The principal to fetch ACL information for. + Principal *string +} + +type GetSecretRequest struct { + // The name of the scope that contains the secret. + Scope *string + // Name of the secret to fetch value information. + Key *string +} + +type GetSecretResponse struct { + // A unique name to identify the secret. + Key *string + // The value of the secret in its byte representation. + Value []byte +} + +type ListAclsRequest struct { + // The name of the scope to fetch ACL information from. + Scope *string +} + +type ListAclsResponse struct { + // The associated ACLs rule applied to principals in the given scope. + Items []AclItem +} + +type ListScopesRequest struct { +} + +type ListScopesResponse struct { + // The available secret scopes. + Scopes []SecretScope +} + +type ListSecretsRequest struct { + // The name of the scope to list secrets within. + Scope *string +} + +type ListSecretsResponse struct { + // Metadata information of all secrets contained within the given scope. + Secrets []SecretMetadata +} + +type PutAclRequest struct { + // The name of the scope to apply permissions to. + Scope *string + // The principal in which the permission is applied. + Principal *string + // The permission level applied to the principal. + Permission AclPermission +} + +type PutAclResponse struct { +} + +type PutSecretRequest struct { + // The name of the scope to which the secret will be associated with. + Scope *string + // A unique name to identify the secret. + Key *string + Value isPutSecretRequest_Value +} + +type isPutSecretRequest_Value interface { + isPutSecretRequest_Value() +} + +// PutSecretRequest_Value_StringValue selects StringValue for PutSecretRequest.Value. +// If specified, note that the value will be stored in UTF-8 (MB4) form. +type PutSecretRequest_Value_StringValue struct { + StringValue string +} + +func (*PutSecretRequest_Value_StringValue) isPutSecretRequest_Value() {} + +// PutSecretRequest_Value_BytesValue selects BytesValue for PutSecretRequest.Value. +// If specified, value will be stored as bytes. +type PutSecretRequest_Value_BytesValue struct { + BytesValue []byte +} + +func (*PutSecretRequest_Value_BytesValue) isPutSecretRequest_Value() {} + +type PutSecretResponse struct { +} + +// The metadata about a secret. Returned when listing secrets. Does not contain +// the actual secret value.. +type SecretMetadata struct { + // A unique name to identify the secret. + Key *string + // The last updated timestamp (in milliseconds) for the secret. + LastUpdatedTimestamp *int64 +} + +// An organizational resource for storing secrets. Secret scopes can be +// different types (Databricks-managed, Azure KeyVault backed, etc), and ACLs +// can be applied to control permissions for all secrets within a scope.. +type SecretScope struct { + // A unique name to identify the secret scope. + Name *string + // The type of secret scope backend. + BackendType ScopeBackendType + // The metadata for the secret scope if the type is ``AZURE_KEYVAULT`` + KeyvaultMetadata *AzureKeyVaultSecretScopeMetadata +} diff --git a/secrets/v1/wire.go b/secrets/v1/wire.go new file mode 100755 index 0000000..eb26151 --- /dev/null +++ b/secrets/v1/wire.go @@ -0,0 +1,337 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package secrets + +import ( + "fmt" +) + +type aclItemWire struct { + Principal *string `json:"principal,omitempty"` + Permission AclPermission `json:"permission,omitempty"` +} + +func aclItemFromWire(w *aclItemWire) (*AclItem, error) { + if w == nil { + return nil, nil + } + return &AclItem{ + Principal: w.Principal, + Permission: w.Permission, + }, nil +} + +type azureKeyVaultSecretScopeMetadataWire struct { + ResourceId *string `json:"resource_id,omitempty"` + DnsName *string `json:"dns_name,omitempty"` +} + +func azureKeyVaultSecretScopeMetadataToWire(v *AzureKeyVaultSecretScopeMetadata) (*azureKeyVaultSecretScopeMetadataWire, error) { + if v == nil { + return nil, nil + } + return &azureKeyVaultSecretScopeMetadataWire{ + ResourceId: v.ResourceId, + DnsName: v.DnsName, + }, nil +} + +func azureKeyVaultSecretScopeMetadataFromWire(w *azureKeyVaultSecretScopeMetadataWire) (*AzureKeyVaultSecretScopeMetadata, error) { + if w == nil { + return nil, nil + } + return &AzureKeyVaultSecretScopeMetadata{ + ResourceId: w.ResourceId, + DnsName: w.DnsName, + }, nil +} + +type createScopeRequestWire struct { + Scope *string `json:"scope,omitempty"` + InitialManagePrincipal *string `json:"initial_manage_principal,omitempty"` + ScopeBackendType ScopeBackendType `json:"scope_backend_type,omitempty"` + BackendAzureKeyvault *azureKeyVaultSecretScopeMetadataWire `json:"backend_azure_keyvault,omitempty"` +} + +func createScopeRequestToWire(v *CreateScopeRequest) (*createScopeRequestWire, error) { + if v == nil { + return nil, nil + } + backendAzureKeyvaultWireValue, err := azureKeyVaultSecretScopeMetadataToWire(v.BackendAzureKeyvault) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateScopeRequest.BackendAzureKeyvault", err) + } + return &createScopeRequestWire{ + Scope: v.Scope, + InitialManagePrincipal: v.InitialManagePrincipal, + ScopeBackendType: v.ScopeBackendType, + BackendAzureKeyvault: backendAzureKeyvaultWireValue, + }, nil +} + +type deleteAclRequestWire struct { + Scope *string `json:"scope,omitempty"` + Principal *string `json:"principal,omitempty"` +} + +func deleteAclRequestToWire(v *DeleteAclRequest) (*deleteAclRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteAclRequestWire{ + Scope: v.Scope, + Principal: v.Principal, + }, nil +} + +type deleteScopeRequestWire struct { + Scope *string `json:"scope,omitempty"` +} + +func deleteScopeRequestToWire(v *DeleteScopeRequest) (*deleteScopeRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteScopeRequestWire{ + Scope: v.Scope, + }, nil +} + +type deleteSecretRequestWire struct { + Scope *string `json:"scope,omitempty"` + Key *string `json:"key,omitempty"` +} + +func deleteSecretRequestToWire(v *DeleteSecretRequest) (*deleteSecretRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteSecretRequestWire{ + Scope: v.Scope, + Key: v.Key, + }, nil +} + +type getAclRequestWire struct { + Scope *string `json:"scope,omitempty"` + Principal *string `json:"principal,omitempty"` +} + +func getAclRequestToWire(v *GetAclRequest) (*getAclRequestWire, error) { + if v == nil { + return nil, nil + } + return &getAclRequestWire{ + Scope: v.Scope, + Principal: v.Principal, + }, nil +} + +type getSecretRequestWire struct { + Scope *string `json:"scope,omitempty"` + Key *string `json:"key,omitempty"` +} + +func getSecretRequestToWire(v *GetSecretRequest) (*getSecretRequestWire, error) { + if v == nil { + return nil, nil + } + return &getSecretRequestWire{ + Scope: v.Scope, + Key: v.Key, + }, nil +} + +type getSecretResponseWire struct { + Key *string `json:"key,omitempty"` + Value []byte `json:"value,omitempty"` +} + +func getSecretResponseFromWire(w *getSecretResponseWire) (*GetSecretResponse, error) { + if w == nil { + return nil, nil + } + return &GetSecretResponse{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type listAclsRequestWire struct { + Scope *string `json:"scope,omitempty"` +} + +func listAclsRequestToWire(v *ListAclsRequest) (*listAclsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAclsRequestWire{ + Scope: v.Scope, + }, nil +} + +type listAclsResponseWire struct { + Items []aclItemWire `json:"items,omitempty"` +} + +func listAclsResponseFromWire(w *listAclsResponseWire) (*ListAclsResponse, error) { + if w == nil { + return nil, nil + } + itemsPublicValue, err := convertSlice(w.Items, aclItemFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAclsResponse.Items", err) + } + return &ListAclsResponse{ + Items: itemsPublicValue, + }, nil +} + +type listScopesResponseWire struct { + Scopes []secretScopeWire `json:"scopes,omitempty"` +} + +func listScopesResponseFromWire(w *listScopesResponseWire) (*ListScopesResponse, error) { + if w == nil { + return nil, nil + } + scopesPublicValue, err := convertSlice(w.Scopes, secretScopeFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListScopesResponse.Scopes", err) + } + return &ListScopesResponse{ + Scopes: scopesPublicValue, + }, nil +} + +type listSecretsRequestWire struct { + Scope *string `json:"scope,omitempty"` +} + +func listSecretsRequestToWire(v *ListSecretsRequest) (*listSecretsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSecretsRequestWire{ + Scope: v.Scope, + }, nil +} + +type listSecretsResponseWire struct { + Secrets []secretMetadataWire `json:"secrets,omitempty"` +} + +func listSecretsResponseFromWire(w *listSecretsResponseWire) (*ListSecretsResponse, error) { + if w == nil { + return nil, nil + } + secretsPublicValue, err := convertSlice(w.Secrets, secretMetadataFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListSecretsResponse.Secrets", err) + } + return &ListSecretsResponse{ + Secrets: secretsPublicValue, + }, nil +} + +type putAclRequestWire struct { + Scope *string `json:"scope,omitempty"` + Principal *string `json:"principal,omitempty"` + Permission AclPermission `json:"permission,omitempty"` +} + +func putAclRequestToWire(v *PutAclRequest) (*putAclRequestWire, error) { + if v == nil { + return nil, nil + } + return &putAclRequestWire{ + Scope: v.Scope, + Principal: v.Principal, + Permission: v.Permission, + }, nil +} + +type putSecretRequestWire struct { + Scope *string `json:"scope,omitempty"` + Key *string `json:"key,omitempty"` + StringValue *string `json:"string_value,omitempty"` + BytesValue []byte `json:"bytes_value,omitempty"` +} + +func putSecretRequestToWire(v *PutSecretRequest) (*putSecretRequestWire, error) { + if v == nil { + return nil, nil + } + var valueStringValueWire *string + var valueBytesValueWire []byte + switch value := v.Value.(type) { + case nil: + case *PutSecretRequest_Value_StringValue: + if value != nil { + valueStringValueWire = new(value.StringValue) + } + case *PutSecretRequest_Value_BytesValue: + if value != nil { + valueBytesValueWire = value.BytesValue + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "PutSecretRequest.Value", value) + } + return &putSecretRequestWire{ + Scope: v.Scope, + Key: v.Key, + StringValue: valueStringValueWire, + BytesValue: valueBytesValueWire, + }, nil +} + +type secretMetadataWire struct { + Key *string `json:"key,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` +} + +func secretMetadataFromWire(w *secretMetadataWire) (*SecretMetadata, error) { + if w == nil { + return nil, nil + } + return &SecretMetadata{ + Key: w.Key, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + }, nil +} + +type secretScopeWire struct { + Name *string `json:"name,omitempty"` + BackendType ScopeBackendType `json:"backend_type,omitempty"` + KeyvaultMetadata *azureKeyVaultSecretScopeMetadataWire `json:"keyvault_metadata,omitempty"` +} + +func secretScopeFromWire(w *secretScopeWire) (*SecretScope, error) { + if w == nil { + return nil, nil + } + keyvaultMetadataPublicValue, err := azureKeyVaultSecretScopeMetadataFromWire(w.KeyvaultMetadata) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SecretScope.KeyvaultMetadata", err) + } + return &SecretScope{ + Name: w.Name, + BackendType: w.BackendType, + KeyvaultMetadata: keyvaultMetadataPublicValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/settings/.package.json b/settings/.package.json new file mode 100644 index 0000000..7de8ca9 --- /dev/null +++ b/settings/.package.json @@ -0,0 +1,3 @@ +{ + "package": "settings" +} diff --git a/settings/CHANGELOG.md b/settings/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/settings/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/settings/README.md b/settings/README.md new file mode 100644 index 0000000..c8b0e98 --- /dev/null +++ b/settings/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/settings + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/settings@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/settings/v2" + +client, err := settings.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/settings/go.mod b/settings/go.mod new file mode 100644 index 0000000..e444738 --- /dev/null +++ b/settings/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/settings + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/settings/internal/version.go b/settings/internal/version.go new file mode 100644 index 0000000..db7d0f0 --- /dev/null +++ b/settings/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-settings" + +const Version = "0.0.1-dev.1" diff --git a/settings/v2/client.go b/settings/v2/client.go new file mode 100755 index 0000000..70247c7 --- /dev/null +++ b/settings/v2/client.go @@ -0,0 +1,861 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package settings + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/settings/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Get a setting value at account level. See +// :method:settingsv2/listaccountsettingsmetadata for list of setting available +// via public APIs at account level. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetPublicAccountSetting(ctx context.Context, req *GetPublicAccountSettingRequest, opts ...call.Option) (*Setting, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/settings/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Setting + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp settingWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = settingFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a user preference for a specific user. User preferences are personal +// settings that allow individual customization without affecting other users. +// See :method:settingsv2/listaccountuserpreferencesmetadata for list of user +// preferences available via public APIs. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetPublicAccountUserPreference(ctx context.Context, req *GetPublicAccountUserPreferenceRequest, opts ...call.Option) (*UserPreference, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/users/") + pb.singleSegment(*req.UserId) + pb.literal("/settings/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UserPreference + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp userPreferenceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = userPreferenceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a setting value at workspace level. See +// :method:settingsv2/listworkspacesettingsmetadata for list of setting +// available via public APIs. +func (c *internalClient) GetPublicWorkspaceSetting(ctx context.Context, req *GetPublicWorkspaceSettingRequest, opts ...call.Option) (*Setting, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/settings/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Setting + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp settingWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = settingFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List valid setting keys and metadata. These settings are available to be +// referenced via GET :method:settingsv2/getpublicaccountsetting and PATCH +// :method:settingsv2/patchpublicaccountsetting APIs +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListAccountSettingsMetadata(ctx context.Context, req *ListAccountSettingsMetadataRequest, opts ...call.Option) (*ListAccountSettingsMetadataResponse, error) { + wireReq, err := listAccountSettingsMetadataRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/settings-metadata") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAccountSettingsMetadataResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAccountSettingsMetadataResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAccountSettingsMetadataResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListAccountSettingsMetadataIter returns an iterator that iterates +// over the results of ListAccountSettingsMetadata. +// +// For example: +// +// for item, err := range c.ListAccountSettingsMetadataIter(ctx, &ListAccountSettingsMetadataRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListAccountSettingsMetadata call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListAccountSettingsMetadata directly. +func (c *internalClient) ListAccountSettingsMetadataIter(ctx context.Context, req *ListAccountSettingsMetadataRequest, opts ...call.Option) iter.Seq2[*SettingsMetadata, error] { + return func(yield func(*SettingsMetadata, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListAccountSettingsMetadataRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListAccountSettingsMetadata(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.SettingsMetadata { + if !yield(&resp.SettingsMetadata[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List valid user preferences and their metadata for a specific user. User +// preferences are personal settings that allow individual customization without +// affecting other users. These settings are available to be referenced via GET +// :method:settingsv2/getpublicaccountuserpreference and PATCH +// :method:settingsv2/patchpublicaccountuserpreference APIs +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListAccountUserPreferencesMetadata(ctx context.Context, req *ListAccountUserPreferencesMetadataRequest, opts ...call.Option) (*ListAccountUserPreferencesMetadataResponse, error) { + wireReq, err := listAccountUserPreferencesMetadataRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/users/") + pb.singleSegment(*req.UserId) + pb.literal("/settings-metadata") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListAccountUserPreferencesMetadataResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listAccountUserPreferencesMetadataResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listAccountUserPreferencesMetadataResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListAccountUserPreferencesMetadataIter returns an iterator that iterates +// over the results of ListAccountUserPreferencesMetadata. +// +// For example: +// +// for item, err := range c.ListAccountUserPreferencesMetadataIter(ctx, &ListAccountUserPreferencesMetadataRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListAccountUserPreferencesMetadata call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListAccountUserPreferencesMetadata directly. +func (c *internalClient) ListAccountUserPreferencesMetadataIter(ctx context.Context, req *ListAccountUserPreferencesMetadataRequest, opts ...call.Option) iter.Seq2[*SettingsMetadata, error] { + return func(yield func(*SettingsMetadata, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListAccountUserPreferencesMetadataRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListAccountUserPreferencesMetadata(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.SettingsMetadata { + if !yield(&resp.SettingsMetadata[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List valid setting keys and metadata. These settings are available to be +// referenced via GET :method:settingsv2/getpublicworkspacesetting and PATCH +// :method:settingsv2/patchpublicworkspacesetting APIs +func (c *internalClient) ListWorkspaceSettingsMetadata(ctx context.Context, req *ListWorkspaceSettingsMetadataRequest, opts ...call.Option) (*ListWorkspaceSettingsMetadataResponse, error) { + wireReq, err := listWorkspaceSettingsMetadataRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/settings-metadata" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListWorkspaceSettingsMetadataResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listWorkspaceSettingsMetadataResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listWorkspaceSettingsMetadataResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListWorkspaceSettingsMetadataIter returns an iterator that iterates +// over the results of ListWorkspaceSettingsMetadata. +// +// For example: +// +// for item, err := range c.ListWorkspaceSettingsMetadataIter(ctx, &ListWorkspaceSettingsMetadataRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListWorkspaceSettingsMetadata call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListWorkspaceSettingsMetadata directly. +func (c *internalClient) ListWorkspaceSettingsMetadataIter(ctx context.Context, req *ListWorkspaceSettingsMetadataRequest, opts ...call.Option) iter.Seq2[*SettingsMetadata, error] { + return func(yield func(*SettingsMetadata, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListWorkspaceSettingsMetadataRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListWorkspaceSettingsMetadata(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.SettingsMetadata { + if !yield(&resp.SettingsMetadata[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Patch a setting value at account level. See +// :method:settingsv2/listaccountsettingsmetadata for list of setting available +// via public APIs at account level. To determine the correct field to include +// in a patch request, refer to the type field of the setting returned in the +// :method:settingsv2/listaccountsettingsmetadata response. +// +// Note: Page refresh is required for changes to take effect in UI. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) PatchPublicAccountSetting(ctx context.Context, req *PatchPublicAccountSettingRequest, opts ...call.Option) (*Setting, error) { + wireReq, err := patchPublicAccountSettingRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Setting) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/settings/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Setting + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp settingWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = settingFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update a user preference for a specific user. User preferences are personal +// settings that allow individual customization without affecting other users. +// See :method:settingsv2/listaccountuserpreferencesmetadata for list of user +// preferences available via public APIs. +// +// Note: Page refresh is required for changes to take effect in UI. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) PatchPublicAccountUserPreference(ctx context.Context, req *PatchPublicAccountUserPreferenceRequest, opts ...call.Option) (*UserPreference, error) { + wireReq, err := patchPublicAccountUserPreferenceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Setting) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.1/accounts/") + pb.singleSegment(accountID) + pb.literal("/users/") + pb.singleSegment(*req.UserId) + pb.literal("/settings/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UserPreference + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp userPreferenceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = userPreferenceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Patch a setting value at workspace level. See +// :method:settingsv2/listworkspacesettingsmetadata for list of setting +// available via public APIs at workspace level. To determine the correct field +// to include in a patch request, refer to the type field of the setting +// returned in the :method:settingsv2/listworkspacesettingsmetadata response. +// +// Note: Page refresh is required for changes to take effect in UI. +func (c *internalClient) PatchPublicWorkspaceSetting(ctx context.Context, req *PatchPublicWorkspaceSettingRequest, opts ...call.Option) (*Setting, error) { + wireReq, err := patchPublicWorkspaceSettingRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Setting) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/settings/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Setting + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp settingWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = settingFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/settings/v2/genhelper.go b/settings/v2/genhelper.go new file mode 100755 index 0000000..7bfc806 --- /dev/null +++ b/settings/v2/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package settings + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/settings/v2/model.go b/settings/v2/model.go new file mode 100755 index 0000000..e11c146 --- /dev/null +++ b/settings/v2/model.go @@ -0,0 +1,605 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package settings + +// Preview phase for settings that are feature previews. For settings that are +// not feature previews, the preview_phase field is left unset. Mirrors only the +// customer-facing phases surfaced in the UI; internal-only phases (DISABLED, +// DEV, UNDER_MIGRATION, LAUNCHED, etc.) are not exposed here. +type PreviewPhase string + +const ( + PreviewPhase_Unspecified PreviewPhase = "" + // The feature is in private preview, available only to specifically enrolled + // customers. + PreviewPhase_PrivatePreview PreviewPhase = "PRIVATE_PREVIEW" + // The feature is in public preview, available to all customers. Also used for + // gated public preview (available to customers who request access) since the + // distinction is internal. + PreviewPhase_PublicPreview PreviewPhase = "PUBLIC_PREVIEW" + // The feature is in beta. + PreviewPhase_Beta PreviewPhase = "BETA" + // The feature is approaching general availability. + PreviewPhase_GaSoon PreviewPhase = "GA_SOON" + // The feature has reached general availability. + PreviewPhase_Ga PreviewPhase = "GA" +) + +type AibiDashboardEmbeddingAccessPolicy_AccessPolicyType string + +const ( + AibiDashboardEmbeddingAccessPolicy_AccessPolicyType_Unspecified AibiDashboardEmbeddingAccessPolicy_AccessPolicyType = "" + AibiDashboardEmbeddingAccessPolicy_AccessPolicyType_AllowAllDomains AibiDashboardEmbeddingAccessPolicy_AccessPolicyType = "ALLOW_ALL_DOMAINS" + AibiDashboardEmbeddingAccessPolicy_AccessPolicyType_AllowApprovedDomains AibiDashboardEmbeddingAccessPolicy_AccessPolicyType = "ALLOW_APPROVED_DOMAINS" + AibiDashboardEmbeddingAccessPolicy_AccessPolicyType_DenyAllDomains AibiDashboardEmbeddingAccessPolicy_AccessPolicyType = "DENY_ALL_DOMAINS" +) + +type ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek string + +const ( + ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek_Unspecified ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek = "" + ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek_Monday ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek = "MONDAY" + ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek_Tuesday ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek = "TUESDAY" + ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek_Wednesday ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek = "WEDNESDAY" + ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek_Thursday ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek = "THURSDAY" + ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek_Friday ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek = "FRIDAY" + ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek_Saturday ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek = "SATURDAY" + ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek_Sunday ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek = "SUNDAY" +) + +type ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency string + +const ( + ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency_Unspecified ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency = "" + ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency_FirstOfMonth ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency = "FIRST_OF_MONTH" + ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency_SecondOfMonth ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency = "SECOND_OF_MONTH" + ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency_ThirdOfMonth ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency = "THIRD_OF_MONTH" + ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency_FourthOfMonth ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency = "FOURTH_OF_MONTH" + ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency_FirstAndThirdOfMonth ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency = "FIRST_AND_THIRD_OF_MONTH" + ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency_SecondAndFourthOfMonth ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency = "SECOND_AND_FOURTH_OF_MONTH" + ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency_EveryWeek ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency = "EVERY_WEEK" +) + +type CollaborationPlatformConnectivityMessage_Connectivity string + +const ( + CollaborationPlatformConnectivityMessage_Connectivity_Unspecified CollaborationPlatformConnectivityMessage_Connectivity = "" + CollaborationPlatformConnectivityMessage_Connectivity_AllowAll CollaborationPlatformConnectivityMessage_Connectivity = "ALLOW_ALL" + CollaborationPlatformConnectivityMessage_Connectivity_AllowTeams CollaborationPlatformConnectivityMessage_Connectivity = "ALLOW_TEAMS" + CollaborationPlatformConnectivityMessage_Connectivity_AllowSlack CollaborationPlatformConnectivityMessage_Connectivity = "ALLOW_SLACK" + CollaborationPlatformConnectivityMessage_Connectivity_DenyAll CollaborationPlatformConnectivityMessage_Connectivity = "DENY_ALL" +) + +// ON: Grants all users in all workspaces access to the Personal Compute default +// policy, allowing all users to create single-machine compute resources. +// DELEGATE: Moves access control for the Personal Compute default policy to +// individual workspaces and requires a workspace’s users or groups to be +// added to the ACLs of that workspace’s Personal Compute default policy +// before they will be able to create compute resources through that policy. +type PersonalComputeMessage_PersonalComputeMessageEnum string + +const ( + PersonalComputeMessage_PersonalComputeMessageEnum_Unspecified PersonalComputeMessage_PersonalComputeMessageEnum = "" + PersonalComputeMessage_PersonalComputeMessageEnum_On PersonalComputeMessage_PersonalComputeMessageEnum = "ON" + PersonalComputeMessage_PersonalComputeMessageEnum_Delegate PersonalComputeMessage_PersonalComputeMessageEnum = "DELEGATE" +) + +type RestrictWorkspaceAdminsMessage_Status string + +const ( + RestrictWorkspaceAdminsMessage_Status_Unspecified RestrictWorkspaceAdminsMessage_Status = "" + // Default value for existing workspaces Allows WS admins to create OBO tokens + // for all SPs in the workspace without explicit permissions. + RestrictWorkspaceAdminsMessage_Status_AllowAll RestrictWorkspaceAdminsMessage_Status = "ALLOW_ALL" + // Default value for new workspaces Restrict WS admins to create OBO tokens for + // SPs in the workspace unless corresponding permissions are provided + RestrictWorkspaceAdminsMessage_Status_RestrictTokensAndJobRunAs RestrictWorkspaceAdminsMessage_Status = "RESTRICT_TOKENS_AND_JOB_RUN_AS" +) + +type AibiDashboardEmbeddingAccessPolicy struct { + AccessPolicyType AibiDashboardEmbeddingAccessPolicy_AccessPolicyType +} + +type AibiDashboardEmbeddingApprovedDomains struct { + ApprovedDomains []string +} + +type AllowedAppsUserApiScopesMessage struct { + AllowedScopes []string +} + +type BooleanMessage struct { + Value *bool +} + +type ClusterAutoRestartMessage struct { + Enabled *bool + CanToggle *bool + MaintenanceWindow *ClusterAutoRestartMessage_MaintenanceWindow + EnablementDetails *ClusterAutoRestartMessage_EnablementDetails + RestartEvenIfNoUpdatesAvailable *bool +} + +// Contains an information about the enablement status judging (e.g. whether the +// enterprise tier is enabled) This is only additional information that MUST NOT +// be used to decide whether the setting is enabled or not. This is intended to +// use only for purposes like showing an error message to the customer with the +// additional details. For example, using these details we can check why exactly +// the feature is disabled for this customer.. +type ClusterAutoRestartMessage_EnablementDetails struct { + // The feature is unavailable if the customer doesn't have enterprise tier + UnavailableForNonEnterpriseTier *bool + // The feature is unavailable if the corresponding entitlement disabled (see + // getShieldEntitlementEnable) + UnavailableForDisabledEntitlement *bool + // The feature is force enabled if compliance mode is active + ForcedForComplianceMode *bool +} + +type ClusterAutoRestartMessage_MaintenanceWindow struct { + WeekDayBasedSchedule *ClusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedSchedule +} + +type ClusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedSchedule struct { + Frequency ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency + DayOfWeek ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek + WindowStartTime *ClusterAutoRestartMessage_MaintenanceWindow_WindowStartTime +} + +type ClusterAutoRestartMessage_MaintenanceWindow_WindowStartTime struct { + Hours *int + Minutes *int +} + +// Controls which external collaboration platforms (Slack, Microsoft Teams) can +// connect to a workspace. Defaults to ALLOW_ALL.. +type CollaborationPlatformConnectivityMessage struct { + Connectivity CollaborationPlatformConnectivityMessage_Connectivity +} + +type GetPublicAccountSettingRequest struct { + AccountId *string + Name *string +} + +type GetPublicAccountUserPreferenceRequest struct { + // account ID of the account being managed. + AccountId *string + // User ID of the user whose setting is being retrieved. + UserId *string + // User Setting name. + Name *string +} + +type GetPublicWorkspaceSettingRequest struct { + // Name of the setting + Name *string +} + +type IntegerMessage struct { + Value *int +} + +type ListAccountSettingsMetadataRequest struct { + // account ID of the account being managed. + AccountId *string + // The maximum number of settings to return. The service may return fewer than + // this value. If unspecified, at most 200 settings will be returned. The + // maximum value is 1000; values above 1000 will be coerced to 1000. + PageSize *int + // A page token, received from a previous `ListAccountSettingsMetadataRequest` + // call. Provide this to retrieve the subsequent page. + // + // When paginating, all other parameters provided to + // `ListAccountSettingsMetadataRequest` must match the call that provided the + // page token. + PageToken *string +} + +type ListAccountSettingsMetadataResponse struct { + // List of all settings available via public APIs and their metadata + SettingsMetadata []SettingsMetadata + // A token that can be sent as `page_token` to retrieve the next page. If this + // field is omitted, there are no subsequent pages. + NextPageToken *string +} + +type ListAccountUserPreferencesMetadataRequest struct { + // account ID of the account being managed. + AccountId *string + // User ID of the user whose settings metadata is being retrieved. + UserId *string + // The maximum number of settings to return. The service may return fewer than + // this value. If unspecified, at most 200 settings will be returned. The + // maximum value is 1000; values above 1000 will be coerced to 1000. + PageSize *int + // A page token, received from a previous + // `ListAccountUserPreferencesMetadataRequest` call. Provide this to retrieve + // the subsequent page. + // + // When paginating, all other parameters provided to + // `ListAccountUserPreferencesMetadataRequest` must match the call that provided + // the page token. + PageToken *string +} + +type ListAccountUserPreferencesMetadataResponse struct { + // List of all settings available via public APIs and their metadata + SettingsMetadata []SettingsMetadata + // A token that can be sent as `page_token` to retrieve the next page. If this + // field is omitted, there are no subsequent pages. + NextPageToken *string +} + +type ListWorkspaceSettingsMetadataRequest struct { + // The maximum number of settings to return. The service may return fewer than + // this value. If unspecified, at most 200 settings will be returned. The + // maximum value is 1000; values above 1000 will be coerced to 1000. + PageSize *int + // A page token, received from a previous `ListWorkspaceSettingsMetadataRequest` + // call. Provide this to retrieve the subsequent page. + // + // When paginating, all other parameters provided to + // `ListWorkspaceSettingsMetadataRequest` must match the call that provided the + // page token. + PageToken *string +} + +type ListWorkspaceSettingsMetadataResponse struct { + // List of all settings available via public APIs and their metadata + SettingsMetadata []SettingsMetadata + // A token that can be sent as `page_token` to retrieve the next page. If this + // field is omitted, there are no subsequent pages. + NextPageToken *string +} + +type OperationalEmailCustomRecipientMessage struct { + Email *string +} + +type PatchPublicAccountSettingRequest struct { + // account ID of the account being managed. + AccountId *string + Name *string + Setting *Setting +} + +type PatchPublicAccountUserPreferenceRequest struct { + // account ID of the account being managed. + AccountId *string + // User ID of the user whose setting is being updated. + UserId *string + Name *string + Setting *UserPreference +} + +type PatchPublicWorkspaceSettingRequest struct { + // Name of the setting + Name *string + Setting *Setting +} + +type PersonalComputeMessage struct { + Value PersonalComputeMessage_PersonalComputeMessageEnum +} + +type RestrictWorkspaceAdminsMessage struct { + Status RestrictWorkspaceAdminsMessage_Status + // When true, workspace admins cannot create governance tags. ALLOW_ALL status + // does not override this; they are independent. + DisableGovTagCreation *bool +} + +type Setting struct { + // Name of the setting. + Name *string + // New fields should be added before the oneof below - unless it's a new Setting + // value message, in that case it needs to be defined in the oneof below. The + // user-set value that goes into storage + Value isSetting_Value + // New fields should be added before the oneof below - unless it's a new Setting + // value message, in that case it needs to be defined in the oneof below. The + // final effective value from server as per the policy evaluation. + EffectiveValue isSetting_EffectiveValue +} + +type isSetting_Value interface { + isSetting_Value() +} + +// Setting_Value_BooleanVal selects BooleanVal for Setting.Value. +// Setting value for boolean type setting. This is the setting value set by +// consumers, check effective_boolean_val for final setting value. +type Setting_Value_BooleanVal struct { + BooleanVal BooleanMessage +} + +func (*Setting_Value_BooleanVal) isSetting_Value() {} + +// Setting_Value_StringVal selects StringVal for Setting.Value. +// Setting value for string type setting. This is the setting value set by +// consumers, check effective_string_val for final setting value. +type Setting_Value_StringVal struct { + StringVal StringMessage +} + +func (*Setting_Value_StringVal) isSetting_Value() {} + +// Setting_Value_IntegerVal selects IntegerVal for Setting.Value. +// Setting value for integer type setting. This is the setting value set by +// consumers, check effective_integer_val for final setting value. +type Setting_Value_IntegerVal struct { + IntegerVal IntegerMessage +} + +func (*Setting_Value_IntegerVal) isSetting_Value() {} + +// Setting_Value_AutomaticClusterUpdateWorkspace selects AutomaticClusterUpdateWorkspace for Setting.Value. +// Setting value for automatic_cluster_update_workspace setting. This is the +// setting value set by consumers, check +// effective_automatic_cluster_update_workspace for final setting value. +type Setting_Value_AutomaticClusterUpdateWorkspace struct { + AutomaticClusterUpdateWorkspace ClusterAutoRestartMessage +} + +func (*Setting_Value_AutomaticClusterUpdateWorkspace) isSetting_Value() {} + +// Setting_Value_AibiDashboardEmbeddingApprovedDomains selects AibiDashboardEmbeddingApprovedDomains for Setting.Value. +// Setting value for aibi_dashboard_embedding_approved_domains setting. This is +// the setting value set by consumers, check +// effective_aibi_dashboard_embedding_approved_domains for final setting value. +type Setting_Value_AibiDashboardEmbeddingApprovedDomains struct { + AibiDashboardEmbeddingApprovedDomains AibiDashboardEmbeddingApprovedDomains +} + +func (*Setting_Value_AibiDashboardEmbeddingApprovedDomains) isSetting_Value() {} + +// Setting_Value_AibiDashboardEmbeddingAccessPolicy selects AibiDashboardEmbeddingAccessPolicy for Setting.Value. +// Setting value for aibi_dashboard_embedding_access_policy setting. This is the +// setting value set by consumers, check +// effective_aibi_dashboard_embedding_access_policy for final setting value. +type Setting_Value_AibiDashboardEmbeddingAccessPolicy struct { + AibiDashboardEmbeddingAccessPolicy AibiDashboardEmbeddingAccessPolicy +} + +func (*Setting_Value_AibiDashboardEmbeddingAccessPolicy) isSetting_Value() {} + +// Setting_Value_RestrictWorkspaceAdmins selects RestrictWorkspaceAdmins for Setting.Value. +// Setting value for restrict_workspace_admins setting. This is the setting +// value set by consumers, check effective_restrict_workspace_admins for final +// setting value. +type Setting_Value_RestrictWorkspaceAdmins struct { + RestrictWorkspaceAdmins RestrictWorkspaceAdminsMessage +} + +func (*Setting_Value_RestrictWorkspaceAdmins) isSetting_Value() {} + +// Setting_Value_PersonalCompute selects PersonalCompute for Setting.Value. +// Setting value for personal_compute setting. This is the setting value set by +// consumers, check effective_personal_compute for final setting value. +type Setting_Value_PersonalCompute struct { + PersonalCompute PersonalComputeMessage +} + +func (*Setting_Value_PersonalCompute) isSetting_Value() {} + +// Setting_Value_AllowedAppsUserApiScopes selects AllowedAppsUserApiScopes for Setting.Value. +// Setting value for allowed_apps_user_api_scopes setting. This is the setting +// value set by consumers, check effective_allowed_apps_user_api_scopes for +// final setting value. +type Setting_Value_AllowedAppsUserApiScopes struct { + AllowedAppsUserApiScopes AllowedAppsUserApiScopesMessage +} + +func (*Setting_Value_AllowedAppsUserApiScopes) isSetting_Value() {} + +// Setting_Value_OperationalEmailCustomRecipient selects OperationalEmailCustomRecipient for Setting.Value. +// Setting value for operational_email_custom_recipient setting. This is the +// setting value set by consumers, check +// effective_operational_email_custom_recipient for final setting value. +type Setting_Value_OperationalEmailCustomRecipient struct { + OperationalEmailCustomRecipient OperationalEmailCustomRecipientMessage +} + +func (*Setting_Value_OperationalEmailCustomRecipient) isSetting_Value() {} + +// Setting_Value_CollaborationPlatformConnectivity selects CollaborationPlatformConnectivity for Setting.Value. +// Setting value for collaboration_platform_connectivity setting. This is the +// setting value set by consumers, check +// effective_collaboration_platform_connectivity for final setting value. +type Setting_Value_CollaborationPlatformConnectivity struct { + CollaborationPlatformConnectivity CollaborationPlatformConnectivityMessage +} + +func (*Setting_Value_CollaborationPlatformConnectivity) isSetting_Value() {} + +type isSetting_EffectiveValue interface { + isSetting_EffectiveValue() +} + +// Setting_EffectiveValue_EffectiveBooleanVal selects EffectiveBooleanVal for Setting.EffectiveValue. +// Effective setting value for boolean type setting. This is the final effective +// value of setting. To set a value use boolean_val. +type Setting_EffectiveValue_EffectiveBooleanVal struct { + EffectiveBooleanVal BooleanMessage +} + +func (*Setting_EffectiveValue_EffectiveBooleanVal) isSetting_EffectiveValue() {} + +// Setting_EffectiveValue_EffectiveStringVal selects EffectiveStringVal for Setting.EffectiveValue. +// Effective setting value for string type setting. This is the final effective +// value of setting. To set a value use string_val. +type Setting_EffectiveValue_EffectiveStringVal struct { + EffectiveStringVal StringMessage +} + +func (*Setting_EffectiveValue_EffectiveStringVal) isSetting_EffectiveValue() {} + +// Setting_EffectiveValue_EffectiveIntegerVal selects EffectiveIntegerVal for Setting.EffectiveValue. +// Effective setting value for integer type setting. This is the final effective +// value of setting. To set a value use integer_val. +type Setting_EffectiveValue_EffectiveIntegerVal struct { + EffectiveIntegerVal IntegerMessage +} + +func (*Setting_EffectiveValue_EffectiveIntegerVal) isSetting_EffectiveValue() {} + +// Setting_EffectiveValue_EffectiveAutomaticClusterUpdateWorkspace selects EffectiveAutomaticClusterUpdateWorkspace for Setting.EffectiveValue. +// Effective setting value for automatic_cluster_update_workspace setting. This +// is the final effective value of setting. To set a value use +// automatic_cluster_update_workspace. +type Setting_EffectiveValue_EffectiveAutomaticClusterUpdateWorkspace struct { + EffectiveAutomaticClusterUpdateWorkspace ClusterAutoRestartMessage +} + +func (*Setting_EffectiveValue_EffectiveAutomaticClusterUpdateWorkspace) isSetting_EffectiveValue() {} + +// Setting_EffectiveValue_EffectiveAibiDashboardEmbeddingApprovedDomains selects EffectiveAibiDashboardEmbeddingApprovedDomains for Setting.EffectiveValue. +// Effective setting value for aibi_dashboard_embedding_approved_domains +// setting. This is the final effective value of setting. To set a value use +// aibi_dashboard_embedding_approved_domains. +type Setting_EffectiveValue_EffectiveAibiDashboardEmbeddingApprovedDomains struct { + EffectiveAibiDashboardEmbeddingApprovedDomains AibiDashboardEmbeddingApprovedDomains +} + +func (*Setting_EffectiveValue_EffectiveAibiDashboardEmbeddingApprovedDomains) isSetting_EffectiveValue() { +} + +// Setting_EffectiveValue_EffectiveAibiDashboardEmbeddingAccessPolicy selects EffectiveAibiDashboardEmbeddingAccessPolicy for Setting.EffectiveValue. +// Effective setting value for aibi_dashboard_embedding_access_policy setting. +// This is the final effective value of setting. To set a value use +// aibi_dashboard_embedding_access_policy. +type Setting_EffectiveValue_EffectiveAibiDashboardEmbeddingAccessPolicy struct { + EffectiveAibiDashboardEmbeddingAccessPolicy AibiDashboardEmbeddingAccessPolicy +} + +func (*Setting_EffectiveValue_EffectiveAibiDashboardEmbeddingAccessPolicy) isSetting_EffectiveValue() { +} + +// Setting_EffectiveValue_EffectiveRestrictWorkspaceAdmins selects EffectiveRestrictWorkspaceAdmins for Setting.EffectiveValue. +// Effective setting value for restrict_workspace_admins setting. This is the +// final effective value of setting. To set a value use +// restrict_workspace_admins. +type Setting_EffectiveValue_EffectiveRestrictWorkspaceAdmins struct { + EffectiveRestrictWorkspaceAdmins RestrictWorkspaceAdminsMessage +} + +func (*Setting_EffectiveValue_EffectiveRestrictWorkspaceAdmins) isSetting_EffectiveValue() {} + +// Setting_EffectiveValue_EffectivePersonalCompute selects EffectivePersonalCompute for Setting.EffectiveValue. +// Effective setting value for personal_compute setting. This is the final +// effective value of setting. To set a value use personal_compute. +type Setting_EffectiveValue_EffectivePersonalCompute struct { + EffectivePersonalCompute PersonalComputeMessage +} + +func (*Setting_EffectiveValue_EffectivePersonalCompute) isSetting_EffectiveValue() {} + +// Setting_EffectiveValue_EffectiveAllowedAppsUserApiScopes selects EffectiveAllowedAppsUserApiScopes for Setting.EffectiveValue. +// Effective setting value for allowed_apps_user_api_scopes setting. This is the +// final effective value of setting. To set a value use +// allowed_apps_user_api_scopes. +type Setting_EffectiveValue_EffectiveAllowedAppsUserApiScopes struct { + EffectiveAllowedAppsUserApiScopes AllowedAppsUserApiScopesMessage +} + +func (*Setting_EffectiveValue_EffectiveAllowedAppsUserApiScopes) isSetting_EffectiveValue() {} + +// Setting_EffectiveValue_EffectiveOperationalEmailCustomRecipient selects EffectiveOperationalEmailCustomRecipient for Setting.EffectiveValue. +// Effective setting value for operational_email_custom_recipient setting. This +// is the final effective value of setting. To set a value use +// operational_email_custom_recipient. +type Setting_EffectiveValue_EffectiveOperationalEmailCustomRecipient struct { + EffectiveOperationalEmailCustomRecipient OperationalEmailCustomRecipientMessage +} + +func (*Setting_EffectiveValue_EffectiveOperationalEmailCustomRecipient) isSetting_EffectiveValue() {} + +// Setting_EffectiveValue_EffectiveCollaborationPlatformConnectivity selects EffectiveCollaborationPlatformConnectivity for Setting.EffectiveValue. +// Effective setting value for collaboration_platform_connectivity setting. This +// is the final effective value of setting. To set a value use +// collaboration_platform_connectivity. +type Setting_EffectiveValue_EffectiveCollaborationPlatformConnectivity struct { + EffectiveCollaborationPlatformConnectivity CollaborationPlatformConnectivityMessage +} + +func (*Setting_EffectiveValue_EffectiveCollaborationPlatformConnectivity) isSetting_EffectiveValue() { +} + +type SettingsMetadata struct { + // Name of the setting. + Name *string + // Setting description for what this setting controls + Description *string + // Sample message depicting the type of the setting. To set this setting, the + // value sent must match this type. + Type *string + // Link to databricks documentation for the setting + DocsLink *string + // Preview phase for feature preview settings. This field is not set for + // non-preview settings. + PreviewPhase PreviewPhase + // Human-readable display name for the setting or feature preview. This field + // may be unset if no display name is available. + DisplayName *string +} + +type StringMessage struct { + // Represents a generic string value. + Value *string +} + +// User Preference represents a user-specific setting scoped to an individual +// user within an account. Unlike workspace or account settings that apply to +// all users, user preferences allow personal customization (e.g., UI theme, +// editor preferences) without affecting other users.. +type UserPreference struct { + // Name of the setting. + Name *string + // User ID of the user. + UserId *string + // New fields should be added before the oneof below - unless it's a new Setting + // value message, in that case it needs to be defined in the oneof below. The + // user-set value that goes into storage. + Value isUserPreference_Value + // New fields should be added before the oneof below - unless it's a new User + // Preference value message, in that case it needs to be defined in the oneof + // below. The final effective value from server as per the policy evaluation. + EffectiveValue isUserPreference_EffectiveValue +} + +type isUserPreference_Value interface { + isUserPreference_Value() +} + +// UserPreference_Value_BooleanVal selects BooleanVal for UserPreference.Value. +type UserPreference_Value_BooleanVal struct { + BooleanVal BooleanMessage +} + +func (*UserPreference_Value_BooleanVal) isUserPreference_Value() {} + +// UserPreference_Value_StringVal selects StringVal for UserPreference.Value. +type UserPreference_Value_StringVal struct { + StringVal StringMessage +} + +func (*UserPreference_Value_StringVal) isUserPreference_Value() {} + +type isUserPreference_EffectiveValue interface { + isUserPreference_EffectiveValue() +} + +// UserPreference_EffectiveValue_EffectiveBooleanVal selects EffectiveBooleanVal for UserPreference.EffectiveValue. +type UserPreference_EffectiveValue_EffectiveBooleanVal struct { + EffectiveBooleanVal BooleanMessage +} + +func (*UserPreference_EffectiveValue_EffectiveBooleanVal) isUserPreference_EffectiveValue() {} + +// UserPreference_EffectiveValue_EffectiveStringVal selects EffectiveStringVal for UserPreference.EffectiveValue. +type UserPreference_EffectiveValue_EffectiveStringVal struct { + EffectiveStringVal StringMessage +} + +func (*UserPreference_EffectiveValue_EffectiveStringVal) isUserPreference_EffectiveValue() {} diff --git a/settings/v2/wire.go b/settings/v2/wire.go new file mode 100755 index 0000000..6629cb8 --- /dev/null +++ b/settings/v2/wire.go @@ -0,0 +1,1227 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package settings + +import ( + "fmt" +) + +type aibiDashboardEmbeddingAccessPolicyWire struct { + AccessPolicyType AibiDashboardEmbeddingAccessPolicy_AccessPolicyType `json:"access_policy_type,omitempty"` +} + +func aibiDashboardEmbeddingAccessPolicyToWire(v *AibiDashboardEmbeddingAccessPolicy) (*aibiDashboardEmbeddingAccessPolicyWire, error) { + if v == nil { + return nil, nil + } + return &aibiDashboardEmbeddingAccessPolicyWire{ + AccessPolicyType: v.AccessPolicyType, + }, nil +} + +func aibiDashboardEmbeddingAccessPolicyFromWire(w *aibiDashboardEmbeddingAccessPolicyWire) (*AibiDashboardEmbeddingAccessPolicy, error) { + if w == nil { + return nil, nil + } + return &AibiDashboardEmbeddingAccessPolicy{ + AccessPolicyType: w.AccessPolicyType, + }, nil +} + +type aibiDashboardEmbeddingApprovedDomainsWire struct { + ApprovedDomains []string `json:"approved_domains,omitempty"` +} + +func aibiDashboardEmbeddingApprovedDomainsToWire(v *AibiDashboardEmbeddingApprovedDomains) (*aibiDashboardEmbeddingApprovedDomainsWire, error) { + if v == nil { + return nil, nil + } + return &aibiDashboardEmbeddingApprovedDomainsWire{ + ApprovedDomains: v.ApprovedDomains, + }, nil +} + +func aibiDashboardEmbeddingApprovedDomainsFromWire(w *aibiDashboardEmbeddingApprovedDomainsWire) (*AibiDashboardEmbeddingApprovedDomains, error) { + if w == nil { + return nil, nil + } + return &AibiDashboardEmbeddingApprovedDomains{ + ApprovedDomains: w.ApprovedDomains, + }, nil +} + +type allowedAppsUserApiScopesMessageWire struct { + AllowedScopes []string `json:"allowed_scopes,omitempty"` +} + +func allowedAppsUserApiScopesMessageToWire(v *AllowedAppsUserApiScopesMessage) (*allowedAppsUserApiScopesMessageWire, error) { + if v == nil { + return nil, nil + } + return &allowedAppsUserApiScopesMessageWire{ + AllowedScopes: v.AllowedScopes, + }, nil +} + +func allowedAppsUserApiScopesMessageFromWire(w *allowedAppsUserApiScopesMessageWire) (*AllowedAppsUserApiScopesMessage, error) { + if w == nil { + return nil, nil + } + return &AllowedAppsUserApiScopesMessage{ + AllowedScopes: w.AllowedScopes, + }, nil +} + +type booleanMessageWire struct { + Value *bool `json:"value,omitempty"` +} + +func booleanMessageToWire(v *BooleanMessage) (*booleanMessageWire, error) { + if v == nil { + return nil, nil + } + return &booleanMessageWire{ + Value: v.Value, + }, nil +} + +func booleanMessageFromWire(w *booleanMessageWire) (*BooleanMessage, error) { + if w == nil { + return nil, nil + } + return &BooleanMessage{ + Value: w.Value, + }, nil +} + +type clusterAutoRestartMessageWire struct { + Enabled *bool `json:"enabled,omitempty"` + CanToggle *bool `json:"can_toggle,omitempty"` + MaintenanceWindow *clusterAutoRestartMessage_MaintenanceWindowWire `json:"maintenance_window,omitempty"` + EnablementDetails *clusterAutoRestartMessage_EnablementDetailsWire `json:"enablement_details,omitempty"` + RestartEvenIfNoUpdatesAvailable *bool `json:"restart_even_if_no_updates_available,omitempty"` +} + +func clusterAutoRestartMessageToWire(v *ClusterAutoRestartMessage) (*clusterAutoRestartMessageWire, error) { + if v == nil { + return nil, nil + } + maintenanceWindowWireValue, err := clusterAutoRestartMessage_MaintenanceWindowToWire(v.MaintenanceWindow) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAutoRestartMessage.MaintenanceWindow", err) + } + enablementDetailsWireValue, err := clusterAutoRestartMessage_EnablementDetailsToWire(v.EnablementDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAutoRestartMessage.EnablementDetails", err) + } + return &clusterAutoRestartMessageWire{ + Enabled: v.Enabled, + CanToggle: v.CanToggle, + MaintenanceWindow: maintenanceWindowWireValue, + EnablementDetails: enablementDetailsWireValue, + RestartEvenIfNoUpdatesAvailable: v.RestartEvenIfNoUpdatesAvailable, + }, nil +} + +func clusterAutoRestartMessageFromWire(w *clusterAutoRestartMessageWire) (*ClusterAutoRestartMessage, error) { + if w == nil { + return nil, nil + } + maintenanceWindowPublicValue, err := clusterAutoRestartMessage_MaintenanceWindowFromWire(w.MaintenanceWindow) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAutoRestartMessage.MaintenanceWindow", err) + } + enablementDetailsPublicValue, err := clusterAutoRestartMessage_EnablementDetailsFromWire(w.EnablementDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAutoRestartMessage.EnablementDetails", err) + } + return &ClusterAutoRestartMessage{ + Enabled: w.Enabled, + CanToggle: w.CanToggle, + MaintenanceWindow: maintenanceWindowPublicValue, + EnablementDetails: enablementDetailsPublicValue, + RestartEvenIfNoUpdatesAvailable: w.RestartEvenIfNoUpdatesAvailable, + }, nil +} + +type clusterAutoRestartMessage_EnablementDetailsWire struct { + UnavailableForNonEnterpriseTier *bool `json:"unavailable_for_non_enterprise_tier,omitempty"` + UnavailableForDisabledEntitlement *bool `json:"unavailable_for_disabled_entitlement,omitempty"` + ForcedForComplianceMode *bool `json:"forced_for_compliance_mode,omitempty"` +} + +func clusterAutoRestartMessage_EnablementDetailsToWire(v *ClusterAutoRestartMessage_EnablementDetails) (*clusterAutoRestartMessage_EnablementDetailsWire, error) { + if v == nil { + return nil, nil + } + return &clusterAutoRestartMessage_EnablementDetailsWire{ + UnavailableForNonEnterpriseTier: v.UnavailableForNonEnterpriseTier, + UnavailableForDisabledEntitlement: v.UnavailableForDisabledEntitlement, + ForcedForComplianceMode: v.ForcedForComplianceMode, + }, nil +} + +func clusterAutoRestartMessage_EnablementDetailsFromWire(w *clusterAutoRestartMessage_EnablementDetailsWire) (*ClusterAutoRestartMessage_EnablementDetails, error) { + if w == nil { + return nil, nil + } + return &ClusterAutoRestartMessage_EnablementDetails{ + UnavailableForNonEnterpriseTier: w.UnavailableForNonEnterpriseTier, + UnavailableForDisabledEntitlement: w.UnavailableForDisabledEntitlement, + ForcedForComplianceMode: w.ForcedForComplianceMode, + }, nil +} + +type clusterAutoRestartMessage_MaintenanceWindowWire struct { + WeekDayBasedSchedule *clusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedScheduleWire `json:"week_day_based_schedule,omitempty"` +} + +func clusterAutoRestartMessage_MaintenanceWindowToWire(v *ClusterAutoRestartMessage_MaintenanceWindow) (*clusterAutoRestartMessage_MaintenanceWindowWire, error) { + if v == nil { + return nil, nil + } + weekDayBasedScheduleWireValue, err := clusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedScheduleToWire(v.WeekDayBasedSchedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAutoRestartMessage_MaintenanceWindow.WeekDayBasedSchedule", err) + } + return &clusterAutoRestartMessage_MaintenanceWindowWire{ + WeekDayBasedSchedule: weekDayBasedScheduleWireValue, + }, nil +} + +func clusterAutoRestartMessage_MaintenanceWindowFromWire(w *clusterAutoRestartMessage_MaintenanceWindowWire) (*ClusterAutoRestartMessage_MaintenanceWindow, error) { + if w == nil { + return nil, nil + } + weekDayBasedSchedulePublicValue, err := clusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedScheduleFromWire(w.WeekDayBasedSchedule) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAutoRestartMessage_MaintenanceWindow.WeekDayBasedSchedule", err) + } + return &ClusterAutoRestartMessage_MaintenanceWindow{ + WeekDayBasedSchedule: weekDayBasedSchedulePublicValue, + }, nil +} + +type clusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedScheduleWire struct { + Frequency ClusterAutoRestartMessage_MaintenanceWindow_WeekDayFrequency `json:"frequency,omitempty"` + DayOfWeek ClusterAutoRestartMessage_MaintenanceWindow_DayOfWeek `json:"day_of_week,omitempty"` + WindowStartTime *clusterAutoRestartMessage_MaintenanceWindow_WindowStartTimeWire `json:"window_start_time,omitempty"` +} + +func clusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedScheduleToWire(v *ClusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedSchedule) (*clusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedScheduleWire, error) { + if v == nil { + return nil, nil + } + windowStartTimeWireValue, err := clusterAutoRestartMessage_MaintenanceWindow_WindowStartTimeToWire(v.WindowStartTime) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedSchedule.WindowStartTime", err) + } + return &clusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedScheduleWire{ + Frequency: v.Frequency, + DayOfWeek: v.DayOfWeek, + WindowStartTime: windowStartTimeWireValue, + }, nil +} + +func clusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedScheduleFromWire(w *clusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedScheduleWire) (*ClusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedSchedule, error) { + if w == nil { + return nil, nil + } + windowStartTimePublicValue, err := clusterAutoRestartMessage_MaintenanceWindow_WindowStartTimeFromWire(w.WindowStartTime) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ClusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedSchedule.WindowStartTime", err) + } + return &ClusterAutoRestartMessage_MaintenanceWindow_WeekDayBasedSchedule{ + Frequency: w.Frequency, + DayOfWeek: w.DayOfWeek, + WindowStartTime: windowStartTimePublicValue, + }, nil +} + +type clusterAutoRestartMessage_MaintenanceWindow_WindowStartTimeWire struct { + Hours *int `json:"hours,omitempty"` + Minutes *int `json:"minutes,omitempty"` +} + +func clusterAutoRestartMessage_MaintenanceWindow_WindowStartTimeToWire(v *ClusterAutoRestartMessage_MaintenanceWindow_WindowStartTime) (*clusterAutoRestartMessage_MaintenanceWindow_WindowStartTimeWire, error) { + if v == nil { + return nil, nil + } + return &clusterAutoRestartMessage_MaintenanceWindow_WindowStartTimeWire{ + Hours: v.Hours, + Minutes: v.Minutes, + }, nil +} + +func clusterAutoRestartMessage_MaintenanceWindow_WindowStartTimeFromWire(w *clusterAutoRestartMessage_MaintenanceWindow_WindowStartTimeWire) (*ClusterAutoRestartMessage_MaintenanceWindow_WindowStartTime, error) { + if w == nil { + return nil, nil + } + return &ClusterAutoRestartMessage_MaintenanceWindow_WindowStartTime{ + Hours: w.Hours, + Minutes: w.Minutes, + }, nil +} + +type collaborationPlatformConnectivityMessageWire struct { + Connectivity CollaborationPlatformConnectivityMessage_Connectivity `json:"connectivity,omitempty"` +} + +func collaborationPlatformConnectivityMessageToWire(v *CollaborationPlatformConnectivityMessage) (*collaborationPlatformConnectivityMessageWire, error) { + if v == nil { + return nil, nil + } + return &collaborationPlatformConnectivityMessageWire{ + Connectivity: v.Connectivity, + }, nil +} + +func collaborationPlatformConnectivityMessageFromWire(w *collaborationPlatformConnectivityMessageWire) (*CollaborationPlatformConnectivityMessage, error) { + if w == nil { + return nil, nil + } + return &CollaborationPlatformConnectivityMessage{ + Connectivity: w.Connectivity, + }, nil +} + +type integerMessageWire struct { + Value *int `json:"value,omitempty"` +} + +func integerMessageToWire(v *IntegerMessage) (*integerMessageWire, error) { + if v == nil { + return nil, nil + } + return &integerMessageWire{ + Value: v.Value, + }, nil +} + +func integerMessageFromWire(w *integerMessageWire) (*IntegerMessage, error) { + if w == nil { + return nil, nil + } + return &IntegerMessage{ + Value: w.Value, + }, nil +} + +type listAccountSettingsMetadataRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listAccountSettingsMetadataRequestToWire(v *ListAccountSettingsMetadataRequest) (*listAccountSettingsMetadataRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAccountSettingsMetadataRequestWire{ + AccountId: v.AccountId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listAccountSettingsMetadataResponseWire struct { + SettingsMetadata []settingsMetadataWire `json:"settings_metadata,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listAccountSettingsMetadataResponseFromWire(w *listAccountSettingsMetadataResponseWire) (*ListAccountSettingsMetadataResponse, error) { + if w == nil { + return nil, nil + } + settingsMetadataPublicValue, err := convertSlice(w.SettingsMetadata, settingsMetadataFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAccountSettingsMetadataResponse.SettingsMetadata", err) + } + return &ListAccountSettingsMetadataResponse{ + SettingsMetadata: settingsMetadataPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listAccountUserPreferencesMetadataRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + UserId *string `json:"user_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listAccountUserPreferencesMetadataRequestToWire(v *ListAccountUserPreferencesMetadataRequest) (*listAccountUserPreferencesMetadataRequestWire, error) { + if v == nil { + return nil, nil + } + return &listAccountUserPreferencesMetadataRequestWire{ + AccountId: v.AccountId, + UserId: v.UserId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listAccountUserPreferencesMetadataResponseWire struct { + SettingsMetadata []settingsMetadataWire `json:"settings_metadata,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listAccountUserPreferencesMetadataResponseFromWire(w *listAccountUserPreferencesMetadataResponseWire) (*ListAccountUserPreferencesMetadataResponse, error) { + if w == nil { + return nil, nil + } + settingsMetadataPublicValue, err := convertSlice(w.SettingsMetadata, settingsMetadataFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListAccountUserPreferencesMetadataResponse.SettingsMetadata", err) + } + return &ListAccountUserPreferencesMetadataResponse{ + SettingsMetadata: settingsMetadataPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listWorkspaceSettingsMetadataRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listWorkspaceSettingsMetadataRequestToWire(v *ListWorkspaceSettingsMetadataRequest) (*listWorkspaceSettingsMetadataRequestWire, error) { + if v == nil { + return nil, nil + } + return &listWorkspaceSettingsMetadataRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listWorkspaceSettingsMetadataResponseWire struct { + SettingsMetadata []settingsMetadataWire `json:"settings_metadata,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listWorkspaceSettingsMetadataResponseFromWire(w *listWorkspaceSettingsMetadataResponseWire) (*ListWorkspaceSettingsMetadataResponse, error) { + if w == nil { + return nil, nil + } + settingsMetadataPublicValue, err := convertSlice(w.SettingsMetadata, settingsMetadataFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListWorkspaceSettingsMetadataResponse.SettingsMetadata", err) + } + return &ListWorkspaceSettingsMetadataResponse{ + SettingsMetadata: settingsMetadataPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type operationalEmailCustomRecipientMessageWire struct { + Email *string `json:"email,omitempty"` +} + +func operationalEmailCustomRecipientMessageToWire(v *OperationalEmailCustomRecipientMessage) (*operationalEmailCustomRecipientMessageWire, error) { + if v == nil { + return nil, nil + } + return &operationalEmailCustomRecipientMessageWire{ + Email: v.Email, + }, nil +} + +func operationalEmailCustomRecipientMessageFromWire(w *operationalEmailCustomRecipientMessageWire) (*OperationalEmailCustomRecipientMessage, error) { + if w == nil { + return nil, nil + } + return &OperationalEmailCustomRecipientMessage{ + Email: w.Email, + }, nil +} + +type patchPublicAccountSettingRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + Name *string `json:"name,omitempty"` + Setting *settingWire `json:"setting,omitempty"` +} + +func patchPublicAccountSettingRequestToWire(v *PatchPublicAccountSettingRequest) (*patchPublicAccountSettingRequestWire, error) { + if v == nil { + return nil, nil + } + settingWireValue, err := settingToWire(v.Setting) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchPublicAccountSettingRequest.Setting", err) + } + return &patchPublicAccountSettingRequestWire{ + AccountId: v.AccountId, + Name: v.Name, + Setting: settingWireValue, + }, nil +} + +type patchPublicAccountUserPreferenceRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + UserId *string `json:"user_id,omitempty"` + Name *string `json:"name,omitempty"` + Setting *userPreferenceWire `json:"setting,omitempty"` +} + +func patchPublicAccountUserPreferenceRequestToWire(v *PatchPublicAccountUserPreferenceRequest) (*patchPublicAccountUserPreferenceRequestWire, error) { + if v == nil { + return nil, nil + } + settingWireValue, err := userPreferenceToWire(v.Setting) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchPublicAccountUserPreferenceRequest.Setting", err) + } + return &patchPublicAccountUserPreferenceRequestWire{ + AccountId: v.AccountId, + UserId: v.UserId, + Name: v.Name, + Setting: settingWireValue, + }, nil +} + +type patchPublicWorkspaceSettingRequestWire struct { + Name *string `json:"name,omitempty"` + Setting *settingWire `json:"setting,omitempty"` +} + +func patchPublicWorkspaceSettingRequestToWire(v *PatchPublicWorkspaceSettingRequest) (*patchPublicWorkspaceSettingRequestWire, error) { + if v == nil { + return nil, nil + } + settingWireValue, err := settingToWire(v.Setting) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PatchPublicWorkspaceSettingRequest.Setting", err) + } + return &patchPublicWorkspaceSettingRequestWire{ + Name: v.Name, + Setting: settingWireValue, + }, nil +} + +type personalComputeMessageWire struct { + Value PersonalComputeMessage_PersonalComputeMessageEnum `json:"value,omitempty"` +} + +func personalComputeMessageToWire(v *PersonalComputeMessage) (*personalComputeMessageWire, error) { + if v == nil { + return nil, nil + } + return &personalComputeMessageWire{ + Value: v.Value, + }, nil +} + +func personalComputeMessageFromWire(w *personalComputeMessageWire) (*PersonalComputeMessage, error) { + if w == nil { + return nil, nil + } + return &PersonalComputeMessage{ + Value: w.Value, + }, nil +} + +type restrictWorkspaceAdminsMessageWire struct { + Status RestrictWorkspaceAdminsMessage_Status `json:"status,omitempty"` + DisableGovTagCreation *bool `json:"disable_gov_tag_creation,omitempty"` +} + +func restrictWorkspaceAdminsMessageToWire(v *RestrictWorkspaceAdminsMessage) (*restrictWorkspaceAdminsMessageWire, error) { + if v == nil { + return nil, nil + } + return &restrictWorkspaceAdminsMessageWire{ + Status: v.Status, + DisableGovTagCreation: v.DisableGovTagCreation, + }, nil +} + +func restrictWorkspaceAdminsMessageFromWire(w *restrictWorkspaceAdminsMessageWire) (*RestrictWorkspaceAdminsMessage, error) { + if w == nil { + return nil, nil + } + return &RestrictWorkspaceAdminsMessage{ + Status: w.Status, + DisableGovTagCreation: w.DisableGovTagCreation, + }, nil +} + +type settingWire struct { + Name *string `json:"name,omitempty"` + BooleanVal *booleanMessageWire `json:"boolean_val,omitempty"` + StringVal *stringMessageWire `json:"string_val,omitempty"` + IntegerVal *integerMessageWire `json:"integer_val,omitempty"` + AutomaticClusterUpdateWorkspace *clusterAutoRestartMessageWire `json:"automatic_cluster_update_workspace,omitempty"` + AibiDashboardEmbeddingApprovedDomains *aibiDashboardEmbeddingApprovedDomainsWire `json:"aibi_dashboard_embedding_approved_domains,omitempty"` + AibiDashboardEmbeddingAccessPolicy *aibiDashboardEmbeddingAccessPolicyWire `json:"aibi_dashboard_embedding_access_policy,omitempty"` + RestrictWorkspaceAdmins *restrictWorkspaceAdminsMessageWire `json:"restrict_workspace_admins,omitempty"` + PersonalCompute *personalComputeMessageWire `json:"personal_compute,omitempty"` + AllowedAppsUserApiScopes *allowedAppsUserApiScopesMessageWire `json:"allowed_apps_user_api_scopes,omitempty"` + OperationalEmailCustomRecipient *operationalEmailCustomRecipientMessageWire `json:"operational_email_custom_recipient,omitempty"` + CollaborationPlatformConnectivity *collaborationPlatformConnectivityMessageWire `json:"collaboration_platform_connectivity,omitempty"` + EffectiveBooleanVal *booleanMessageWire `json:"effective_boolean_val,omitempty"` + EffectiveStringVal *stringMessageWire `json:"effective_string_val,omitempty"` + EffectiveIntegerVal *integerMessageWire `json:"effective_integer_val,omitempty"` + EffectiveAutomaticClusterUpdateWorkspace *clusterAutoRestartMessageWire `json:"effective_automatic_cluster_update_workspace,omitempty"` + EffectiveAibiDashboardEmbeddingApprovedDomains *aibiDashboardEmbeddingApprovedDomainsWire `json:"effective_aibi_dashboard_embedding_approved_domains,omitempty"` + EffectiveAibiDashboardEmbeddingAccessPolicy *aibiDashboardEmbeddingAccessPolicyWire `json:"effective_aibi_dashboard_embedding_access_policy,omitempty"` + EffectiveRestrictWorkspaceAdmins *restrictWorkspaceAdminsMessageWire `json:"effective_restrict_workspace_admins,omitempty"` + EffectivePersonalCompute *personalComputeMessageWire `json:"effective_personal_compute,omitempty"` + EffectiveAllowedAppsUserApiScopes *allowedAppsUserApiScopesMessageWire `json:"effective_allowed_apps_user_api_scopes,omitempty"` + EffectiveOperationalEmailCustomRecipient *operationalEmailCustomRecipientMessageWire `json:"effective_operational_email_custom_recipient,omitempty"` + EffectiveCollaborationPlatformConnectivity *collaborationPlatformConnectivityMessageWire `json:"effective_collaboration_platform_connectivity,omitempty"` +} + +func settingToWire(v *Setting) (*settingWire, error) { + if v == nil { + return nil, nil + } + var valueBooleanValWire *booleanMessageWire + var valueStringValWire *stringMessageWire + var valueIntegerValWire *integerMessageWire + var valueAutomaticClusterUpdateWorkspaceWire *clusterAutoRestartMessageWire + var valueAibiDashboardEmbeddingApprovedDomainsWire *aibiDashboardEmbeddingApprovedDomainsWire + var valueAibiDashboardEmbeddingAccessPolicyWire *aibiDashboardEmbeddingAccessPolicyWire + var valueRestrictWorkspaceAdminsWire *restrictWorkspaceAdminsMessageWire + var valuePersonalComputeWire *personalComputeMessageWire + var valueAllowedAppsUserApiScopesWire *allowedAppsUserApiScopesMessageWire + var valueOperationalEmailCustomRecipientWire *operationalEmailCustomRecipientMessageWire + var valueCollaborationPlatformConnectivityWire *collaborationPlatformConnectivityMessageWire + switch value := v.Value.(type) { + case nil: + case *Setting_Value_BooleanVal: + if value != nil { + valueBooleanValConverted, err := booleanMessageToWire(&value.BooleanVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.BooleanVal", err) + } + valueBooleanValWire = valueBooleanValConverted + } + case *Setting_Value_StringVal: + if value != nil { + valueStringValConverted, err := stringMessageToWire(&value.StringVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.StringVal", err) + } + valueStringValWire = valueStringValConverted + } + case *Setting_Value_IntegerVal: + if value != nil { + valueIntegerValConverted, err := integerMessageToWire(&value.IntegerVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.IntegerVal", err) + } + valueIntegerValWire = valueIntegerValConverted + } + case *Setting_Value_AutomaticClusterUpdateWorkspace: + if value != nil { + valueAutomaticClusterUpdateWorkspaceConverted, err := clusterAutoRestartMessageToWire(&value.AutomaticClusterUpdateWorkspace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.AutomaticClusterUpdateWorkspace", err) + } + valueAutomaticClusterUpdateWorkspaceWire = valueAutomaticClusterUpdateWorkspaceConverted + } + case *Setting_Value_AibiDashboardEmbeddingApprovedDomains: + if value != nil { + valueAibiDashboardEmbeddingApprovedDomainsConverted, err := aibiDashboardEmbeddingApprovedDomainsToWire(&value.AibiDashboardEmbeddingApprovedDomains) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.AibiDashboardEmbeddingApprovedDomains", err) + } + valueAibiDashboardEmbeddingApprovedDomainsWire = valueAibiDashboardEmbeddingApprovedDomainsConverted + } + case *Setting_Value_AibiDashboardEmbeddingAccessPolicy: + if value != nil { + valueAibiDashboardEmbeddingAccessPolicyConverted, err := aibiDashboardEmbeddingAccessPolicyToWire(&value.AibiDashboardEmbeddingAccessPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.AibiDashboardEmbeddingAccessPolicy", err) + } + valueAibiDashboardEmbeddingAccessPolicyWire = valueAibiDashboardEmbeddingAccessPolicyConverted + } + case *Setting_Value_RestrictWorkspaceAdmins: + if value != nil { + valueRestrictWorkspaceAdminsConverted, err := restrictWorkspaceAdminsMessageToWire(&value.RestrictWorkspaceAdmins) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.RestrictWorkspaceAdmins", err) + } + valueRestrictWorkspaceAdminsWire = valueRestrictWorkspaceAdminsConverted + } + case *Setting_Value_PersonalCompute: + if value != nil { + valuePersonalComputeConverted, err := personalComputeMessageToWire(&value.PersonalCompute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.PersonalCompute", err) + } + valuePersonalComputeWire = valuePersonalComputeConverted + } + case *Setting_Value_AllowedAppsUserApiScopes: + if value != nil { + valueAllowedAppsUserApiScopesConverted, err := allowedAppsUserApiScopesMessageToWire(&value.AllowedAppsUserApiScopes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.AllowedAppsUserApiScopes", err) + } + valueAllowedAppsUserApiScopesWire = valueAllowedAppsUserApiScopesConverted + } + case *Setting_Value_OperationalEmailCustomRecipient: + if value != nil { + valueOperationalEmailCustomRecipientConverted, err := operationalEmailCustomRecipientMessageToWire(&value.OperationalEmailCustomRecipient) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.OperationalEmailCustomRecipient", err) + } + valueOperationalEmailCustomRecipientWire = valueOperationalEmailCustomRecipientConverted + } + case *Setting_Value_CollaborationPlatformConnectivity: + if value != nil { + valueCollaborationPlatformConnectivityConverted, err := collaborationPlatformConnectivityMessageToWire(&value.CollaborationPlatformConnectivity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.CollaborationPlatformConnectivity", err) + } + valueCollaborationPlatformConnectivityWire = valueCollaborationPlatformConnectivityConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Setting.Value", value) + } + var effectiveValueEffectiveBooleanValWire *booleanMessageWire + var effectiveValueEffectiveStringValWire *stringMessageWire + var effectiveValueEffectiveIntegerValWire *integerMessageWire + var effectiveValueEffectiveAutomaticClusterUpdateWorkspaceWire *clusterAutoRestartMessageWire + var effectiveValueEffectiveAibiDashboardEmbeddingApprovedDomainsWire *aibiDashboardEmbeddingApprovedDomainsWire + var effectiveValueEffectiveAibiDashboardEmbeddingAccessPolicyWire *aibiDashboardEmbeddingAccessPolicyWire + var effectiveValueEffectiveRestrictWorkspaceAdminsWire *restrictWorkspaceAdminsMessageWire + var effectiveValueEffectivePersonalComputeWire *personalComputeMessageWire + var effectiveValueEffectiveAllowedAppsUserApiScopesWire *allowedAppsUserApiScopesMessageWire + var effectiveValueEffectiveOperationalEmailCustomRecipientWire *operationalEmailCustomRecipientMessageWire + var effectiveValueEffectiveCollaborationPlatformConnectivityWire *collaborationPlatformConnectivityMessageWire + switch value := v.EffectiveValue.(type) { + case nil: + case *Setting_EffectiveValue_EffectiveBooleanVal: + if value != nil { + effectiveValueEffectiveBooleanValConverted, err := booleanMessageToWire(&value.EffectiveBooleanVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveBooleanVal", err) + } + effectiveValueEffectiveBooleanValWire = effectiveValueEffectiveBooleanValConverted + } + case *Setting_EffectiveValue_EffectiveStringVal: + if value != nil { + effectiveValueEffectiveStringValConverted, err := stringMessageToWire(&value.EffectiveStringVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveStringVal", err) + } + effectiveValueEffectiveStringValWire = effectiveValueEffectiveStringValConverted + } + case *Setting_EffectiveValue_EffectiveIntegerVal: + if value != nil { + effectiveValueEffectiveIntegerValConverted, err := integerMessageToWire(&value.EffectiveIntegerVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveIntegerVal", err) + } + effectiveValueEffectiveIntegerValWire = effectiveValueEffectiveIntegerValConverted + } + case *Setting_EffectiveValue_EffectiveAutomaticClusterUpdateWorkspace: + if value != nil { + effectiveValueEffectiveAutomaticClusterUpdateWorkspaceConverted, err := clusterAutoRestartMessageToWire(&value.EffectiveAutomaticClusterUpdateWorkspace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveAutomaticClusterUpdateWorkspace", err) + } + effectiveValueEffectiveAutomaticClusterUpdateWorkspaceWire = effectiveValueEffectiveAutomaticClusterUpdateWorkspaceConverted + } + case *Setting_EffectiveValue_EffectiveAibiDashboardEmbeddingApprovedDomains: + if value != nil { + effectiveValueEffectiveAibiDashboardEmbeddingApprovedDomainsConverted, err := aibiDashboardEmbeddingApprovedDomainsToWire(&value.EffectiveAibiDashboardEmbeddingApprovedDomains) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveAibiDashboardEmbeddingApprovedDomains", err) + } + effectiveValueEffectiveAibiDashboardEmbeddingApprovedDomainsWire = effectiveValueEffectiveAibiDashboardEmbeddingApprovedDomainsConverted + } + case *Setting_EffectiveValue_EffectiveAibiDashboardEmbeddingAccessPolicy: + if value != nil { + effectiveValueEffectiveAibiDashboardEmbeddingAccessPolicyConverted, err := aibiDashboardEmbeddingAccessPolicyToWire(&value.EffectiveAibiDashboardEmbeddingAccessPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveAibiDashboardEmbeddingAccessPolicy", err) + } + effectiveValueEffectiveAibiDashboardEmbeddingAccessPolicyWire = effectiveValueEffectiveAibiDashboardEmbeddingAccessPolicyConverted + } + case *Setting_EffectiveValue_EffectiveRestrictWorkspaceAdmins: + if value != nil { + effectiveValueEffectiveRestrictWorkspaceAdminsConverted, err := restrictWorkspaceAdminsMessageToWire(&value.EffectiveRestrictWorkspaceAdmins) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveRestrictWorkspaceAdmins", err) + } + effectiveValueEffectiveRestrictWorkspaceAdminsWire = effectiveValueEffectiveRestrictWorkspaceAdminsConverted + } + case *Setting_EffectiveValue_EffectivePersonalCompute: + if value != nil { + effectiveValueEffectivePersonalComputeConverted, err := personalComputeMessageToWire(&value.EffectivePersonalCompute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectivePersonalCompute", err) + } + effectiveValueEffectivePersonalComputeWire = effectiveValueEffectivePersonalComputeConverted + } + case *Setting_EffectiveValue_EffectiveAllowedAppsUserApiScopes: + if value != nil { + effectiveValueEffectiveAllowedAppsUserApiScopesConverted, err := allowedAppsUserApiScopesMessageToWire(&value.EffectiveAllowedAppsUserApiScopes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveAllowedAppsUserApiScopes", err) + } + effectiveValueEffectiveAllowedAppsUserApiScopesWire = effectiveValueEffectiveAllowedAppsUserApiScopesConverted + } + case *Setting_EffectiveValue_EffectiveOperationalEmailCustomRecipient: + if value != nil { + effectiveValueEffectiveOperationalEmailCustomRecipientConverted, err := operationalEmailCustomRecipientMessageToWire(&value.EffectiveOperationalEmailCustomRecipient) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveOperationalEmailCustomRecipient", err) + } + effectiveValueEffectiveOperationalEmailCustomRecipientWire = effectiveValueEffectiveOperationalEmailCustomRecipientConverted + } + case *Setting_EffectiveValue_EffectiveCollaborationPlatformConnectivity: + if value != nil { + effectiveValueEffectiveCollaborationPlatformConnectivityConverted, err := collaborationPlatformConnectivityMessageToWire(&value.EffectiveCollaborationPlatformConnectivity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveCollaborationPlatformConnectivity", err) + } + effectiveValueEffectiveCollaborationPlatformConnectivityWire = effectiveValueEffectiveCollaborationPlatformConnectivityConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Setting.EffectiveValue", value) + } + return &settingWire{ + Name: v.Name, + BooleanVal: valueBooleanValWire, + StringVal: valueStringValWire, + IntegerVal: valueIntegerValWire, + AutomaticClusterUpdateWorkspace: valueAutomaticClusterUpdateWorkspaceWire, + AibiDashboardEmbeddingApprovedDomains: valueAibiDashboardEmbeddingApprovedDomainsWire, + AibiDashboardEmbeddingAccessPolicy: valueAibiDashboardEmbeddingAccessPolicyWire, + RestrictWorkspaceAdmins: valueRestrictWorkspaceAdminsWire, + PersonalCompute: valuePersonalComputeWire, + AllowedAppsUserApiScopes: valueAllowedAppsUserApiScopesWire, + OperationalEmailCustomRecipient: valueOperationalEmailCustomRecipientWire, + CollaborationPlatformConnectivity: valueCollaborationPlatformConnectivityWire, + EffectiveBooleanVal: effectiveValueEffectiveBooleanValWire, + EffectiveStringVal: effectiveValueEffectiveStringValWire, + EffectiveIntegerVal: effectiveValueEffectiveIntegerValWire, + EffectiveAutomaticClusterUpdateWorkspace: effectiveValueEffectiveAutomaticClusterUpdateWorkspaceWire, + EffectiveAibiDashboardEmbeddingApprovedDomains: effectiveValueEffectiveAibiDashboardEmbeddingApprovedDomainsWire, + EffectiveAibiDashboardEmbeddingAccessPolicy: effectiveValueEffectiveAibiDashboardEmbeddingAccessPolicyWire, + EffectiveRestrictWorkspaceAdmins: effectiveValueEffectiveRestrictWorkspaceAdminsWire, + EffectivePersonalCompute: effectiveValueEffectivePersonalComputeWire, + EffectiveAllowedAppsUserApiScopes: effectiveValueEffectiveAllowedAppsUserApiScopesWire, + EffectiveOperationalEmailCustomRecipient: effectiveValueEffectiveOperationalEmailCustomRecipientWire, + EffectiveCollaborationPlatformConnectivity: effectiveValueEffectiveCollaborationPlatformConnectivityWire, + }, nil +} + +func settingFromWire(w *settingWire) (*Setting, error) { + if w == nil { + return nil, nil + } + valueMembers := 0 + if w.BooleanVal != nil { + valueMembers++ + } + if w.StringVal != nil { + valueMembers++ + } + if w.IntegerVal != nil { + valueMembers++ + } + if w.AutomaticClusterUpdateWorkspace != nil { + valueMembers++ + } + if w.AibiDashboardEmbeddingApprovedDomains != nil { + valueMembers++ + } + if w.AibiDashboardEmbeddingAccessPolicy != nil { + valueMembers++ + } + if w.RestrictWorkspaceAdmins != nil { + valueMembers++ + } + if w.PersonalCompute != nil { + valueMembers++ + } + if w.AllowedAppsUserApiScopes != nil { + valueMembers++ + } + if w.OperationalEmailCustomRecipient != nil { + valueMembers++ + } + if w.CollaborationPlatformConnectivity != nil { + valueMembers++ + } + if valueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Setting.Value") + } + effectiveValueMembers := 0 + if w.EffectiveBooleanVal != nil { + effectiveValueMembers++ + } + if w.EffectiveStringVal != nil { + effectiveValueMembers++ + } + if w.EffectiveIntegerVal != nil { + effectiveValueMembers++ + } + if w.EffectiveAutomaticClusterUpdateWorkspace != nil { + effectiveValueMembers++ + } + if w.EffectiveAibiDashboardEmbeddingApprovedDomains != nil { + effectiveValueMembers++ + } + if w.EffectiveAibiDashboardEmbeddingAccessPolicy != nil { + effectiveValueMembers++ + } + if w.EffectiveRestrictWorkspaceAdmins != nil { + effectiveValueMembers++ + } + if w.EffectivePersonalCompute != nil { + effectiveValueMembers++ + } + if w.EffectiveAllowedAppsUserApiScopes != nil { + effectiveValueMembers++ + } + if w.EffectiveOperationalEmailCustomRecipient != nil { + effectiveValueMembers++ + } + if w.EffectiveCollaborationPlatformConnectivity != nil { + effectiveValueMembers++ + } + if effectiveValueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Setting.EffectiveValue") + } + var valueSelection isSetting_Value + switch { + case w.BooleanVal != nil: + valueBooleanValConverted, err := booleanMessageFromWire(w.BooleanVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.BooleanVal", err) + } + valueSelection = &Setting_Value_BooleanVal{BooleanVal: *valueBooleanValConverted} + case w.StringVal != nil: + valueStringValConverted, err := stringMessageFromWire(w.StringVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.StringVal", err) + } + valueSelection = &Setting_Value_StringVal{StringVal: *valueStringValConverted} + case w.IntegerVal != nil: + valueIntegerValConverted, err := integerMessageFromWire(w.IntegerVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.IntegerVal", err) + } + valueSelection = &Setting_Value_IntegerVal{IntegerVal: *valueIntegerValConverted} + case w.AutomaticClusterUpdateWorkspace != nil: + valueAutomaticClusterUpdateWorkspaceConverted, err := clusterAutoRestartMessageFromWire(w.AutomaticClusterUpdateWorkspace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.AutomaticClusterUpdateWorkspace", err) + } + valueSelection = &Setting_Value_AutomaticClusterUpdateWorkspace{AutomaticClusterUpdateWorkspace: *valueAutomaticClusterUpdateWorkspaceConverted} + case w.AibiDashboardEmbeddingApprovedDomains != nil: + valueAibiDashboardEmbeddingApprovedDomainsConverted, err := aibiDashboardEmbeddingApprovedDomainsFromWire(w.AibiDashboardEmbeddingApprovedDomains) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.AibiDashboardEmbeddingApprovedDomains", err) + } + valueSelection = &Setting_Value_AibiDashboardEmbeddingApprovedDomains{AibiDashboardEmbeddingApprovedDomains: *valueAibiDashboardEmbeddingApprovedDomainsConverted} + case w.AibiDashboardEmbeddingAccessPolicy != nil: + valueAibiDashboardEmbeddingAccessPolicyConverted, err := aibiDashboardEmbeddingAccessPolicyFromWire(w.AibiDashboardEmbeddingAccessPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.AibiDashboardEmbeddingAccessPolicy", err) + } + valueSelection = &Setting_Value_AibiDashboardEmbeddingAccessPolicy{AibiDashboardEmbeddingAccessPolicy: *valueAibiDashboardEmbeddingAccessPolicyConverted} + case w.RestrictWorkspaceAdmins != nil: + valueRestrictWorkspaceAdminsConverted, err := restrictWorkspaceAdminsMessageFromWire(w.RestrictWorkspaceAdmins) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.RestrictWorkspaceAdmins", err) + } + valueSelection = &Setting_Value_RestrictWorkspaceAdmins{RestrictWorkspaceAdmins: *valueRestrictWorkspaceAdminsConverted} + case w.PersonalCompute != nil: + valuePersonalComputeConverted, err := personalComputeMessageFromWire(w.PersonalCompute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.PersonalCompute", err) + } + valueSelection = &Setting_Value_PersonalCompute{PersonalCompute: *valuePersonalComputeConverted} + case w.AllowedAppsUserApiScopes != nil: + valueAllowedAppsUserApiScopesConverted, err := allowedAppsUserApiScopesMessageFromWire(w.AllowedAppsUserApiScopes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.AllowedAppsUserApiScopes", err) + } + valueSelection = &Setting_Value_AllowedAppsUserApiScopes{AllowedAppsUserApiScopes: *valueAllowedAppsUserApiScopesConverted} + case w.OperationalEmailCustomRecipient != nil: + valueOperationalEmailCustomRecipientConverted, err := operationalEmailCustomRecipientMessageFromWire(w.OperationalEmailCustomRecipient) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.OperationalEmailCustomRecipient", err) + } + valueSelection = &Setting_Value_OperationalEmailCustomRecipient{OperationalEmailCustomRecipient: *valueOperationalEmailCustomRecipientConverted} + case w.CollaborationPlatformConnectivity != nil: + valueCollaborationPlatformConnectivityConverted, err := collaborationPlatformConnectivityMessageFromWire(w.CollaborationPlatformConnectivity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.Value.CollaborationPlatformConnectivity", err) + } + valueSelection = &Setting_Value_CollaborationPlatformConnectivity{CollaborationPlatformConnectivity: *valueCollaborationPlatformConnectivityConverted} + } + var effectiveValueSelection isSetting_EffectiveValue + switch { + case w.EffectiveBooleanVal != nil: + effectiveValueEffectiveBooleanValConverted, err := booleanMessageFromWire(w.EffectiveBooleanVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveBooleanVal", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectiveBooleanVal{EffectiveBooleanVal: *effectiveValueEffectiveBooleanValConverted} + case w.EffectiveStringVal != nil: + effectiveValueEffectiveStringValConverted, err := stringMessageFromWire(w.EffectiveStringVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveStringVal", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectiveStringVal{EffectiveStringVal: *effectiveValueEffectiveStringValConverted} + case w.EffectiveIntegerVal != nil: + effectiveValueEffectiveIntegerValConverted, err := integerMessageFromWire(w.EffectiveIntegerVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveIntegerVal", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectiveIntegerVal{EffectiveIntegerVal: *effectiveValueEffectiveIntegerValConverted} + case w.EffectiveAutomaticClusterUpdateWorkspace != nil: + effectiveValueEffectiveAutomaticClusterUpdateWorkspaceConverted, err := clusterAutoRestartMessageFromWire(w.EffectiveAutomaticClusterUpdateWorkspace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveAutomaticClusterUpdateWorkspace", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectiveAutomaticClusterUpdateWorkspace{EffectiveAutomaticClusterUpdateWorkspace: *effectiveValueEffectiveAutomaticClusterUpdateWorkspaceConverted} + case w.EffectiveAibiDashboardEmbeddingApprovedDomains != nil: + effectiveValueEffectiveAibiDashboardEmbeddingApprovedDomainsConverted, err := aibiDashboardEmbeddingApprovedDomainsFromWire(w.EffectiveAibiDashboardEmbeddingApprovedDomains) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveAibiDashboardEmbeddingApprovedDomains", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectiveAibiDashboardEmbeddingApprovedDomains{EffectiveAibiDashboardEmbeddingApprovedDomains: *effectiveValueEffectiveAibiDashboardEmbeddingApprovedDomainsConverted} + case w.EffectiveAibiDashboardEmbeddingAccessPolicy != nil: + effectiveValueEffectiveAibiDashboardEmbeddingAccessPolicyConverted, err := aibiDashboardEmbeddingAccessPolicyFromWire(w.EffectiveAibiDashboardEmbeddingAccessPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveAibiDashboardEmbeddingAccessPolicy", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectiveAibiDashboardEmbeddingAccessPolicy{EffectiveAibiDashboardEmbeddingAccessPolicy: *effectiveValueEffectiveAibiDashboardEmbeddingAccessPolicyConverted} + case w.EffectiveRestrictWorkspaceAdmins != nil: + effectiveValueEffectiveRestrictWorkspaceAdminsConverted, err := restrictWorkspaceAdminsMessageFromWire(w.EffectiveRestrictWorkspaceAdmins) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveRestrictWorkspaceAdmins", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectiveRestrictWorkspaceAdmins{EffectiveRestrictWorkspaceAdmins: *effectiveValueEffectiveRestrictWorkspaceAdminsConverted} + case w.EffectivePersonalCompute != nil: + effectiveValueEffectivePersonalComputeConverted, err := personalComputeMessageFromWire(w.EffectivePersonalCompute) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectivePersonalCompute", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectivePersonalCompute{EffectivePersonalCompute: *effectiveValueEffectivePersonalComputeConverted} + case w.EffectiveAllowedAppsUserApiScopes != nil: + effectiveValueEffectiveAllowedAppsUserApiScopesConverted, err := allowedAppsUserApiScopesMessageFromWire(w.EffectiveAllowedAppsUserApiScopes) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveAllowedAppsUserApiScopes", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectiveAllowedAppsUserApiScopes{EffectiveAllowedAppsUserApiScopes: *effectiveValueEffectiveAllowedAppsUserApiScopesConverted} + case w.EffectiveOperationalEmailCustomRecipient != nil: + effectiveValueEffectiveOperationalEmailCustomRecipientConverted, err := operationalEmailCustomRecipientMessageFromWire(w.EffectiveOperationalEmailCustomRecipient) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveOperationalEmailCustomRecipient", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectiveOperationalEmailCustomRecipient{EffectiveOperationalEmailCustomRecipient: *effectiveValueEffectiveOperationalEmailCustomRecipientConverted} + case w.EffectiveCollaborationPlatformConnectivity != nil: + effectiveValueEffectiveCollaborationPlatformConnectivityConverted, err := collaborationPlatformConnectivityMessageFromWire(w.EffectiveCollaborationPlatformConnectivity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Setting.EffectiveValue.EffectiveCollaborationPlatformConnectivity", err) + } + effectiveValueSelection = &Setting_EffectiveValue_EffectiveCollaborationPlatformConnectivity{EffectiveCollaborationPlatformConnectivity: *effectiveValueEffectiveCollaborationPlatformConnectivityConverted} + } + return &Setting{ + Name: w.Name, + Value: valueSelection, + EffectiveValue: effectiveValueSelection, + }, nil +} + +type settingsMetadataWire struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + Type *string `json:"type,omitempty"` + DocsLink *string `json:"docs_link,omitempty"` + PreviewPhase PreviewPhase `json:"preview_phase,omitempty"` + DisplayName *string `json:"display_name,omitempty"` +} + +func settingsMetadataFromWire(w *settingsMetadataWire) (*SettingsMetadata, error) { + if w == nil { + return nil, nil + } + return &SettingsMetadata{ + Name: w.Name, + Description: w.Description, + Type: w.Type, + DocsLink: w.DocsLink, + PreviewPhase: w.PreviewPhase, + DisplayName: w.DisplayName, + }, nil +} + +type stringMessageWire struct { + Value *string `json:"value,omitempty"` +} + +func stringMessageToWire(v *StringMessage) (*stringMessageWire, error) { + if v == nil { + return nil, nil + } + return &stringMessageWire{ + Value: v.Value, + }, nil +} + +func stringMessageFromWire(w *stringMessageWire) (*StringMessage, error) { + if w == nil { + return nil, nil + } + return &StringMessage{ + Value: w.Value, + }, nil +} + +type userPreferenceWire struct { + Name *string `json:"name,omitempty"` + UserId *string `json:"user_id,omitempty"` + BooleanVal *booleanMessageWire `json:"boolean_val,omitempty"` + StringVal *stringMessageWire `json:"string_val,omitempty"` + EffectiveBooleanVal *booleanMessageWire `json:"effective_boolean_val,omitempty"` + EffectiveStringVal *stringMessageWire `json:"effective_string_val,omitempty"` +} + +func userPreferenceToWire(v *UserPreference) (*userPreferenceWire, error) { + if v == nil { + return nil, nil + } + var valueBooleanValWire *booleanMessageWire + var valueStringValWire *stringMessageWire + switch value := v.Value.(type) { + case nil: + case *UserPreference_Value_BooleanVal: + if value != nil { + valueBooleanValConverted, err := booleanMessageToWire(&value.BooleanVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UserPreference.Value.BooleanVal", err) + } + valueBooleanValWire = valueBooleanValConverted + } + case *UserPreference_Value_StringVal: + if value != nil { + valueStringValConverted, err := stringMessageToWire(&value.StringVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UserPreference.Value.StringVal", err) + } + valueStringValWire = valueStringValConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "UserPreference.Value", value) + } + var effectiveValueEffectiveBooleanValWire *booleanMessageWire + var effectiveValueEffectiveStringValWire *stringMessageWire + switch value := v.EffectiveValue.(type) { + case nil: + case *UserPreference_EffectiveValue_EffectiveBooleanVal: + if value != nil { + effectiveValueEffectiveBooleanValConverted, err := booleanMessageToWire(&value.EffectiveBooleanVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UserPreference.EffectiveValue.EffectiveBooleanVal", err) + } + effectiveValueEffectiveBooleanValWire = effectiveValueEffectiveBooleanValConverted + } + case *UserPreference_EffectiveValue_EffectiveStringVal: + if value != nil { + effectiveValueEffectiveStringValConverted, err := stringMessageToWire(&value.EffectiveStringVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UserPreference.EffectiveValue.EffectiveStringVal", err) + } + effectiveValueEffectiveStringValWire = effectiveValueEffectiveStringValConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "UserPreference.EffectiveValue", value) + } + return &userPreferenceWire{ + Name: v.Name, + UserId: v.UserId, + BooleanVal: valueBooleanValWire, + StringVal: valueStringValWire, + EffectiveBooleanVal: effectiveValueEffectiveBooleanValWire, + EffectiveStringVal: effectiveValueEffectiveStringValWire, + }, nil +} + +func userPreferenceFromWire(w *userPreferenceWire) (*UserPreference, error) { + if w == nil { + return nil, nil + } + valueMembers := 0 + if w.BooleanVal != nil { + valueMembers++ + } + if w.StringVal != nil { + valueMembers++ + } + if valueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "UserPreference.Value") + } + effectiveValueMembers := 0 + if w.EffectiveBooleanVal != nil { + effectiveValueMembers++ + } + if w.EffectiveStringVal != nil { + effectiveValueMembers++ + } + if effectiveValueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "UserPreference.EffectiveValue") + } + var valueSelection isUserPreference_Value + switch { + case w.BooleanVal != nil: + valueBooleanValConverted, err := booleanMessageFromWire(w.BooleanVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UserPreference.Value.BooleanVal", err) + } + valueSelection = &UserPreference_Value_BooleanVal{BooleanVal: *valueBooleanValConverted} + case w.StringVal != nil: + valueStringValConverted, err := stringMessageFromWire(w.StringVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UserPreference.Value.StringVal", err) + } + valueSelection = &UserPreference_Value_StringVal{StringVal: *valueStringValConverted} + } + var effectiveValueSelection isUserPreference_EffectiveValue + switch { + case w.EffectiveBooleanVal != nil: + effectiveValueEffectiveBooleanValConverted, err := booleanMessageFromWire(w.EffectiveBooleanVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UserPreference.EffectiveValue.EffectiveBooleanVal", err) + } + effectiveValueSelection = &UserPreference_EffectiveValue_EffectiveBooleanVal{EffectiveBooleanVal: *effectiveValueEffectiveBooleanValConverted} + case w.EffectiveStringVal != nil: + effectiveValueEffectiveStringValConverted, err := stringMessageFromWire(w.EffectiveStringVal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UserPreference.EffectiveValue.EffectiveStringVal", err) + } + effectiveValueSelection = &UserPreference_EffectiveValue_EffectiveStringVal{EffectiveStringVal: *effectiveValueEffectiveStringValConverted} + } + return &UserPreference{ + Name: w.Name, + UserId: w.UserId, + Value: valueSelection, + EffectiveValue: effectiveValueSelection, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/sharing/.package.json b/sharing/.package.json new file mode 100644 index 0000000..2dbf2d4 --- /dev/null +++ b/sharing/.package.json @@ -0,0 +1,3 @@ +{ + "package": "sharing" +} diff --git a/sharing/CHANGELOG.md b/sharing/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/sharing/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/sharing/README.md b/sharing/README.md new file mode 100644 index 0000000..3ef8151 --- /dev/null +++ b/sharing/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/sharing + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/sharing@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/sharing/v1" + +client, err := sharing.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/sharing/go.mod b/sharing/go.mod new file mode 100644 index 0000000..4b77885 --- /dev/null +++ b/sharing/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/sharing + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/sharing/internal/version.go b/sharing/internal/version.go new file mode 100644 index 0000000..9b9f307 --- /dev/null +++ b/sharing/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-sharing" + +const Version = "0.0.1-dev.1" diff --git a/sharing/v1/client.go b/sharing/v1/client.go new file mode 100755 index 0000000..c8fa075 --- /dev/null +++ b/sharing/v1/client.go @@ -0,0 +1,2139 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package sharing + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/sharing/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a federation policy for an OIDC_FEDERATION recipient for sharing data +// from to non- recipients. The caller must be the +// owner of the recipient. When sharing data from to +// non- clients, you can define a federation policy to authenticate +// non- recipients. The federation policy validates OIDC claims in +// federated tokens and is defined at the recipient level. This enables +// secretless sharing clients to authenticate using OIDC tokens. +// +// Supported scenarios for federation policies: 1. **User-to-Machine (U2M) +// flow** (e.g., PowerBI): A user accesses a resource using their own identity. +// 2. **Machine-to-Machine (M2M) flow** (e.g., OAuth App): An OAuth App accesses +// a resource using its own identity, typically for tasks like running nightly +// jobs. +// +// For an overview, refer to: - Blog post: Overview of feature: +// https://www.databricks.com/blog/announcing-oidc-token-federation-enhanced-delta-sharing-security +// +// For detailed configuration guides based on your use case: - Creating a +// Federation Policy as a provider: +// https://docs.databricks.com/en/delta-sharing/create-recipient-oidc-fed - +// Configuration and usage for Machine-to-Machine (M2M) applications (e.g., +// Python Delta Sharing Client): +// https://docs.databricks.com/aws/en/delta-sharing/sharing-over-oidc-m2m - +// Configuration and usage for User-to-Machine (U2M) applications (e.g., +// PowerBI): +// https://docs.databricks.com/aws/en/delta-sharing/sharing-over-oidc-u2m +func (c *internalClient) CreateFederationPolicy(ctx context.Context, req *CreateFederationPolicyRequest, opts ...call.Option) (*FederationPolicy, error) { + wireReq, err := createFederationPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Policy) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/data-sharing/recipients/") + pb.singleSegment(*req.RecipientName) + pb.literal("/federation-policies") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FederationPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp federationPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = federationPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new authentication provider minimally based on a name and +// authentication type. The caller must be an admin on the metastore. +func (c *internalClient) CreateProvider(ctx context.Context, req *CreateProviderRequest, opts ...call.Option) (*ProviderInfo, error) { + wireReq, err := createProviderRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/providers" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ProviderInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp providerInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = providerInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new recipient with the delta sharing authentication type in the +// metastore. The caller must be a metastore admin or have the +// **CREATE_RECIPIENT** privilege on the metastore. +func (c *internalClient) CreateRecipient(ctx context.Context, req *CreateRecipientRequest, opts ...call.Option) (*RecipientInfo, error) { + wireReq, err := createRecipientRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/recipients" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RecipientInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp recipientInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = recipientInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new share for data objects. Data objects can be added after +// creation with **update**. The caller must be a metastore admin or have the +// **CREATE_SHARE** privilege on the metastore. +func (c *internalClient) CreateShare(ctx context.Context, req *CreateShareRequest, opts ...call.Option) (*ShareInfo, error) { + wireReq, err := createShareRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/shares" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ShareInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp shareInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = shareInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes an existing federation policy for an OIDC_FEDERATION recipient. The +// caller must be the owner of the recipient. +func (c *internalClient) DeleteFederationPolicy(ctx context.Context, req *DeleteFederationPolicyRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/data-sharing/recipients/") + pb.singleSegment(*req.RecipientName) + pb.literal("/federation-policies/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Deletes an authentication provider, if the caller is a metastore admin or is +// the owner of the provider. +func (c *internalClient) DeleteProvider(ctx context.Context, req *DeleteProviderRequest, opts ...call.Option) (*DeleteProviderResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/providers/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteProviderResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteProviderResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the specified recipient from the metastore. The caller must be the +// owner of the recipient. +func (c *internalClient) DeleteRecipient(ctx context.Context, req *DeleteRecipientRequest, opts ...call.Option) (*DeleteRecipientResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/recipients/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteRecipientResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteRecipientResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a data object share from the metastore. The caller must be an owner +// of the share. +func (c *internalClient) DeleteShare(ctx context.Context, req *DeleteShareRequest, opts ...call.Option) (*DeleteShareResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/shares/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteShareResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteShareResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an activation URL for a share. +func (c *internalClient) GetActivationUrlInfo(ctx context.Context, req *GetActivationUrlInfoRequest, opts ...call.Option) (*GetActivationUrlInfoResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/public/data_sharing_activation_info/") + pb.singleSegment(*req.ActivationUrl) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetActivationUrlInfoResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &GetActivationUrlInfoResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Reads an existing federation policy for an OIDC_FEDERATION recipient for +// sharing data from to non- recipients. The caller +// must have read access to the recipient. +func (c *internalClient) GetFederationPolicy(ctx context.Context, req *GetFederationPolicyRequest, opts ...call.Option) (*FederationPolicy, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/data-sharing/recipients/") + pb.singleSegment(*req.RecipientName) + pb.literal("/federation-policies/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FederationPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp federationPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = federationPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a specific authentication provider. The caller must supply the name of +// the provider, and must either be a metastore admin or the owner of the +// provider. +func (c *internalClient) GetProvider(ctx context.Context, req *GetProviderRequest, opts ...call.Option) (*ProviderInfo, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/providers/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ProviderInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp providerInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = providerInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a share recipient from the metastore. The caller must be one of: * A +// user with **USE_RECIPIENT** privilege on the metastore * The owner of the +// share recipient * A metastore admin +func (c *internalClient) GetRecipient(ctx context.Context, req *GetRecipientRequest, opts ...call.Option) (*RecipientInfo, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/recipients/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RecipientInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp recipientInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = recipientInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a data object share from the metastore. The caller must have the +// USE_SHARE privilege on the metastore or be the owner of the share. +func (c *internalClient) GetShare(ctx context.Context, req *GetShareRequest, opts ...call.Option) (*ShareInfo, error) { + wireReq, err := getShareRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/shares/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_shared_data", wireReq.IncludeSharedData); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ShareInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp shareInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = shareInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists federation policies for an OIDC_FEDERATION recipient for sharing data +// from to non- recipients. The caller must have read +// access to the recipient. +func (c *internalClient) ListFederationPolicies(ctx context.Context, req *ListFederationPoliciesRequest, opts ...call.Option) (*ListFederationPoliciesResponse, error) { + wireReq, err := listFederationPoliciesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/data-sharing/recipients/") + pb.singleSegment(*req.RecipientName) + pb.literal("/federation-policies") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListFederationPoliciesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listFederationPoliciesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listFederationPoliciesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListFederationPoliciesIter returns an iterator that iterates +// over the results of ListFederationPolicies. +// +// For example: +// +// for item, err := range c.ListFederationPoliciesIter(ctx, &ListFederationPoliciesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListFederationPolicies call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListFederationPolicies directly. +func (c *internalClient) ListFederationPoliciesIter(ctx context.Context, req *ListFederationPoliciesRequest, opts ...call.Option) iter.Seq2[*FederationPolicy, error] { + return func(yield func(*FederationPolicy, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListFederationPoliciesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListFederationPolicies(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Policies { + if !yield(&resp.Policies[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Get arrays of assets associated with a specified provider's share. The caller +// is the recipient of the share. +func (c *internalClient) ListProviderShareAssets(ctx context.Context, req *ListProviderShareAssetsRequest, opts ...call.Option) (*ListProviderShareAssetsResponse, error) { + wireReq, err := listProviderShareAssetsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/data-sharing/providers/") + pb.singleSegment(*req.ProviderNameArg) + pb.literal("/shares/") + pb.singleSegment(*req.ShareNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "table_max_results", wireReq.TableMaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "function_max_results", wireReq.FunctionMaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "volume_max_results", wireReq.VolumeMaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "notebook_max_results", wireReq.NotebookMaxResults); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListProviderShareAssetsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listProviderShareAssetsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listProviderShareAssetsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of a specified provider's shares within the metastore where: * +// the caller is a metastore admin, or * the caller is the owner. +func (c *internalClient) ListProviderShares(ctx context.Context, req *ListProviderSharesRequest, opts ...call.Option) (*ListProviderSharesResponse, error) { + wireReq, err := listProviderSharesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/providers/") + pb.singleSegment(*req.ProviderNameArg) + pb.literal("/shares") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListProviderSharesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listProviderSharesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listProviderSharesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListProviderSharesIter returns an iterator that iterates +// over the results of ListProviderShares. +// +// For example: +// +// for item, err := range c.ListProviderSharesIter(ctx, &ListProviderSharesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListProviderShares call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListProviderShares directly. +func (c *internalClient) ListProviderSharesIter(ctx context.Context, req *ListProviderSharesRequest, opts ...call.Option) iter.Seq2[*ProviderShare, error] { + return func(yield func(*ProviderShare, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListProviderSharesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListProviderShares(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Shares { + if !yield(&resp.Shares[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Gets an array of available authentication providers. The caller must either +// be a metastore admin, have the **USE_PROVIDER** privilege on the providers, +// or be the owner of the providers. Providers not owned by the caller and for +// which the caller does not have the **USE_PROVIDER** privilege are not +// included in the response. There is no guarantee of a specific ordering of the +// elements in the array. +func (c *internalClient) ListProviders(ctx context.Context, req *ListProvidersRequest, opts ...call.Option) (*ListProvidersResponse, error) { + wireReq, err := listProvidersRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/providers" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "data_provider_global_metastore_id", wireReq.DataProviderGlobalMetastoreId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListProvidersResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listProvidersResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listProvidersResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListProvidersIter returns an iterator that iterates +// over the results of ListProviders. +// +// For example: +// +// for item, err := range c.ListProvidersIter(ctx, &ListProvidersRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListProviders call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListProviders directly. +func (c *internalClient) ListProvidersIter(ctx context.Context, req *ListProvidersRequest, opts ...call.Option) iter.Seq2[*ProviderInfo, error] { + return func(yield func(*ProviderInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListProvidersRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListProviders(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Providers { + if !yield(&resp.Providers[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Gets the share permissions for the specified Recipient. The caller must have +// the **USE_RECIPIENT** privilege on the metastore or be the owner of the +// Recipient. +func (c *internalClient) ListRecipientSharePermissions(ctx context.Context, req *ListRecipientSharePermissionsRequest, opts ...call.Option) (*GetRecipientSharePermissionsResponse, error) { + wireReq, err := listRecipientSharePermissionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/recipients/") + pb.singleSegment(*req.Name) + pb.literal("/share-permissions") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetRecipientSharePermissionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getRecipientSharePermissionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getRecipientSharePermissionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of all share recipients within the current metastore where: * +// the caller is a metastore admin, or * the caller is the owner. There is no +// guarantee of a specific ordering of the elements in the array. +func (c *internalClient) ListRecipients(ctx context.Context, req *ListRecipientsRequest, opts ...call.Option) (*ListRecipientsResponse, error) { + wireReq, err := listRecipientsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/recipients" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "data_recipient_global_metastore_id", wireReq.DataRecipientGlobalMetastoreId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListRecipientsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listRecipientsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listRecipientsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListRecipientsIter returns an iterator that iterates +// over the results of ListRecipients. +// +// For example: +// +// for item, err := range c.ListRecipientsIter(ctx, &ListRecipientsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListRecipients call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListRecipients directly. +func (c *internalClient) ListRecipientsIter(ctx context.Context, req *ListRecipientsRequest, opts ...call.Option) iter.Seq2[*RecipientInfo, error] { + return func(yield func(*RecipientInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListRecipientsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListRecipients(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Recipients { + if !yield(&resp.Recipients[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Gets the permissions for a data share from the metastore. The caller must +// have the USE_SHARE privilege on the metastore or be the owner of the share. +func (c *internalClient) ListSharePermissions(ctx context.Context, req *ListSharePermissionsRequest, opts ...call.Option) (*GetSharePermissionsResponse, error) { + wireReq, err := listSharePermissionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/shares/") + pb.singleSegment(*req.Name) + pb.literal("/permissions") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetSharePermissionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getSharePermissionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getSharePermissionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of data object shares from the metastore. If the caller has the +// USE_SHARE privilege on the metastore, all shares are returned. Otherwise, +// only shares owned by the caller are returned. There is no guarantee of a +// specific ordering of the elements in the array. +func (c *internalClient) ListShares(ctx context.Context, req *ListSharesRequest, opts ...call.Option) (*ListSharesResponse, error) { + wireReq, err := listSharesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/shares" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListSharesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listSharesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listSharesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListSharesIter returns an iterator that iterates +// over the results of ListShares. +// +// For example: +// +// for item, err := range c.ListSharesIter(ctx, &ListSharesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListShares call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListShares directly. +func (c *internalClient) ListSharesIter(ctx context.Context, req *ListSharesRequest, opts ...call.Option) iter.Seq2[*ShareInfo, error] { + return func(yield func(*ShareInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListSharesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListShares(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Shares { + if !yield(&resp.Shares[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Retrieve access token with an activation url. This is a public API without +// any authentication. +func (c *internalClient) RetrieveAccessToken(ctx context.Context, req *RetrieveTokenRequest, opts ...call.Option) (*RetrieveTokenResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/public/data_sharing_activation/") + pb.singleSegment(*req.ActivationUrl) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RetrieveTokenResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp retrieveTokenResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = retrieveTokenResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Refreshes the specified recipient's delta sharing authentication token with +// the provided token info. The caller must be the owner of the recipient. +func (c *internalClient) RotateRecipientToken(ctx context.Context, req *RotateRecipientTokenRequest, opts ...call.Option) (*RecipientInfo, error) { + wireReq, err := rotateRecipientTokenRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/recipients/") + pb.singleSegment(*req.Name) + pb.literal("/rotate-token") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RecipientInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp recipientInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = recipientInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the information for an authentication provider, if the caller is a +// metastore admin or is the owner of the provider. If the update changes the +// provider name, the caller must be both a metastore admin and the owner of the +// provider. +func (c *internalClient) UpdateProvider(ctx context.Context, req *UpdateProviderRequest, opts ...call.Option) (*ProviderInfo, error) { + wireReq, err := updateProviderRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/providers/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ProviderInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp providerInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = providerInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an existing recipient in the metastore. The caller must be a +// metastore admin or the owner of the recipient. If the recipient name will be +// updated, the user must be both a metastore admin and the owner of the +// recipient. +func (c *internalClient) UpdateRecipient(ctx context.Context, req *UpdateRecipientRequest, opts ...call.Option) (*RecipientInfo, error) { + wireReq, err := updateRecipientRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/recipients/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RecipientInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp recipientInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = recipientInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the share with the changes and data objects in the request. The +// caller must be the owner of the share or a metastore admin. When the caller +// is a metastore admin, only the __owner__ field can be updated. In the case +// the share name is changed, **updateShare** requires that the caller is the +// owner of the share and has the CREATE_SHARE privilege. +// +// If there are notebook files in the share, the __storage_root__ field cannot +// be updated. For each table that is added through this method, the share owner +// must also have **SELECT** privilege on the table. This privilege must be +// maintained indefinitely for recipients to be able to access the table. +// Typically, you should use a group as the share owner. Table removals through +// **update** do not require additional privileges. +func (c *internalClient) UpdateShare(ctx context.Context, req *UpdateShareRequest, opts ...call.Option) (*ShareInfo, error) { + wireReq, err := updateShareRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/shares/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ShareInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp shareInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = shareInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the permissions for a data share in the metastore. The caller must +// have both the USE_SHARE and SET_SHARE_PERMISSION privileges on the metastore, +// or be the owner of the share. +// +// For new recipient grants, the user must also be the owner of the recipients. +// recipient revocations do not require additional privileges. +func (c *internalClient) UpdateSharePermissions(ctx context.Context, req *UpdateSharePermissionsRequest, opts ...call.Option) (*UpdateSharePermissionsResponse, error) { + wireReq, err := updateSharePermissionsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/shares/") + pb.singleSegment(*req.Name) + pb.literal("/permissions") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateSharePermissionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateSharePermissionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateSharePermissionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/sharing/v1/genhelper.go b/sharing/v1/genhelper.go new file mode 100755 index 0000000..c171086 --- /dev/null +++ b/sharing/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package sharing + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/sharing/v1/model.go b/sharing/v1/model.go new file mode 100755 index 0000000..ff189eb --- /dev/null +++ b/sharing/v1/model.go @@ -0,0 +1,1228 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package sharing + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// UC supported column types Copied from +// https://src.dev.databricks.com/databricks/universe@23a85902bb58695ab9293adc9f327b0714b55e72/-/blob/managed-catalog/api/messages/table.proto?L68 +type ColumnTypeName string + +const ( + ColumnTypeName_Unspecified ColumnTypeName = "" + ColumnTypeName_Boolean ColumnTypeName = "BOOLEAN" + ColumnTypeName_Byte ColumnTypeName = "BYTE" + ColumnTypeName_Short ColumnTypeName = "SHORT" + ColumnTypeName_Int ColumnTypeName = "INT" + ColumnTypeName_Long ColumnTypeName = "LONG" + ColumnTypeName_Float ColumnTypeName = "FLOAT" + ColumnTypeName_Double ColumnTypeName = "DOUBLE" + ColumnTypeName_Date ColumnTypeName = "DATE" + ColumnTypeName_Timestamp ColumnTypeName = "TIMESTAMP" + ColumnTypeName_String ColumnTypeName = "STRING" + ColumnTypeName_Binary ColumnTypeName = "BINARY" + ColumnTypeName_Decimal ColumnTypeName = "DECIMAL" + ColumnTypeName_Interval ColumnTypeName = "INTERVAL" + ColumnTypeName_Array ColumnTypeName = "ARRAY" + ColumnTypeName_Struct ColumnTypeName = "STRUCT" + ColumnTypeName_Map ColumnTypeName = "MAP" + ColumnTypeName_Char ColumnTypeName = "CHAR" + ColumnTypeName_Null ColumnTypeName = "NULL" + ColumnTypeName_UserDefinedType ColumnTypeName = "USER_DEFINED_TYPE" + ColumnTypeName_TimestampNtz ColumnTypeName = "TIMESTAMP_NTZ" + ColumnTypeName_Variant ColumnTypeName = "VARIANT" + ColumnTypeName_TableType ColumnTypeName = "TABLE_TYPE" +) + +// The delta sharing authentication type. +type DeltaSharingAuthenticationType string + +const ( + DeltaSharingAuthenticationType_Unspecified DeltaSharingAuthenticationType = "" + // Token-based authentication. + DeltaSharingAuthenticationType_Token DeltaSharingAuthenticationType = "TOKEN" + // Databricks-managed authentication. + DeltaSharingAuthenticationType_Databricks DeltaSharingAuthenticationType = "DATABRICKS" + // OIDC Federation authentication + DeltaSharingAuthenticationType_OidcFederation DeltaSharingAuthenticationType = "OIDC_FEDERATION" + // OAuth Client Credentials Grant based authentication. This option is for + // provider imports only. + DeltaSharingAuthenticationType_OauthClientCredentials DeltaSharingAuthenticationType = "OAUTH_CLIENT_CREDENTIALS" +) + +type FunctionParameterMode string + +const ( + FunctionParameterMode_Unspecified FunctionParameterMode = "" + FunctionParameterMode_In FunctionParameterMode = "IN" + FunctionParameterMode_Out FunctionParameterMode = "OUT" + FunctionParameterMode_Inout FunctionParameterMode = "INOUT" +) + +type FunctionParameterType string + +const ( + FunctionParameterType_Unspecified FunctionParameterType = "" + FunctionParameterType_Param FunctionParameterType = "PARAM" + FunctionParameterType_Column FunctionParameterType = "COLUMN" +) + +// The SecurableKind of a delta-shared object. +type SharedSecurableKind string + +const ( + SharedSecurableKind_Unspecified SharedSecurableKind = "" + SharedSecurableKind_FunctionStandard SharedSecurableKind = "FUNCTION_STANDARD" + SharedSecurableKind_FunctionRegisteredModel SharedSecurableKind = "FUNCTION_REGISTERED_MODEL" + SharedSecurableKind_FunctionFeatureSpec SharedSecurableKind = "FUNCTION_FEATURE_SPEC" +) + +type PartitionSpecification_Partition_PartitionValue_PartitionValueOp string + +const ( + PartitionSpecification_Partition_PartitionValue_PartitionValueOp_Unspecified PartitionSpecification_Partition_PartitionValue_PartitionValueOp = "" + PartitionSpecification_Partition_PartitionValue_PartitionValueOp_Like PartitionSpecification_Partition_PartitionValue_PartitionValueOp = "LIKE" +) + +type SharedDataObject_HistoryDataSharingStatus_Enum string + +const ( + SharedDataObject_HistoryDataSharingStatus_Enum_Unspecified SharedDataObject_HistoryDataSharingStatus_Enum = "" + SharedDataObject_HistoryDataSharingStatus_Enum_Disabled SharedDataObject_HistoryDataSharingStatus_Enum = "DISABLED" + SharedDataObject_HistoryDataSharingStatus_Enum_Enabled SharedDataObject_HistoryDataSharingStatus_Enum = "ENABLED" +) + +type SharedDataObject_Status_Enum string + +const ( + SharedDataObject_Status_Enum_Unspecified SharedDataObject_Status_Enum = "" + // Object is being shared with recipients without any issues. + SharedDataObject_Status_Enum_Active SharedDataObject_Status_Enum = "ACTIVE" + // For securables, the share owner has lost access to the securable, so the + // securable is not being shared with the recipient. + SharedDataObject_Status_Enum_PermissionDenied SharedDataObject_Status_Enum = "PERMISSION_DENIED" +) + +type UpdateShareRequest_SharedDataObjectUpdate_Action string + +const ( + UpdateShareRequest_SharedDataObjectUpdate_Action_Unspecified UpdateShareRequest_SharedDataObjectUpdate_Action = "" + UpdateShareRequest_SharedDataObjectUpdate_Action_Remove UpdateShareRequest_SharedDataObjectUpdate_Action = "REMOVE" + UpdateShareRequest_SharedDataObjectUpdate_Action_Update UpdateShareRequest_SharedDataObjectUpdate_Action = "UPDATE" +) + +type CreateFederationPolicyRequest struct { + // Name of the recipient. This is the name of the recipient for which the policy + // is being created. + RecipientName *string + // Name of the policy. This is the name of the policy to be created. + Policy *FederationPolicy +} + +type CreateProviderRequest struct { + // The name of the Provider. + Name *string + AuthenticationType DeltaSharingAuthenticationType + // This field is required when the __authentication_type__ is **TOKEN**, + // **OAUTH_CLIENT_CREDENTIALS** or not provided. + RecipientProfileStr *string + // Description about the provider. + Comment *string + // Username of Provider owner. + Owner *string + // The recipient profile. This field is only present when the + // authentication_type is `TOKEN` or `OAUTH_CLIENT_CREDENTIALS`. + RecipientProfile *RecipientProfile + // Time at which this Provider was created, in epoch milliseconds. + CreatedAt *int64 + // Username of Provider creator. + CreatedBy *string + // Time at which this Provider was created, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified Provider. + UpdatedBy *string + // Cloud vendor of the provider's UC metastore. This field is only present when + // the __authentication_type__ is **DATABRICKS**. + Cloud *string + // Cloud region of the provider's UC metastore. This field is only present when + // the __authentication_type__ is **DATABRICKS**. + Region *string + // UUID of the provider's UC metastore. This field is only present when the + // __authentication_type__ is **DATABRICKS**. + MetastoreId *string + // The global UC metastore id of the data provider. This field is only present + // when the __authentication_type__ is **DATABRICKS**. The identifier is of + // format __cloud__:__region__:__metastore-uuid__. + DataProviderGlobalMetastoreId *string +} + +type CreateRecipientRequest struct { + // Name of Recipient. + Name *string + AuthenticationType DeltaSharingAuthenticationType + // The one-time sharing code provided by the data recipient. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + SharingCode *string + // The global Unity Catalog metastore id provided by the data recipient. This + // field is only present when the __authentication_type__ is **DATABRICKS**. The + // identifier is of format __cloud__:__region__:__metastore-uuid__. + DataRecipientGlobalMetastoreId *string + // Username of the recipient owner. + Owner *string + // Description about the recipient. + Comment *string + // IP Access List + IpAccessList *IpAccessList + // Recipient properties as map of string key-value pairs. When provided in + // update request, the specified properties will override the existing + // properties. To add and remove properties, one would need to perform a + // read-modify-write. + PropertiesKvpairs *PropertiesKvPairs + // Expiration timestamp of the token, in epoch milliseconds. + ExpirationTime *int64 + // Full activation url to retrieve the access token. It will be empty if the + // token is already retrieved. + ActivationUrl *string + // A boolean status field showing whether the Recipient's activation URL has + // been exercised or not. + Activated *bool + // Time at which this recipient was created, in epoch milliseconds. + CreatedAt *int64 + // Username of recipient creator. + CreatedBy *string + // This field is only present when the __authentication_type__ is **TOKEN**. + Tokens []RecipientTokenInfo + // Time at which the recipient was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of recipient updater. + UpdatedBy *string + // Cloud vendor of the recipient's Unity Catalog Metastore. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + Cloud *string + // Cloud region of the recipient's Unity Catalog Metastore. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + Region *string + // Unique identifier of recipient's Unity Catalog Metastore. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + MetastoreId *string + // [Create,Update:IGN] common - id of the recipient + Id *string +} + +type CreateShareRequest struct { + // Name of the share. + Name *string + // Username of current owner of share. + Owner *string + // User-provided free-form text description. + Comment *string + // Storage root URL for the share. + StorageRoot *string + // A list of shared data objects within the share. + Objects []SharedDataObject + // Time at which this share was created, in epoch milliseconds. + CreatedAt *int64 + // Username of share creator. + CreatedBy *string + // Time at which this share was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of share updater. + UpdatedBy *string + // Storage Location URL (full path) for the share. + StorageLocation *string +} + +type DeleteFederationPolicyRequest struct { + // Name of the recipient. This is the name of the recipient for which the policy + // is being deleted. + RecipientName *string + // Name of the policy. This is the name of the policy to be deleted. + Name *string +} + +type DeleteProviderRequest struct { + // Name of the provider. + NameArg *string +} + +type DeleteProviderResponse struct { +} + +type DeleteRecipientRequest struct { + // Name of the recipient. + Name *string +} + +type DeleteRecipientResponse struct { +} + +type DeleteShareRequest struct { + // The name of the share. + Name *string +} + +type DeleteShareResponse struct { +} + +// Represents a UC dependency.. +type Dependency struct { + Value isDependency_Value +} + +type isDependency_Value interface { + isDependency_Value() +} + +// Dependency_Value_Table selects Table for Dependency.Value. +type Dependency_Value_Table struct { + Table TableDependency +} + +func (*Dependency_Value_Table) isDependency_Value() {} + +// Dependency_Value_Function selects Function for Dependency.Value. +type Dependency_Value_Function struct { + Function FunctionDependency +} + +func (*Dependency_Value_Function) isDependency_Value() {} + +// Represents a list of dependencies.. +type DependencyList struct { + // An array of Dependency. + Dependencies []Dependency +} + +type FederationPolicy struct { + // Name of the federation policy. A recipient can have multiple policies with + // different names. The name must contain only lowercase alphanumeric + // characters, numbers, and hyphens. + Name *string + Policy isFederationPolicy_Policy + // System-generated timestamp indicating when the policy was created. + CreateTime *types.Time + // Description of the policy. This is a user-provided description. + Comment *string + // System-generated timestamp indicating when the policy was last updated. + UpdateTime *types.Time + // Unique, immutable system-generated identifier for the federation policy. + Id *string +} + +type isFederationPolicy_Policy interface { + isFederationPolicy_Policy() +} + +// FederationPolicy_Policy_OidcPolicy selects OidcPolicy for FederationPolicy.Policy. +// Specifies the policy to use for validating OIDC claims in the federated +// tokens. +type FederationPolicy_Policy_OidcPolicy struct { + OidcPolicy OidcFederationPolicy +} + +func (*FederationPolicy_Policy_OidcPolicy) isFederationPolicy_Policy() {} + +type Function struct { + // The name of the function. + Name *string + // The name of the schema that the function belongs to. + Schema *string + // The name of the share that the function belongs to. + Share *string + // The id of the share that the function belongs to. + ShareId *string + // The id of the function. + Id *string + // The storage location of the function. + StorageLocation *string + // The comment of the function. + Comment *string + // The aliass of registered model. + Aliases []RegisteredModelAlias + // The tags of the function. + Tags []TagKeyValue + // The securable kind of the function. + SecurableKind SharedSecurableKind + // The full data type of the function. + FullDataType *string + // The data type of the function. + DataType ColumnTypeName + // The routine definition of the function. + RoutineDefinition *string + // The function parameter information. + InputParams *FunctionParameterInfos + // The dependency list of the function. + DependencyList *DependencyList + // The properties of the function. + Properties *string +} + +// A Function in UC as a dependency.. +type FunctionDependency struct { + SchemaName *string + FunctionName *string +} + +// Represents a parameter of a function. The same message is used for both input +// and output columns.. +type FunctionParameterInfo struct { + // The name of the parameter. + Name *string + // The type of the parameter in text format. + TypeText *string + // The type of the parameter in JSON format. + TypeJson *string + // The type of the parameter in Enum format. + TypeName ColumnTypeName + // The precision of the parameter type. + TypePrecision *int + // The scale of the parameter type. + TypeScale *int + // The interval type of the parameter type. + TypeIntervalType *string + // The position of the parameter. + Position *int + // The mode of the function parameter. + ParameterMode FunctionParameterMode + // The type of the function parameter. + ParameterType FunctionParameterType + // The default value of the parameter. + ParameterDefault *string + // The comment of the parameter. + Comment *string +} + +type FunctionParameterInfos struct { + // The list of parameters of the function. + Parameters []FunctionParameterInfo +} + +type GetActivationUrlInfoRequest struct { + // The one time activation url. It also accepts activation token. + ActivationUrl *string +} + +type GetActivationUrlInfoResponse struct { +} + +type GetFederationPolicyRequest struct { + // Name of the recipient. This is the name of the recipient for which the policy + // is being retrieved. + RecipientName *string + // Name of the policy. This is the name of the policy to be retrieved. + Name *string +} + +type GetProviderRequest struct { + // Name of the provider. + NameArg *string +} + +type GetRecipientRequest struct { + // Name of the recipient. + Name *string +} + +type GetRecipientSharePermissionsResponse struct { + // An array of data share permissions for a recipient. + PermissionsOut []ShareToPrivilegeAssignment + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type GetSharePermissionsResponse struct { + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string + // The privileges assigned to each principal + PrivilegeAssignments []PrivilegeAssignment +} + +type GetShareRequest struct { + // The name of the share. + Name *string + // Query for data to include in the share. + IncludeSharedData *bool +} + +type IpAccessList struct { + // Allowed IP Addresses in CIDR notation. Limit of 100. + AllowedIpAddresses []string +} + +type ListFederationPoliciesRequest struct { + // Name of the recipient. This is the name of the recipient for which the + // policies are being listed. + RecipientName *string + MaxResults *int + PageToken *string +} + +type ListFederationPoliciesResponse struct { + Policies []FederationPolicy + NextPageToken *string +} + +// Request to fetch the list of assets of a share that is shared with the +// recipient.. +type ListProviderShareAssetsRequest struct { + // The name of the provider who owns the share. + ProviderNameArg *string + // The name of the share. + ShareNameArg *string + // Maximum number of tables to return. + TableMaxResults *int + // Maximum number of functions to return. + FunctionMaxResults *int + // Maximum number of volumes to return. + VolumeMaxResults *int + // Maximum number of notebooks to return. + NotebookMaxResults *int +} + +// Response to ListProviderShareAssets, which contains the list of assets of a +// share.. +type ListProviderShareAssetsResponse struct { + // The list of tables in the share. + Tables []Table + // The list of functions in the share. + Functions []Function + // The list of notebooks in the share. + Notebooks []NotebookFile + // The list of volumes in the share. + Volumes []Volume + // The metadata of the share. + Share *Share +} + +type ListProviderSharesRequest struct { + // Name of the provider in which to list shares. + ProviderNameArg *string + // Maximum number of shares to return. - when set to 0, the page length is set + // to a server configured value (recommended); - when set to a value greater + // than 0, the page length is the minimum of this value and a server configured + // value; - when set to a value less than 0, an invalid parameter error is + // returned; - If not set, all valid shares are returned (not recommended). - + // Note: The number of returned shares might be less than the specified + // max_results size, even zero. The only definitive indication that no further + // shares can be fetched is when the next_page_token is unset from the response. + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListProviderSharesResponse struct { + // An array of provider shares. + Shares []ProviderShare + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type ListProvidersRequest struct { + // If not provided, all providers will be returned. If no providers exist with + // this ID, no results will be returned. + DataProviderGlobalMetastoreId *string + // Maximum number of providers to return. - when set to 0, the page length is + // set to a server configured value (recommended); - when set to a value greater + // than 0, the page length is the minimum of this value and a server configured + // value; - when set to a value less than 0, an invalid parameter error is + // returned; - If not set, all valid providers are returned (not recommended). - + // Note: The number of returned providers might be less than the specified + // max_results size, even zero. The only definitive indication that no further + // providers can be fetched is when the next_page_token is unset from the + // response. + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListProvidersResponse struct { + // An array of provider information objects. + Providers []ProviderInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type ListRecipientSharePermissionsRequest struct { + // The name of the Recipient. + Name *string + // Maximum number of permissions to return. - when set to 0, the page length is + // set to a server configured value (recommended); - when set to a value greater + // than 0, the page length is the minimum of this value and a server configured + // value; - when set to a value less than 0, an invalid parameter error is + // returned; - If not set, all valid permissions are returned (not recommended). + // - Note: The number of returned permissions might be less than the specified + // max_results size, even zero. The only definitive indication that no further + // permissions can be fetched is when the next_page_token is unset from the + // response. + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListRecipientsRequest struct { + // If not provided, all recipients will be returned. If no recipients exist with + // this ID, no results will be returned. + DataRecipientGlobalMetastoreId *string + // Maximum number of recipients to return. - when set to 0, the page length is + // set to a server configured value (recommended); - when set to a value greater + // than 0, the page length is the minimum of this value and a server configured + // value; - when set to a value less than 0, an invalid parameter error is + // returned; - If not set, all valid recipients are returned (not recommended). + // - Note: The number of returned recipients might be less than the specified + // max_results size, even zero. The only definitive indication that no further + // recipients can be fetched is when the next_page_token is unset from the + // response. + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListRecipientsResponse struct { + // An array of recipient information objects. + Recipients []RecipientInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type ListSharePermissionsRequest struct { + // The name of the share. + Name *string + // Maximum number of permissions to return. - when set to 0, the page length is + // set to a server configured value (recommended); - when set to a value greater + // than 0, the page length is the minimum of this value and a server configured + // value; - when set to a value less than 0, an invalid parameter error is + // returned; - If not set, all valid permissions are returned (not recommended). + // - Note: The number of returned permissions might be less than the specified + // max_results size, even zero. The only definitive indication that no further + // permissions can be fetched is when the next_page_token is unset from the + // response. + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListSharesRequest struct { + // Maximum number of shares to return. - when set to 0, the page length is set + // to a server configured value (recommended); - when set to a value greater + // than 0, the page length is the minimum of this value and a server configured + // value; - when set to a value less than 0, an invalid parameter error is + // returned; - If not set, all valid shares are returned (not recommended). - + // Note: The number of returned shares might be less than the specified + // max_results size, even zero. The only definitive indication that no further + // shares can be fetched is when the next_page_token is unset from the response. + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListSharesResponse struct { + // An array of data share information objects. + Shares []ShareInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type NotebookFile struct { + // Name of the notebook file. + Name *string + // The name of the share that the notebook file belongs to. + Share *string + // The id of the share that the notebook file belongs to. + ShareId *string + // The id of the notebook file. + Id *string + // The comment of the notebook file. + Comment *string + // The tags of the notebook file. + Tags []TagKeyValue +} + +// Specifies the policy to use for validating OIDC claims in your federated +// tokens from Delta Sharing Clients. Refer to +// https://docs.databricks.com/en/delta-sharing/create-recipient-oidc-fed for +// more details.. +type OidcFederationPolicy struct { + // The required token issuer, as specified in the 'iss' claim of federated + // tokens. + Issuer *string + // The claim that contains the subject of the token. Depending on the identity + // provider and the use case (U2M or M2M), this can vary: - For Entra ID (AAD): + // * U2M flow (group access): Use `groups`. * U2M flow (user access): Use `oid`. + // * M2M flow (OAuth App access): Use `azp`. - For other IdPs, refer to the + // specific IdP documentation. + // + // Supported `subject_claim` values are: - `oid`: Object ID of the user. - + // `azp`: Client ID of the OAuth app. - `groups`: Object ID of the group. - + // `sub`: Subject identifier for other use cases. + SubjectClaim *string + // The required token subject, as specified in the subject claim of federated + // tokens. The subject claim identifies the identity of the user or machine + // accessing the resource. Examples for Entra ID (AAD): - U2M flow (group + // access): If the subject claim is `groups`, this must be the Object ID of the + // group in Entra ID. - U2M flow (user access): If the subject claim is `oid`, + // this must be the Object ID of the user in Entra ID. - M2M flow (OAuth App + // access): If the subject claim is `azp`, this must be the client ID of the + // OAuth app registered in Entra ID. + Subject *string + // The allowed token audiences, as specified in the 'aud' claim of federated + // tokens. The audience identifier is intended to represent the recipient of the + // token. Can be any non-empty string value. As long as the audience in the + // token matches at least one audience in the policy, + Audiences []string +} + +// PartitionSpecification defines the format of partition filtering +// specification for shared tables. It consists of a list of Partitions which in +// turn include a list of PartitionValues. - Partitions inside a single +// PartitionSpecification have OR logical relationship. - PartitionValues inside +// a single Partition have AND logical relationship. - PartitionValue.name must +// have distinct values inside a single Partition.. +type PartitionSpecification struct { +} + +type PartitionSpecification_Partition struct { + // An array of partition values. + Values []PartitionSpecification_Partition_PartitionValue +} + +type PartitionSpecification_Partition_PartitionValue struct { + // The name of the partition column. + Name *string + // The value of the partition column. When this value is not set, it means + // `null` value. When this field is set, field `recipient_property_key` can not + // be set. + Value *string + // The key of a Delta Sharing recipient's property. For example + // "databricks-account-id". When this field is set, field `value` can not be + // set. + RecipientPropertyKey *string + // The operator to apply for the value. + Op PartitionSpecification_Partition_PartitionValue_PartitionValueOp +} + +type PermissionsChange struct { + // The principal whose privileges we are changing. Only one of principal or + // principal_id should be specified, never both at the same time. + Principal *string + // The set of privileges to add. + Add []string + // The set of privileges to remove. + Remove []string +} + +type PrivilegeAssignment struct { + // The principal (user email address or group name). For deleted principals, + // `principal` is empty while `principal_id` is populated. + Principal *string + // The privileges assigned to the principal. + Privileges []string +} + +// An object with __properties__ containing map of key-value properties attached +// to the securable.. +type PropertiesKvPairs struct { + // A map of key-value properties attached to the securable. + Properties map[string]string +} + +type ProviderInfo struct { + // The name of the Provider. + Name *string + AuthenticationType DeltaSharingAuthenticationType + // This field is required when the __authentication_type__ is **TOKEN**, + // **OAUTH_CLIENT_CREDENTIALS** or not provided. + RecipientProfileStr *string + // Description about the provider. + Comment *string + // Username of Provider owner. + Owner *string + // The recipient profile. This field is only present when the + // authentication_type is `TOKEN` or `OAUTH_CLIENT_CREDENTIALS`. + RecipientProfile *RecipientProfile + // Time at which this Provider was created, in epoch milliseconds. + CreatedAt *int64 + // Username of Provider creator. + CreatedBy *string + // Time at which this Provider was created, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified Provider. + UpdatedBy *string + // Cloud vendor of the provider's UC metastore. This field is only present when + // the __authentication_type__ is **DATABRICKS**. + Cloud *string + // Cloud region of the provider's UC metastore. This field is only present when + // the __authentication_type__ is **DATABRICKS**. + Region *string + // UUID of the provider's UC metastore. This field is only present when the + // __authentication_type__ is **DATABRICKS**. + MetastoreId *string + // The global UC metastore id of the data provider. This field is only present + // when the __authentication_type__ is **DATABRICKS**. The identifier is of + // format __cloud__:__region__:__metastore-uuid__. + DataProviderGlobalMetastoreId *string +} + +type ProviderShare struct { + // The name of the Provider Share. + Name *string +} + +type RecipientInfo struct { + // Name of Recipient. + Name *string + AuthenticationType DeltaSharingAuthenticationType + // The one-time sharing code provided by the data recipient. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + SharingCode *string + // The global Unity Catalog metastore id provided by the data recipient. This + // field is only present when the __authentication_type__ is **DATABRICKS**. The + // identifier is of format __cloud__:__region__:__metastore-uuid__. + DataRecipientGlobalMetastoreId *string + // Username of the recipient owner. + Owner *string + // Description about the recipient. + Comment *string + // IP Access List + IpAccessList *IpAccessList + // Recipient properties as map of string key-value pairs. When provided in + // update request, the specified properties will override the existing + // properties. To add and remove properties, one would need to perform a + // read-modify-write. + PropertiesKvpairs *PropertiesKvPairs + // Expiration timestamp of the token, in epoch milliseconds. + ExpirationTime *int64 + // Full activation url to retrieve the access token. It will be empty if the + // token is already retrieved. + ActivationUrl *string + // A boolean status field showing whether the Recipient's activation URL has + // been exercised or not. + Activated *bool + // Time at which this recipient was created, in epoch milliseconds. + CreatedAt *int64 + // Username of recipient creator. + CreatedBy *string + // This field is only present when the __authentication_type__ is **TOKEN**. + Tokens []RecipientTokenInfo + // Time at which the recipient was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of recipient updater. + UpdatedBy *string + // Cloud vendor of the recipient's Unity Catalog Metastore. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + Cloud *string + // Cloud region of the recipient's Unity Catalog Metastore. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + Region *string + // Unique identifier of recipient's Unity Catalog Metastore. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + MetastoreId *string + // [Create,Update:IGN] common - id of the recipient + Id *string +} + +type RecipientProfile struct { + // The version number of the recipient's credentials on a share. + ShareCredentialsVersion *int + // The endpoint for the share to be used by the recipient. + Endpoint *string + // The token used to authorize the recipient. + BearerToken *string +} + +type RecipientTokenInfo struct { + // Unique ID of the recipient token. + Id *string + // Time at which this recipient token was created, in epoch milliseconds. + CreatedAt *int64 + // Username of recipient token creator. + CreatedBy *string + // Full activation URL to retrieve the access token. It will be empty if the + // token is already retrieved. + ActivationUrl *string + // Expiration timestamp of the token in epoch milliseconds. + ExpirationTime *int64 + // Time at which this recipient token was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of recipient token updater. + UpdatedBy *string +} + +type RegisteredModelAlias struct { + // Name of the alias. + AliasName *string + // Numeric model version that alias will reference. + VersionNum *int64 +} + +type RetrieveTokenRequest struct { + // The one time activation url. It also accepts activation token. + ActivationUrl *string +} + +type RetrieveTokenResponse struct { + // These field names must follow the delta sharing protocol. + ShareCredentialsVersion *int + // The token used to authorize the recipient. + BearerToken *string + // The endpoint for the share to be used by the recipient. + Endpoint *string + // Expiration timestamp of the token in epoch milliseconds. + ExpirationTime *string +} + +type RotateRecipientTokenRequest struct { + // The name of the Recipient. + Name *string + // The expiration time of the bearer token in ISO 8601 format. This will set the + // expiration_time of existing token only to a smaller timestamp, it cannot + // extend the expiration_time. Use 0 to expire the existing token immediately, + // negative number will return an error. + ExistingTokenExpireInSeconds *int64 +} + +type Share struct { + Name *string + Id *string +} + +type ShareInfo struct { + // Name of the share. + Name *string + // Username of current owner of share. + Owner *string + // User-provided free-form text description. + Comment *string + // Storage root URL for the share. + StorageRoot *string + // A list of shared data objects within the share. + Objects []SharedDataObject + // Time at which this share was created, in epoch milliseconds. + CreatedAt *int64 + // Username of share creator. + CreatedBy *string + // Time at which this share was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of share updater. + UpdatedBy *string + // Storage Location URL (full path) for the share. + StorageLocation *string +} + +type ShareToPrivilegeAssignment struct { + // The share name. + ShareName *string + // The privileges assigned to the principal. + PrivilegeAssignments []PrivilegeAssignment +} + +type SharedDataObject struct { + // A fully qualified name that uniquely identifies a data object. For example, a + // table's fully qualified name is in the format of + // `..`, + Name *string + // The type of the data object. + DataObjectType *string + // The time when this data object is added to the share, in epoch milliseconds. + AddedAt *int64 + // Username of the sharer. + AddedBy *string + // A user-provided comment when adding the data object to the share. + Comment *string + // A user-provided alias name for table-like data objects within the share. + // + // Use this field for table-like objects (for example: TABLE, VIEW, + // MATERIALIZED_VIEW, STREAMING_TABLE, FOREIGN_TABLE). For non-table objects + // (for example: VOLUME, MODEL, NOTEBOOK_FILE, FUNCTION), use `string_shared_as` + // instead. + // + // Important: For non-table objects, this field must be omitted entirely. + // + // Format: Must be a 2-part name `.` (e.g., + // "sales_schema.orders_table") - Both schema and table names must contain only + // alphanumeric characters and underscores - No periods, spaces, forward + // slashes, or control characters are allowed within each part - Do not include + // the catalog name (use 2 parts, not 3) + // + // Behavior: - If not provided, the service automatically generates the alias as + // `.
` from the object's original name - If you don't want to + // specify this field, omit it entirely from the request (do not pass an empty + // string) - The `shared_as` name must be unique within the share + // + // Examples: - Valid: "analytics_schema.customer_view" - Invalid: + // "catalog.analytics_schema.customer_view" (3 parts not allowed) - Invalid: + // "analytics-schema.customer-view" (hyphens not allowed) + SharedAs *string + // Whether to enable cdf or indicate if cdf is enabled on the shared object. + CdfEnabled *bool + // Whether to enable or disable sharing of data history. If not specified, the + // default is **DISABLED**. + HistoryDataSharingStatus SharedDataObject_HistoryDataSharingStatus_Enum + // The start version associated with the object. This allows data providers to + // control the lowest object version that is accessible by clients. If + // specified, clients can query snapshots or changes for versions >= + // start_version. If not specified, clients can only query starting from the + // version of the object at the time it was added to the share. + // + // NOTE: The start_version should be <= the `current` version of the object. + StartVersion *int64 + // One of: **ACTIVE**, **PERMISSION_DENIED**. + Status SharedDataObject_Status_Enum + // The content of the notebook file when the data object type is NOTEBOOK_FILE. + // This should be base64 encoded. Required for adding a NOTEBOOK_FILE, optional + // for updating, ignored for other types. + Content *string + // A user-provided alias name for non-table data objects within the share. + // + // Use this field for non-table objects (for example: VOLUME, MODEL, + // NOTEBOOK_FILE, FUNCTION). For table-like objects (for example: TABLE, VIEW, + // MATERIALIZED_VIEW, STREAMING_TABLE, FOREIGN_TABLE), use `shared_as` instead. + // + // Important: For table-like objects, this field must be omitted entirely. + // + // Format: - For VOLUME: Must be a 2-part name `.` + // (e.g., "data_schema.ml_models") - For FUNCTION: Must be a 2-part name + // `.` (e.g., "udf_schema.calculate_tax") - For + // MODEL: Must be a 2-part name `.` (e.g., + // "models.prediction_model") - For NOTEBOOK_FILE: Should be the notebook file + // name (e.g., "analysis_notebook.py") - All names must contain only + // alphanumeric characters and underscores - No periods, spaces, forward + // slashes, or control characters are allowed within each part + // + // Behavior: - If not provided, the service automatically generates the alias + // from the object's original name - If you don't want to specify this field, + // omit it entirely from the request (do not pass an empty string) - The + // `string_shared_as` name must be unique for objects of the same type within + // the share + // + // Examples: - Valid for VOLUME: "data_schema.training_data" - Valid for + // FUNCTION: "analytics.calculate_revenue" - Invalid: + // "catalog.data_schema.training_data" (3 parts not allowed for volumes) - + // Invalid: "data-schema.training-data" (hyphens not allowed) + StringSharedAs *string + // Array of partitions for the shared data. + Partitions []PartitionSpecification_Partition +} + +type SharedDataObject_HistoryDataSharingStatus struct { +} + +// Note: This is scoped to prevent future enum name conflicts.. +type SharedDataObject_Status struct { +} + +type Table struct { + // The name of the table. + Name *string + // The name of the schema that the table belongs to. + Schema *string + // The name of the share that the table belongs to. + Share *string + // The id of the share that the table belongs to. + ShareId *string + // The id of the table. + Id *string + // The comment of the table. + Comment *string + // The Tags of the table. + Tags []TagKeyValue + // The name of a materialized table. + MaterializedTableName *string + // The catalog and schema of the materialized table + MaterializationNamespace *string +} + +// A Table in UC as a dependency.. +type TableDependency struct { + SchemaName *string + TableName *string +} + +type TagKeyValue struct { + // name of the tag + Key *string + // value of the tag associated with the key, could be optional + Value *string +} + +type UpdateProviderRequest struct { + // Name of the provider. + NameArg *string + // New name for the provider. + NewName *string + // The name of the Provider. + Name *string + AuthenticationType DeltaSharingAuthenticationType + // This field is required when the __authentication_type__ is **TOKEN**, + // **OAUTH_CLIENT_CREDENTIALS** or not provided. + RecipientProfileStr *string + // Description about the provider. + Comment *string + // Username of Provider owner. + Owner *string + // The recipient profile. This field is only present when the + // authentication_type is `TOKEN` or `OAUTH_CLIENT_CREDENTIALS`. + RecipientProfile *RecipientProfile + // Time at which this Provider was created, in epoch milliseconds. + CreatedAt *int64 + // Username of Provider creator. + CreatedBy *string + // Time at which this Provider was created, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified Provider. + UpdatedBy *string + // Cloud vendor of the provider's UC metastore. This field is only present when + // the __authentication_type__ is **DATABRICKS**. + Cloud *string + // Cloud region of the provider's UC metastore. This field is only present when + // the __authentication_type__ is **DATABRICKS**. + Region *string + // UUID of the provider's UC metastore. This field is only present when the + // __authentication_type__ is **DATABRICKS**. + MetastoreId *string + // The global UC metastore id of the data provider. This field is only present + // when the __authentication_type__ is **DATABRICKS**. The identifier is of + // format __cloud__:__region__:__metastore-uuid__. + DataProviderGlobalMetastoreId *string +} + +type UpdateRecipientRequest struct { + // Name of the recipient. + NameArg *string + // New name for the recipient. . + NewName *string + // Name of Recipient. + Name *string + AuthenticationType DeltaSharingAuthenticationType + // The one-time sharing code provided by the data recipient. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + SharingCode *string + // The global Unity Catalog metastore id provided by the data recipient. This + // field is only present when the __authentication_type__ is **DATABRICKS**. The + // identifier is of format __cloud__:__region__:__metastore-uuid__. + DataRecipientGlobalMetastoreId *string + // Username of the recipient owner. + Owner *string + // Description about the recipient. + Comment *string + // IP Access List + IpAccessList *IpAccessList + // Recipient properties as map of string key-value pairs. When provided in + // update request, the specified properties will override the existing + // properties. To add and remove properties, one would need to perform a + // read-modify-write. + PropertiesKvpairs *PropertiesKvPairs + // Expiration timestamp of the token, in epoch milliseconds. + ExpirationTime *int64 + // Full activation url to retrieve the access token. It will be empty if the + // token is already retrieved. + ActivationUrl *string + // A boolean status field showing whether the Recipient's activation URL has + // been exercised or not. + Activated *bool + // Time at which this recipient was created, in epoch milliseconds. + CreatedAt *int64 + // Username of recipient creator. + CreatedBy *string + // This field is only present when the __authentication_type__ is **TOKEN**. + Tokens []RecipientTokenInfo + // Time at which the recipient was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of recipient updater. + UpdatedBy *string + // Cloud vendor of the recipient's Unity Catalog Metastore. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + Cloud *string + // Cloud region of the recipient's Unity Catalog Metastore. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + Region *string + // Unique identifier of recipient's Unity Catalog Metastore. This field is only + // present when the __authentication_type__ is **DATABRICKS**. + MetastoreId *string + // [Create,Update:IGN] common - id of the recipient + Id *string +} + +type UpdateSharePermissionsRequest struct { + // The name of the share. + Name *string + // Optional. Whether to return the latest permissions list of the share in the + // response. + OmitPermissionsList *bool + // Array of permissions change objects. + Changes []PermissionsChange +} + +type UpdateSharePermissionsResponse struct { + // The privileges assigned to each principal + PrivilegeAssignments []PrivilegeAssignment +} + +type UpdateShareRequest struct { + // The name of the share. + NameArg *string + // New name for the share. + NewName *string + // Array of shared data object updates. + Updates []UpdateShareRequest_SharedDataObjectUpdate + // Name of the share. + Name *string + // Username of current owner of share. + Owner *string + // User-provided free-form text description. + Comment *string + // Storage root URL for the share. + StorageRoot *string + // A list of shared data objects within the share. + Objects []SharedDataObject + // Time at which this share was created, in epoch milliseconds. + CreatedAt *int64 + // Username of share creator. + CreatedBy *string + // Time at which this share was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of share updater. + UpdatedBy *string + // Storage Location URL (full path) for the share. + StorageLocation *string +} + +type UpdateShareRequest_SharedDataObjectUpdate struct { + // One of: **ADD**, **REMOVE**, **UPDATE**. + Action UpdateShareRequest_SharedDataObjectUpdate_Action + // The data object that is being added, removed, or updated. The maximum number + // update data objects allowed is a 100. + DataObject *SharedDataObject +} + +type Volume struct { + // The name of the volume. + Name *string + // This id maps to the shared_volume_id in database Recipient needs + // shared_volume_id for recon to check if this volume is already in recipient's + // DB or not. + Id *string + // The name of the schema that the volume belongs to. + Schema *string + // The name of the share that the volume belongs to. + Share *string + // / The id of the share that the volume belongs to. + ShareId *string + // The comment of the volume. + Comment *string + // The tags of the volume. + Tags []TagKeyValue +} diff --git a/sharing/v1/wire.go b/sharing/v1/wire.go new file mode 100755 index 0000000..4aeee5d --- /dev/null +++ b/sharing/v1/wire.go @@ -0,0 +1,1636 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package sharing + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +type createFederationPolicyRequestWire struct { + RecipientName *string `json:"recipient_name,omitempty"` + Policy *federationPolicyWire `json:"policy,omitempty"` +} + +func createFederationPolicyRequestToWire(v *CreateFederationPolicyRequest) (*createFederationPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + policyWireValue, err := federationPolicyToWire(v.Policy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateFederationPolicyRequest.Policy", err) + } + return &createFederationPolicyRequestWire{ + RecipientName: v.RecipientName, + Policy: policyWireValue, + }, nil +} + +type createProviderRequestWire struct { + Name *string `json:"name,omitempty"` + AuthenticationType DeltaSharingAuthenticationType `json:"authentication_type,omitempty"` + RecipientProfileStr *string `json:"recipient_profile_str,omitempty"` + Comment *string `json:"comment,omitempty"` + Owner *string `json:"owner,omitempty"` + RecipientProfile *recipientProfileWire `json:"recipient_profile,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Cloud *string `json:"cloud,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + DataProviderGlobalMetastoreId *string `json:"data_provider_global_metastore_id,omitempty"` +} + +func createProviderRequestToWire(v *CreateProviderRequest) (*createProviderRequestWire, error) { + if v == nil { + return nil, nil + } + recipientProfileWireValue, err := recipientProfileToWire(v.RecipientProfile) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateProviderRequest.RecipientProfile", err) + } + return &createProviderRequestWire{ + Name: v.Name, + AuthenticationType: v.AuthenticationType, + RecipientProfileStr: v.RecipientProfileStr, + Comment: v.Comment, + Owner: v.Owner, + RecipientProfile: recipientProfileWireValue, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + Cloud: v.Cloud, + Region: v.Region, + MetastoreId: v.MetastoreId, + DataProviderGlobalMetastoreId: v.DataProviderGlobalMetastoreId, + }, nil +} + +type createRecipientRequestWire struct { + Name *string `json:"name,omitempty"` + AuthenticationType DeltaSharingAuthenticationType `json:"authentication_type,omitempty"` + SharingCode *string `json:"sharing_code,omitempty"` + DataRecipientGlobalMetastoreId *string `json:"data_recipient_global_metastore_id,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + IpAccessList *ipAccessListWire `json:"ip_access_list,omitempty"` + PropertiesKvpairs *propertiesKvPairsWire `json:"properties_kvpairs,omitempty"` + ExpirationTime *int64 `json:"expiration_time,omitempty"` + ActivationUrl *string `json:"activation_url,omitempty"` + Activated *bool `json:"activated,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + Tokens []recipientTokenInfoWire `json:"tokens,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Cloud *string `json:"cloud,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + Id *string `json:"id,omitempty"` +} + +func createRecipientRequestToWire(v *CreateRecipientRequest) (*createRecipientRequestWire, error) { + if v == nil { + return nil, nil + } + ipAccessListWireValue, err := ipAccessListToWire(v.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRecipientRequest.IpAccessList", err) + } + propertiesKvpairsWireValue, err := propertiesKvPairsToWire(v.PropertiesKvpairs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRecipientRequest.PropertiesKvpairs", err) + } + tokensWireValue, err := convertSlice(v.Tokens, recipientTokenInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRecipientRequest.Tokens", err) + } + return &createRecipientRequestWire{ + Name: v.Name, + AuthenticationType: v.AuthenticationType, + SharingCode: v.SharingCode, + DataRecipientGlobalMetastoreId: v.DataRecipientGlobalMetastoreId, + Owner: v.Owner, + Comment: v.Comment, + IpAccessList: ipAccessListWireValue, + PropertiesKvpairs: propertiesKvpairsWireValue, + ExpirationTime: v.ExpirationTime, + ActivationUrl: v.ActivationUrl, + Activated: v.Activated, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + Tokens: tokensWireValue, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + Cloud: v.Cloud, + Region: v.Region, + MetastoreId: v.MetastoreId, + Id: v.Id, + }, nil +} + +type createShareRequestWire struct { + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + Objects []sharedDataObjectWire `json:"objects,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` +} + +func createShareRequestToWire(v *CreateShareRequest) (*createShareRequestWire, error) { + if v == nil { + return nil, nil + } + objectsWireValue, err := convertSlice(v.Objects, sharedDataObjectToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateShareRequest.Objects", err) + } + return &createShareRequestWire{ + Name: v.Name, + Owner: v.Owner, + Comment: v.Comment, + StorageRoot: v.StorageRoot, + Objects: objectsWireValue, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + StorageLocation: v.StorageLocation, + }, nil +} + +type dependencyWire struct { + Table *tableDependencyWire `json:"table,omitempty"` + Function *functionDependencyWire `json:"function,omitempty"` +} + +func dependencyFromWire(w *dependencyWire) (*Dependency, error) { + if w == nil { + return nil, nil + } + valueMembers := 0 + if w.Table != nil { + valueMembers++ + } + if w.Function != nil { + valueMembers++ + } + if valueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Dependency.Value") + } + var valueSelection isDependency_Value + switch { + case w.Table != nil: + valueTableConverted, err := tableDependencyFromWire(w.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Table", err) + } + valueSelection = &Dependency_Value_Table{Table: *valueTableConverted} + case w.Function != nil: + valueFunctionConverted, err := functionDependencyFromWire(w.Function) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Function", err) + } + valueSelection = &Dependency_Value_Function{Function: *valueFunctionConverted} + } + return &Dependency{ + Value: valueSelection, + }, nil +} + +type dependencyListWire struct { + Dependencies []dependencyWire `json:"dependencies,omitempty"` +} + +func dependencyListFromWire(w *dependencyListWire) (*DependencyList, error) { + if w == nil { + return nil, nil + } + dependenciesPublicValue, err := convertSlice(w.Dependencies, dependencyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DependencyList.Dependencies", err) + } + return &DependencyList{ + Dependencies: dependenciesPublicValue, + }, nil +} + +type federationPolicyWire struct { + Name *string `json:"name,omitempty"` + OidcPolicy *oidcFederationPolicyWire `json:"oidc_policy,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + Comment *string `json:"comment,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + Id *string `json:"id,omitempty"` +} + +func federationPolicyToWire(v *FederationPolicy) (*federationPolicyWire, error) { + if v == nil { + return nil, nil + } + var policyOidcPolicyWire *oidcFederationPolicyWire + switch value := v.Policy.(type) { + case nil: + case *FederationPolicy_Policy_OidcPolicy: + if value != nil { + policyOidcPolicyConverted, err := oidcFederationPolicyToWire(&value.OidcPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FederationPolicy.Policy.OidcPolicy", err) + } + policyOidcPolicyWire = policyOidcPolicyConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "FederationPolicy.Policy", value) + } + return &federationPolicyWire{ + Name: v.Name, + OidcPolicy: policyOidcPolicyWire, + CreateTime: v.CreateTime, + Comment: v.Comment, + UpdateTime: v.UpdateTime, + Id: v.Id, + }, nil +} + +func federationPolicyFromWire(w *federationPolicyWire) (*FederationPolicy, error) { + if w == nil { + return nil, nil + } + policyMembers := 0 + if w.OidcPolicy != nil { + policyMembers++ + } + if policyMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "FederationPolicy.Policy") + } + var policySelection isFederationPolicy_Policy + switch { + case w.OidcPolicy != nil: + policyOidcPolicyConverted, err := oidcFederationPolicyFromWire(w.OidcPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FederationPolicy.Policy.OidcPolicy", err) + } + policySelection = &FederationPolicy_Policy_OidcPolicy{OidcPolicy: *policyOidcPolicyConverted} + } + return &FederationPolicy{ + Name: w.Name, + CreateTime: w.CreateTime, + Comment: w.Comment, + UpdateTime: w.UpdateTime, + Id: w.Id, + Policy: policySelection, + }, nil +} + +type functionWire struct { + Name *string `json:"name,omitempty"` + Schema *string `json:"schema,omitempty"` + Share *string `json:"share,omitempty"` + ShareId *string `json:"share_id,omitempty"` + Id *string `json:"id,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + Comment *string `json:"comment,omitempty"` + Aliases []registeredModelAliasWire `json:"aliases,omitempty"` + Tags []tagKeyValueWire `json:"tags,omitempty"` + SecurableKind SharedSecurableKind `json:"securable_kind,omitempty"` + FullDataType *string `json:"full_data_type,omitempty"` + DataType ColumnTypeName `json:"data_type,omitempty"` + RoutineDefinition *string `json:"routine_definition,omitempty"` + InputParams *functionParameterInfosWire `json:"input_params,omitempty"` + DependencyList *dependencyListWire `json:"dependency_list,omitempty"` + Properties *string `json:"properties,omitempty"` +} + +func functionFromWire(w *functionWire) (*Function, error) { + if w == nil { + return nil, nil + } + aliasesPublicValue, err := convertSlice(w.Aliases, registeredModelAliasFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Function.Aliases", err) + } + tagsPublicValue, err := convertSlice(w.Tags, tagKeyValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Function.Tags", err) + } + inputParamsPublicValue, err := functionParameterInfosFromWire(w.InputParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Function.InputParams", err) + } + dependencyListPublicValue, err := dependencyListFromWire(w.DependencyList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Function.DependencyList", err) + } + return &Function{ + Name: w.Name, + Schema: w.Schema, + Share: w.Share, + ShareId: w.ShareId, + Id: w.Id, + StorageLocation: w.StorageLocation, + Comment: w.Comment, + Aliases: aliasesPublicValue, + Tags: tagsPublicValue, + SecurableKind: w.SecurableKind, + FullDataType: w.FullDataType, + DataType: w.DataType, + RoutineDefinition: w.RoutineDefinition, + InputParams: inputParamsPublicValue, + DependencyList: dependencyListPublicValue, + Properties: w.Properties, + }, nil +} + +type functionDependencyWire struct { + SchemaName *string `json:"schema_name,omitempty"` + FunctionName *string `json:"function_name,omitempty"` +} + +func functionDependencyFromWire(w *functionDependencyWire) (*FunctionDependency, error) { + if w == nil { + return nil, nil + } + return &FunctionDependency{ + SchemaName: w.SchemaName, + FunctionName: w.FunctionName, + }, nil +} + +type functionParameterInfoWire struct { + Name *string `json:"name,omitempty"` + TypeText *string `json:"type_text,omitempty"` + TypeJson *string `json:"type_json,omitempty"` + TypeName ColumnTypeName `json:"type_name,omitempty"` + TypePrecision *int `json:"type_precision,omitempty"` + TypeScale *int `json:"type_scale,omitempty"` + TypeIntervalType *string `json:"type_interval_type,omitempty"` + Position *int `json:"position,omitempty"` + ParameterMode FunctionParameterMode `json:"parameter_mode,omitempty"` + ParameterType FunctionParameterType `json:"parameter_type,omitempty"` + ParameterDefault *string `json:"parameter_default,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func functionParameterInfoFromWire(w *functionParameterInfoWire) (*FunctionParameterInfo, error) { + if w == nil { + return nil, nil + } + return &FunctionParameterInfo{ + Name: w.Name, + TypeText: w.TypeText, + TypeJson: w.TypeJson, + TypeName: w.TypeName, + TypePrecision: w.TypePrecision, + TypeScale: w.TypeScale, + TypeIntervalType: w.TypeIntervalType, + Position: w.Position, + ParameterMode: w.ParameterMode, + ParameterType: w.ParameterType, + ParameterDefault: w.ParameterDefault, + Comment: w.Comment, + }, nil +} + +type functionParameterInfosWire struct { + Parameters []functionParameterInfoWire `json:"parameters,omitempty"` +} + +func functionParameterInfosFromWire(w *functionParameterInfosWire) (*FunctionParameterInfos, error) { + if w == nil { + return nil, nil + } + parametersPublicValue, err := convertSlice(w.Parameters, functionParameterInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FunctionParameterInfos.Parameters", err) + } + return &FunctionParameterInfos{ + Parameters: parametersPublicValue, + }, nil +} + +type getRecipientSharePermissionsResponseWire struct { + PermissionsOut []shareToPrivilegeAssignmentWire `json:"permissions_out,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func getRecipientSharePermissionsResponseFromWire(w *getRecipientSharePermissionsResponseWire) (*GetRecipientSharePermissionsResponse, error) { + if w == nil { + return nil, nil + } + permissionsOutPublicValue, err := convertSlice(w.PermissionsOut, shareToPrivilegeAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetRecipientSharePermissionsResponse.PermissionsOut", err) + } + return &GetRecipientSharePermissionsResponse{ + PermissionsOut: permissionsOutPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type getSharePermissionsResponseWire struct { + NextPageToken *string `json:"next_page_token,omitempty"` + PrivilegeAssignments []privilegeAssignmentWire `json:"privilege_assignments,omitempty"` +} + +func getSharePermissionsResponseFromWire(w *getSharePermissionsResponseWire) (*GetSharePermissionsResponse, error) { + if w == nil { + return nil, nil + } + privilegeAssignmentsPublicValue, err := convertSlice(w.PrivilegeAssignments, privilegeAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetSharePermissionsResponse.PrivilegeAssignments", err) + } + return &GetSharePermissionsResponse{ + NextPageToken: w.NextPageToken, + PrivilegeAssignments: privilegeAssignmentsPublicValue, + }, nil +} + +type getShareRequestWire struct { + Name *string `json:"name,omitempty"` + IncludeSharedData *bool `json:"include_shared_data,omitempty"` +} + +func getShareRequestToWire(v *GetShareRequest) (*getShareRequestWire, error) { + if v == nil { + return nil, nil + } + return &getShareRequestWire{ + Name: v.Name, + IncludeSharedData: v.IncludeSharedData, + }, nil +} + +type ipAccessListWire struct { + AllowedIpAddresses []string `json:"allowed_ip_addresses,omitempty"` +} + +func ipAccessListToWire(v *IpAccessList) (*ipAccessListWire, error) { + if v == nil { + return nil, nil + } + return &ipAccessListWire{ + AllowedIpAddresses: v.AllowedIpAddresses, + }, nil +} + +func ipAccessListFromWire(w *ipAccessListWire) (*IpAccessList, error) { + if w == nil { + return nil, nil + } + return &IpAccessList{ + AllowedIpAddresses: w.AllowedIpAddresses, + }, nil +} + +type listFederationPoliciesRequestWire struct { + RecipientName *string `json:"recipient_name,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listFederationPoliciesRequestToWire(v *ListFederationPoliciesRequest) (*listFederationPoliciesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listFederationPoliciesRequestWire{ + RecipientName: v.RecipientName, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listFederationPoliciesResponseWire struct { + Policies []federationPolicyWire `json:"policies,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listFederationPoliciesResponseFromWire(w *listFederationPoliciesResponseWire) (*ListFederationPoliciesResponse, error) { + if w == nil { + return nil, nil + } + policiesPublicValue, err := convertSlice(w.Policies, federationPolicyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListFederationPoliciesResponse.Policies", err) + } + return &ListFederationPoliciesResponse{ + Policies: policiesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listProviderShareAssetsRequestWire struct { + ProviderNameArg *string `json:"provider_name_arg,omitempty"` + ShareNameArg *string `json:"share_name_arg,omitempty"` + TableMaxResults *int `json:"table_max_results,omitempty"` + FunctionMaxResults *int `json:"function_max_results,omitempty"` + VolumeMaxResults *int `json:"volume_max_results,omitempty"` + NotebookMaxResults *int `json:"notebook_max_results,omitempty"` +} + +func listProviderShareAssetsRequestToWire(v *ListProviderShareAssetsRequest) (*listProviderShareAssetsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listProviderShareAssetsRequestWire{ + ProviderNameArg: v.ProviderNameArg, + ShareNameArg: v.ShareNameArg, + TableMaxResults: v.TableMaxResults, + FunctionMaxResults: v.FunctionMaxResults, + VolumeMaxResults: v.VolumeMaxResults, + NotebookMaxResults: v.NotebookMaxResults, + }, nil +} + +type listProviderShareAssetsResponseWire struct { + Tables []tableWire `json:"tables,omitempty"` + Functions []functionWire `json:"functions,omitempty"` + Notebooks []notebookFileWire `json:"notebooks,omitempty"` + Volumes []volumeWire `json:"volumes,omitempty"` + Share *shareWire `json:"share,omitempty"` +} + +func listProviderShareAssetsResponseFromWire(w *listProviderShareAssetsResponseWire) (*ListProviderShareAssetsResponse, error) { + if w == nil { + return nil, nil + } + tablesPublicValue, err := convertSlice(w.Tables, tableFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListProviderShareAssetsResponse.Tables", err) + } + functionsPublicValue, err := convertSlice(w.Functions, functionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListProviderShareAssetsResponse.Functions", err) + } + notebooksPublicValue, err := convertSlice(w.Notebooks, notebookFileFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListProviderShareAssetsResponse.Notebooks", err) + } + volumesPublicValue, err := convertSlice(w.Volumes, volumeFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListProviderShareAssetsResponse.Volumes", err) + } + sharePublicValue, err := shareFromWire(w.Share) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListProviderShareAssetsResponse.Share", err) + } + return &ListProviderShareAssetsResponse{ + Tables: tablesPublicValue, + Functions: functionsPublicValue, + Notebooks: notebooksPublicValue, + Volumes: volumesPublicValue, + Share: sharePublicValue, + }, nil +} + +type listProviderSharesRequestWire struct { + ProviderNameArg *string `json:"provider_name_arg,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listProviderSharesRequestToWire(v *ListProviderSharesRequest) (*listProviderSharesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listProviderSharesRequestWire{ + ProviderNameArg: v.ProviderNameArg, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listProviderSharesResponseWire struct { + Shares []providerShareWire `json:"shares,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listProviderSharesResponseFromWire(w *listProviderSharesResponseWire) (*ListProviderSharesResponse, error) { + if w == nil { + return nil, nil + } + sharesPublicValue, err := convertSlice(w.Shares, providerShareFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListProviderSharesResponse.Shares", err) + } + return &ListProviderSharesResponse{ + Shares: sharesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listProvidersRequestWire struct { + DataProviderGlobalMetastoreId *string `json:"data_provider_global_metastore_id,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listProvidersRequestToWire(v *ListProvidersRequest) (*listProvidersRequestWire, error) { + if v == nil { + return nil, nil + } + return &listProvidersRequestWire{ + DataProviderGlobalMetastoreId: v.DataProviderGlobalMetastoreId, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listProvidersResponseWire struct { + Providers []providerInfoWire `json:"providers,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listProvidersResponseFromWire(w *listProvidersResponseWire) (*ListProvidersResponse, error) { + if w == nil { + return nil, nil + } + providersPublicValue, err := convertSlice(w.Providers, providerInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListProvidersResponse.Providers", err) + } + return &ListProvidersResponse{ + Providers: providersPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listRecipientSharePermissionsRequestWire struct { + Name *string `json:"name,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listRecipientSharePermissionsRequestToWire(v *ListRecipientSharePermissionsRequest) (*listRecipientSharePermissionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listRecipientSharePermissionsRequestWire{ + Name: v.Name, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listRecipientsRequestWire struct { + DataRecipientGlobalMetastoreId *string `json:"data_recipient_global_metastore_id,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listRecipientsRequestToWire(v *ListRecipientsRequest) (*listRecipientsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listRecipientsRequestWire{ + DataRecipientGlobalMetastoreId: v.DataRecipientGlobalMetastoreId, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listRecipientsResponseWire struct { + Recipients []recipientInfoWire `json:"recipients,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listRecipientsResponseFromWire(w *listRecipientsResponseWire) (*ListRecipientsResponse, error) { + if w == nil { + return nil, nil + } + recipientsPublicValue, err := convertSlice(w.Recipients, recipientInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListRecipientsResponse.Recipients", err) + } + return &ListRecipientsResponse{ + Recipients: recipientsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listSharePermissionsRequestWire struct { + Name *string `json:"name,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listSharePermissionsRequestToWire(v *ListSharePermissionsRequest) (*listSharePermissionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSharePermissionsRequestWire{ + Name: v.Name, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listSharesRequestWire struct { + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listSharesRequestToWire(v *ListSharesRequest) (*listSharesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSharesRequestWire{ + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listSharesResponseWire struct { + Shares []shareInfoWire `json:"shares,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listSharesResponseFromWire(w *listSharesResponseWire) (*ListSharesResponse, error) { + if w == nil { + return nil, nil + } + sharesPublicValue, err := convertSlice(w.Shares, shareInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListSharesResponse.Shares", err) + } + return &ListSharesResponse{ + Shares: sharesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type notebookFileWire struct { + Name *string `json:"name,omitempty"` + Share *string `json:"share,omitempty"` + ShareId *string `json:"share_id,omitempty"` + Id *string `json:"id,omitempty"` + Comment *string `json:"comment,omitempty"` + Tags []tagKeyValueWire `json:"tags,omitempty"` +} + +func notebookFileFromWire(w *notebookFileWire) (*NotebookFile, error) { + if w == nil { + return nil, nil + } + tagsPublicValue, err := convertSlice(w.Tags, tagKeyValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "NotebookFile.Tags", err) + } + return &NotebookFile{ + Name: w.Name, + Share: w.Share, + ShareId: w.ShareId, + Id: w.Id, + Comment: w.Comment, + Tags: tagsPublicValue, + }, nil +} + +type oidcFederationPolicyWire struct { + Issuer *string `json:"issuer,omitempty"` + SubjectClaim *string `json:"subject_claim,omitempty"` + Subject *string `json:"subject,omitempty"` + Audiences []string `json:"audiences,omitempty"` +} + +func oidcFederationPolicyToWire(v *OidcFederationPolicy) (*oidcFederationPolicyWire, error) { + if v == nil { + return nil, nil + } + return &oidcFederationPolicyWire{ + Issuer: v.Issuer, + SubjectClaim: v.SubjectClaim, + Subject: v.Subject, + Audiences: v.Audiences, + }, nil +} + +func oidcFederationPolicyFromWire(w *oidcFederationPolicyWire) (*OidcFederationPolicy, error) { + if w == nil { + return nil, nil + } + return &OidcFederationPolicy{ + Issuer: w.Issuer, + SubjectClaim: w.SubjectClaim, + Subject: w.Subject, + Audiences: w.Audiences, + }, nil +} + +type partitionSpecification_PartitionWire struct { + Values []partitionSpecification_Partition_PartitionValueWire `json:"values,omitempty"` +} + +func partitionSpecification_PartitionToWire(v *PartitionSpecification_Partition) (*partitionSpecification_PartitionWire, error) { + if v == nil { + return nil, nil + } + valuesWireValue, err := convertSlice(v.Values, partitionSpecification_Partition_PartitionValueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PartitionSpecification_Partition.Values", err) + } + return &partitionSpecification_PartitionWire{ + Values: valuesWireValue, + }, nil +} + +func partitionSpecification_PartitionFromWire(w *partitionSpecification_PartitionWire) (*PartitionSpecification_Partition, error) { + if w == nil { + return nil, nil + } + valuesPublicValue, err := convertSlice(w.Values, partitionSpecification_Partition_PartitionValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PartitionSpecification_Partition.Values", err) + } + return &PartitionSpecification_Partition{ + Values: valuesPublicValue, + }, nil +} + +type partitionSpecification_Partition_PartitionValueWire struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` + RecipientPropertyKey *string `json:"recipient_property_key,omitempty"` + Op PartitionSpecification_Partition_PartitionValue_PartitionValueOp `json:"op,omitempty"` +} + +func partitionSpecification_Partition_PartitionValueToWire(v *PartitionSpecification_Partition_PartitionValue) (*partitionSpecification_Partition_PartitionValueWire, error) { + if v == nil { + return nil, nil + } + return &partitionSpecification_Partition_PartitionValueWire{ + Name: v.Name, + Value: v.Value, + RecipientPropertyKey: v.RecipientPropertyKey, + Op: v.Op, + }, nil +} + +func partitionSpecification_Partition_PartitionValueFromWire(w *partitionSpecification_Partition_PartitionValueWire) (*PartitionSpecification_Partition_PartitionValue, error) { + if w == nil { + return nil, nil + } + return &PartitionSpecification_Partition_PartitionValue{ + Name: w.Name, + Value: w.Value, + RecipientPropertyKey: w.RecipientPropertyKey, + Op: w.Op, + }, nil +} + +type permissionsChangeWire struct { + Principal *string `json:"principal,omitempty"` + Add []string `json:"add,omitempty"` + Remove []string `json:"remove,omitempty"` +} + +func permissionsChangeToWire(v *PermissionsChange) (*permissionsChangeWire, error) { + if v == nil { + return nil, nil + } + return &permissionsChangeWire{ + Principal: v.Principal, + Add: v.Add, + Remove: v.Remove, + }, nil +} + +type privilegeAssignmentWire struct { + Principal *string `json:"principal,omitempty"` + Privileges []string `json:"privileges,omitempty"` +} + +func privilegeAssignmentFromWire(w *privilegeAssignmentWire) (*PrivilegeAssignment, error) { + if w == nil { + return nil, nil + } + return &PrivilegeAssignment{ + Principal: w.Principal, + Privileges: w.Privileges, + }, nil +} + +type propertiesKvPairsWire struct { + Properties map[string]string `json:"properties,omitempty"` +} + +func propertiesKvPairsToWire(v *PropertiesKvPairs) (*propertiesKvPairsWire, error) { + if v == nil { + return nil, nil + } + return &propertiesKvPairsWire{ + Properties: v.Properties, + }, nil +} + +func propertiesKvPairsFromWire(w *propertiesKvPairsWire) (*PropertiesKvPairs, error) { + if w == nil { + return nil, nil + } + return &PropertiesKvPairs{ + Properties: w.Properties, + }, nil +} + +type providerInfoWire struct { + Name *string `json:"name,omitempty"` + AuthenticationType DeltaSharingAuthenticationType `json:"authentication_type,omitempty"` + RecipientProfileStr *string `json:"recipient_profile_str,omitempty"` + Comment *string `json:"comment,omitempty"` + Owner *string `json:"owner,omitempty"` + RecipientProfile *recipientProfileWire `json:"recipient_profile,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Cloud *string `json:"cloud,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + DataProviderGlobalMetastoreId *string `json:"data_provider_global_metastore_id,omitempty"` +} + +func providerInfoFromWire(w *providerInfoWire) (*ProviderInfo, error) { + if w == nil { + return nil, nil + } + recipientProfilePublicValue, err := recipientProfileFromWire(w.RecipientProfile) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProviderInfo.RecipientProfile", err) + } + return &ProviderInfo{ + Name: w.Name, + AuthenticationType: w.AuthenticationType, + RecipientProfileStr: w.RecipientProfileStr, + Comment: w.Comment, + Owner: w.Owner, + RecipientProfile: recipientProfilePublicValue, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + Cloud: w.Cloud, + Region: w.Region, + MetastoreId: w.MetastoreId, + DataProviderGlobalMetastoreId: w.DataProviderGlobalMetastoreId, + }, nil +} + +type providerShareWire struct { + Name *string `json:"name,omitempty"` +} + +func providerShareFromWire(w *providerShareWire) (*ProviderShare, error) { + if w == nil { + return nil, nil + } + return &ProviderShare{ + Name: w.Name, + }, nil +} + +type recipientInfoWire struct { + Name *string `json:"name,omitempty"` + AuthenticationType DeltaSharingAuthenticationType `json:"authentication_type,omitempty"` + SharingCode *string `json:"sharing_code,omitempty"` + DataRecipientGlobalMetastoreId *string `json:"data_recipient_global_metastore_id,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + IpAccessList *ipAccessListWire `json:"ip_access_list,omitempty"` + PropertiesKvpairs *propertiesKvPairsWire `json:"properties_kvpairs,omitempty"` + ExpirationTime *int64 `json:"expiration_time,omitempty"` + ActivationUrl *string `json:"activation_url,omitempty"` + Activated *bool `json:"activated,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + Tokens []recipientTokenInfoWire `json:"tokens,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Cloud *string `json:"cloud,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + Id *string `json:"id,omitempty"` +} + +func recipientInfoFromWire(w *recipientInfoWire) (*RecipientInfo, error) { + if w == nil { + return nil, nil + } + ipAccessListPublicValue, err := ipAccessListFromWire(w.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RecipientInfo.IpAccessList", err) + } + propertiesKvpairsPublicValue, err := propertiesKvPairsFromWire(w.PropertiesKvpairs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RecipientInfo.PropertiesKvpairs", err) + } + tokensPublicValue, err := convertSlice(w.Tokens, recipientTokenInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RecipientInfo.Tokens", err) + } + return &RecipientInfo{ + Name: w.Name, + AuthenticationType: w.AuthenticationType, + SharingCode: w.SharingCode, + DataRecipientGlobalMetastoreId: w.DataRecipientGlobalMetastoreId, + Owner: w.Owner, + Comment: w.Comment, + IpAccessList: ipAccessListPublicValue, + PropertiesKvpairs: propertiesKvpairsPublicValue, + ExpirationTime: w.ExpirationTime, + ActivationUrl: w.ActivationUrl, + Activated: w.Activated, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + Tokens: tokensPublicValue, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + Cloud: w.Cloud, + Region: w.Region, + MetastoreId: w.MetastoreId, + Id: w.Id, + }, nil +} + +type recipientProfileWire struct { + ShareCredentialsVersion *int `json:"share_credentials_version,omitempty"` + Endpoint *string `json:"endpoint,omitempty"` + BearerToken *string `json:"bearer_token,omitempty"` +} + +func recipientProfileToWire(v *RecipientProfile) (*recipientProfileWire, error) { + if v == nil { + return nil, nil + } + return &recipientProfileWire{ + ShareCredentialsVersion: v.ShareCredentialsVersion, + Endpoint: v.Endpoint, + BearerToken: v.BearerToken, + }, nil +} + +func recipientProfileFromWire(w *recipientProfileWire) (*RecipientProfile, error) { + if w == nil { + return nil, nil + } + return &RecipientProfile{ + ShareCredentialsVersion: w.ShareCredentialsVersion, + Endpoint: w.Endpoint, + BearerToken: w.BearerToken, + }, nil +} + +type recipientTokenInfoWire struct { + Id *string `json:"id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + ActivationUrl *string `json:"activation_url,omitempty"` + ExpirationTime *int64 `json:"expiration_time,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` +} + +func recipientTokenInfoToWire(v *RecipientTokenInfo) (*recipientTokenInfoWire, error) { + if v == nil { + return nil, nil + } + return &recipientTokenInfoWire{ + Id: v.Id, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + ActivationUrl: v.ActivationUrl, + ExpirationTime: v.ExpirationTime, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + }, nil +} + +func recipientTokenInfoFromWire(w *recipientTokenInfoWire) (*RecipientTokenInfo, error) { + if w == nil { + return nil, nil + } + return &RecipientTokenInfo{ + Id: w.Id, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + ActivationUrl: w.ActivationUrl, + ExpirationTime: w.ExpirationTime, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + }, nil +} + +type registeredModelAliasWire struct { + AliasName *string `json:"alias_name,omitempty"` + VersionNum *int64 `json:"version_num,omitempty"` +} + +func registeredModelAliasFromWire(w *registeredModelAliasWire) (*RegisteredModelAlias, error) { + if w == nil { + return nil, nil + } + return &RegisteredModelAlias{ + AliasName: w.AliasName, + VersionNum: w.VersionNum, + }, nil +} + +type retrieveTokenResponseWire struct { + ShareCredentialsVersion *int `json:"shareCredentialsVersion,omitempty"` + BearerToken *string `json:"bearerToken,omitempty"` + Endpoint *string `json:"endpoint,omitempty"` + ExpirationTime *string `json:"expirationTime,omitempty"` +} + +func retrieveTokenResponseFromWire(w *retrieveTokenResponseWire) (*RetrieveTokenResponse, error) { + if w == nil { + return nil, nil + } + return &RetrieveTokenResponse{ + ShareCredentialsVersion: w.ShareCredentialsVersion, + BearerToken: w.BearerToken, + Endpoint: w.Endpoint, + ExpirationTime: w.ExpirationTime, + }, nil +} + +type rotateRecipientTokenRequestWire struct { + Name *string `json:"name,omitempty"` + ExistingTokenExpireInSeconds *int64 `json:"existing_token_expire_in_seconds,omitempty"` +} + +func rotateRecipientTokenRequestToWire(v *RotateRecipientTokenRequest) (*rotateRecipientTokenRequestWire, error) { + if v == nil { + return nil, nil + } + return &rotateRecipientTokenRequestWire{ + Name: v.Name, + ExistingTokenExpireInSeconds: v.ExistingTokenExpireInSeconds, + }, nil +} + +type shareWire struct { + Name *string `json:"name,omitempty"` + Id *string `json:"id,omitempty"` +} + +func shareFromWire(w *shareWire) (*Share, error) { + if w == nil { + return nil, nil + } + return &Share{ + Name: w.Name, + Id: w.Id, + }, nil +} + +type shareInfoWire struct { + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + Objects []sharedDataObjectWire `json:"objects,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` +} + +func shareInfoFromWire(w *shareInfoWire) (*ShareInfo, error) { + if w == nil { + return nil, nil + } + objectsPublicValue, err := convertSlice(w.Objects, sharedDataObjectFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ShareInfo.Objects", err) + } + return &ShareInfo{ + Name: w.Name, + Owner: w.Owner, + Comment: w.Comment, + StorageRoot: w.StorageRoot, + Objects: objectsPublicValue, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + StorageLocation: w.StorageLocation, + }, nil +} + +type shareToPrivilegeAssignmentWire struct { + ShareName *string `json:"share_name,omitempty"` + PrivilegeAssignments []privilegeAssignmentWire `json:"privilege_assignments,omitempty"` +} + +func shareToPrivilegeAssignmentFromWire(w *shareToPrivilegeAssignmentWire) (*ShareToPrivilegeAssignment, error) { + if w == nil { + return nil, nil + } + privilegeAssignmentsPublicValue, err := convertSlice(w.PrivilegeAssignments, privilegeAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ShareToPrivilegeAssignment.PrivilegeAssignments", err) + } + return &ShareToPrivilegeAssignment{ + ShareName: w.ShareName, + PrivilegeAssignments: privilegeAssignmentsPublicValue, + }, nil +} + +type sharedDataObjectWire struct { + Name *string `json:"name,omitempty"` + DataObjectType *string `json:"data_object_type,omitempty"` + AddedAt *int64 `json:"added_at,omitempty"` + AddedBy *string `json:"added_by,omitempty"` + Comment *string `json:"comment,omitempty"` + SharedAs *string `json:"shared_as,omitempty"` + CdfEnabled *bool `json:"cdf_enabled,omitempty"` + HistoryDataSharingStatus SharedDataObject_HistoryDataSharingStatus_Enum `json:"history_data_sharing_status,omitempty"` + StartVersion *int64 `json:"start_version,omitempty"` + Status SharedDataObject_Status_Enum `json:"status,omitempty"` + Content *string `json:"content,omitempty"` + StringSharedAs *string `json:"string_shared_as,omitempty"` + Partitions []partitionSpecification_PartitionWire `json:"partitions,omitempty"` +} + +func sharedDataObjectToWire(v *SharedDataObject) (*sharedDataObjectWire, error) { + if v == nil { + return nil, nil + } + partitionsWireValue, err := convertSlice(v.Partitions, partitionSpecification_PartitionToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SharedDataObject.Partitions", err) + } + return &sharedDataObjectWire{ + Name: v.Name, + DataObjectType: v.DataObjectType, + AddedAt: v.AddedAt, + AddedBy: v.AddedBy, + Comment: v.Comment, + SharedAs: v.SharedAs, + CdfEnabled: v.CdfEnabled, + HistoryDataSharingStatus: v.HistoryDataSharingStatus, + StartVersion: v.StartVersion, + Status: v.Status, + Content: v.Content, + StringSharedAs: v.StringSharedAs, + Partitions: partitionsWireValue, + }, nil +} + +func sharedDataObjectFromWire(w *sharedDataObjectWire) (*SharedDataObject, error) { + if w == nil { + return nil, nil + } + partitionsPublicValue, err := convertSlice(w.Partitions, partitionSpecification_PartitionFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SharedDataObject.Partitions", err) + } + return &SharedDataObject{ + Name: w.Name, + DataObjectType: w.DataObjectType, + AddedAt: w.AddedAt, + AddedBy: w.AddedBy, + Comment: w.Comment, + SharedAs: w.SharedAs, + CdfEnabled: w.CdfEnabled, + HistoryDataSharingStatus: w.HistoryDataSharingStatus, + StartVersion: w.StartVersion, + Status: w.Status, + Content: w.Content, + StringSharedAs: w.StringSharedAs, + Partitions: partitionsPublicValue, + }, nil +} + +type tableWire struct { + Name *string `json:"name,omitempty"` + Schema *string `json:"schema,omitempty"` + Share *string `json:"share,omitempty"` + ShareId *string `json:"share_id,omitempty"` + Id *string `json:"id,omitempty"` + Comment *string `json:"comment,omitempty"` + Tags []tagKeyValueWire `json:"tags,omitempty"` + MaterializedTableName *string `json:"materialized_table_name,omitempty"` + MaterializationNamespace *string `json:"materialization_namespace,omitempty"` +} + +func tableFromWire(w *tableWire) (*Table, error) { + if w == nil { + return nil, nil + } + tagsPublicValue, err := convertSlice(w.Tags, tagKeyValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Table.Tags", err) + } + return &Table{ + Name: w.Name, + Schema: w.Schema, + Share: w.Share, + ShareId: w.ShareId, + Id: w.Id, + Comment: w.Comment, + Tags: tagsPublicValue, + MaterializedTableName: w.MaterializedTableName, + MaterializationNamespace: w.MaterializationNamespace, + }, nil +} + +type tableDependencyWire struct { + SchemaName *string `json:"schema_name,omitempty"` + TableName *string `json:"table_name,omitempty"` +} + +func tableDependencyFromWire(w *tableDependencyWire) (*TableDependency, error) { + if w == nil { + return nil, nil + } + return &TableDependency{ + SchemaName: w.SchemaName, + TableName: w.TableName, + }, nil +} + +type tagKeyValueWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func tagKeyValueFromWire(w *tagKeyValueWire) (*TagKeyValue, error) { + if w == nil { + return nil, nil + } + return &TagKeyValue{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type updateProviderRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + Name *string `json:"name,omitempty"` + AuthenticationType DeltaSharingAuthenticationType `json:"authentication_type,omitempty"` + RecipientProfileStr *string `json:"recipient_profile_str,omitempty"` + Comment *string `json:"comment,omitempty"` + Owner *string `json:"owner,omitempty"` + RecipientProfile *recipientProfileWire `json:"recipient_profile,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Cloud *string `json:"cloud,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + DataProviderGlobalMetastoreId *string `json:"data_provider_global_metastore_id,omitempty"` +} + +func updateProviderRequestToWire(v *UpdateProviderRequest) (*updateProviderRequestWire, error) { + if v == nil { + return nil, nil + } + recipientProfileWireValue, err := recipientProfileToWire(v.RecipientProfile) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateProviderRequest.RecipientProfile", err) + } + return &updateProviderRequestWire{ + NameArg: v.NameArg, + NewName: v.NewName, + Name: v.Name, + AuthenticationType: v.AuthenticationType, + RecipientProfileStr: v.RecipientProfileStr, + Comment: v.Comment, + Owner: v.Owner, + RecipientProfile: recipientProfileWireValue, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + Cloud: v.Cloud, + Region: v.Region, + MetastoreId: v.MetastoreId, + DataProviderGlobalMetastoreId: v.DataProviderGlobalMetastoreId, + }, nil +} + +type updateRecipientRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + Name *string `json:"name,omitempty"` + AuthenticationType DeltaSharingAuthenticationType `json:"authentication_type,omitempty"` + SharingCode *string `json:"sharing_code,omitempty"` + DataRecipientGlobalMetastoreId *string `json:"data_recipient_global_metastore_id,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + IpAccessList *ipAccessListWire `json:"ip_access_list,omitempty"` + PropertiesKvpairs *propertiesKvPairsWire `json:"properties_kvpairs,omitempty"` + ExpirationTime *int64 `json:"expiration_time,omitempty"` + ActivationUrl *string `json:"activation_url,omitempty"` + Activated *bool `json:"activated,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + Tokens []recipientTokenInfoWire `json:"tokens,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Cloud *string `json:"cloud,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + Id *string `json:"id,omitempty"` +} + +func updateRecipientRequestToWire(v *UpdateRecipientRequest) (*updateRecipientRequestWire, error) { + if v == nil { + return nil, nil + } + ipAccessListWireValue, err := ipAccessListToWire(v.IpAccessList) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRecipientRequest.IpAccessList", err) + } + propertiesKvpairsWireValue, err := propertiesKvPairsToWire(v.PropertiesKvpairs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRecipientRequest.PropertiesKvpairs", err) + } + tokensWireValue, err := convertSlice(v.Tokens, recipientTokenInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRecipientRequest.Tokens", err) + } + return &updateRecipientRequestWire{ + NameArg: v.NameArg, + NewName: v.NewName, + Name: v.Name, + AuthenticationType: v.AuthenticationType, + SharingCode: v.SharingCode, + DataRecipientGlobalMetastoreId: v.DataRecipientGlobalMetastoreId, + Owner: v.Owner, + Comment: v.Comment, + IpAccessList: ipAccessListWireValue, + PropertiesKvpairs: propertiesKvpairsWireValue, + ExpirationTime: v.ExpirationTime, + ActivationUrl: v.ActivationUrl, + Activated: v.Activated, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + Tokens: tokensWireValue, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + Cloud: v.Cloud, + Region: v.Region, + MetastoreId: v.MetastoreId, + Id: v.Id, + }, nil +} + +type updateSharePermissionsRequestWire struct { + Name *string `json:"name,omitempty"` + OmitPermissionsList *bool `json:"omit_permissions_list,omitempty"` + Changes []permissionsChangeWire `json:"changes,omitempty"` +} + +func updateSharePermissionsRequestToWire(v *UpdateSharePermissionsRequest) (*updateSharePermissionsRequestWire, error) { + if v == nil { + return nil, nil + } + changesWireValue, err := convertSlice(v.Changes, permissionsChangeToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateSharePermissionsRequest.Changes", err) + } + return &updateSharePermissionsRequestWire{ + Name: v.Name, + OmitPermissionsList: v.OmitPermissionsList, + Changes: changesWireValue, + }, nil +} + +type updateSharePermissionsResponseWire struct { + PrivilegeAssignments []privilegeAssignmentWire `json:"privilege_assignments,omitempty"` +} + +func updateSharePermissionsResponseFromWire(w *updateSharePermissionsResponseWire) (*UpdateSharePermissionsResponse, error) { + if w == nil { + return nil, nil + } + privilegeAssignmentsPublicValue, err := convertSlice(w.PrivilegeAssignments, privilegeAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateSharePermissionsResponse.PrivilegeAssignments", err) + } + return &UpdateSharePermissionsResponse{ + PrivilegeAssignments: privilegeAssignmentsPublicValue, + }, nil +} + +type updateShareRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + Updates []updateShareRequest_SharedDataObjectUpdateWire `json:"updates,omitempty"` + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + Objects []sharedDataObjectWire `json:"objects,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` +} + +func updateShareRequestToWire(v *UpdateShareRequest) (*updateShareRequestWire, error) { + if v == nil { + return nil, nil + } + updatesWireValue, err := convertSlice(v.Updates, updateShareRequest_SharedDataObjectUpdateToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateShareRequest.Updates", err) + } + objectsWireValue, err := convertSlice(v.Objects, sharedDataObjectToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateShareRequest.Objects", err) + } + return &updateShareRequestWire{ + NameArg: v.NameArg, + NewName: v.NewName, + Updates: updatesWireValue, + Name: v.Name, + Owner: v.Owner, + Comment: v.Comment, + StorageRoot: v.StorageRoot, + Objects: objectsWireValue, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + StorageLocation: v.StorageLocation, + }, nil +} + +type updateShareRequest_SharedDataObjectUpdateWire struct { + Action UpdateShareRequest_SharedDataObjectUpdate_Action `json:"action,omitempty"` + DataObject *sharedDataObjectWire `json:"data_object,omitempty"` +} + +func updateShareRequest_SharedDataObjectUpdateToWire(v *UpdateShareRequest_SharedDataObjectUpdate) (*updateShareRequest_SharedDataObjectUpdateWire, error) { + if v == nil { + return nil, nil + } + dataObjectWireValue, err := sharedDataObjectToWire(v.DataObject) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateShareRequest_SharedDataObjectUpdate.DataObject", err) + } + return &updateShareRequest_SharedDataObjectUpdateWire{ + Action: v.Action, + DataObject: dataObjectWireValue, + }, nil +} + +type volumeWire struct { + Name *string `json:"name,omitempty"` + Id *string `json:"id,omitempty"` + Schema *string `json:"schema,omitempty"` + Share *string `json:"share,omitempty"` + ShareId *string `json:"share_id,omitempty"` + Comment *string `json:"comment,omitempty"` + Tags []tagKeyValueWire `json:"tags,omitempty"` +} + +func volumeFromWire(w *volumeWire) (*Volume, error) { + if w == nil { + return nil, nil + } + tagsPublicValue, err := convertSlice(w.Tags, tagKeyValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Volume.Tags", err) + } + return &Volume{ + Name: w.Name, + Id: w.Id, + Schema: w.Schema, + Share: w.Share, + ShareId: w.ShareId, + Comment: w.Comment, + Tags: tagsPublicValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/statementexecution/.package.json b/statementexecution/.package.json new file mode 100644 index 0000000..372c1ac --- /dev/null +++ b/statementexecution/.package.json @@ -0,0 +1,3 @@ +{ + "package": "statementexecution" +} diff --git a/statementexecution/CHANGELOG.md b/statementexecution/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/statementexecution/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/statementexecution/README.md b/statementexecution/README.md new file mode 100644 index 0000000..b0bdbeb --- /dev/null +++ b/statementexecution/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/statementexecution + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/statementexecution@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/statementexecution/v1" + +client, err := statementexecution.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/statementexecution/go.mod b/statementexecution/go.mod new file mode 100644 index 0000000..bcd2a35 --- /dev/null +++ b/statementexecution/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/statementexecution + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/statementexecution/internal/version.go b/statementexecution/internal/version.go new file mode 100644 index 0000000..e5ca1cf --- /dev/null +++ b/statementexecution/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-statementexecution" + +const Version = "0.0.1-dev.1" diff --git a/statementexecution/v1/client.go b/statementexecution/v1/client.go new file mode 100755 index 0000000..a1d3b24 --- /dev/null +++ b/statementexecution/v1/client.go @@ -0,0 +1,397 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package statementexecution + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/statementexecution/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Requests that an executing statement be canceled. Callers must poll for +// status to see the terminal state. Cancel response is empty; receiving +// response indicates successful receipt. +func (c *internalClient) CancelStatement(ctx context.Context, req *CancelStatementRequest, opts ...call.Option) (*CancelStatementResponse, error) { + wireReq, err := cancelStatementRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/statements/") + pb.singleSegment(*req.StatementId) + pb.literal("/cancel") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CancelStatementResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &CancelStatementResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Execute a SQL statement and optionally await its results for a specified +// time. +// +// **Use case: small result sets with INLINE + JSON_ARRAY** +// +// For flows that generate small and predictable result sets (<= 25 MiB), +// `INLINE` responses of `JSON_ARRAY` result data are typically the simplest way +// to execute and fetch result data. +// +// **Use case: large result sets with EXTERNAL_LINKS** +// +// Using `EXTERNAL_LINKS` to fetch result data allows you to fetch large result +// sets efficiently. The main differences from using `INLINE` disposition are +// that the result data is accessed with URLs, and that there are 3 supported +// formats: `JSON_ARRAY`, `ARROW_STREAM` and `CSV` compared to only `JSON_ARRAY` +// with `INLINE`. +// +// ** URLs** +// +// External links point to data stored within your workspace's internal storage, +// in the form of a URL. The URLs are valid for only a short period, <= 15 +// minutes. Alongside each `external_link` is an expiration field indicating the +// time at which the URL is no longer valid. In `EXTERNAL_LINKS` mode, chunks +// can be resolved and fetched multiple times and in parallel. +// +// ---- +// +// ### **Warning: Databricks strongly recommends that you protect the URLs that +// are returned by the `EXTERNAL_LINKS` disposition.** +// +// When you use the `EXTERNAL_LINKS` disposition, a short-lived, URL is +// generated, which can be used to download the results directly from . As a +// short-lived is embedded in this URL, you should protect the URL. +// +// Because URLs are already generated with embedded temporary s, you must not +// set an `Authorization` header in the download requests. +// +// The `EXTERNAL_LINKS` disposition can be disabled upon request by creating a +// support case. +// +// See also [Security best +// practices](/sql/admin/sql-execution-tutorial.html#security-best-practices). +// +// ---- +// +// StatementResponse contains `statement_id` and `status`; other fields might be +// absent or present depending on context. If the SQL warehouse fails to execute +// the provided statement, a 200 response is returned with `status.state` set to +// `FAILED` (in contrast to a failure when accepting the request, which results +// in a non-200 response). Details of the error can be found at `status.error` +// in case of execution failures. +func (c *internalClient) ExecuteStatement(ctx context.Context, req *ExecuteStatementRequest, opts ...call.Option) (*StatementResponse, error) { + wireReq, err := executeStatementRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/sql/statements" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StatementResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp statementResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = statementResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// After the statement execution has `SUCCEEDED`, this request can be used to +// fetch any chunk by index. Whereas the first chunk with `chunk_index=0` is +// typically fetched with :method:statementexecution/executeStatement or +// :method:statementexecution/getStatement, this request can be used to fetch +// subsequent chunks. The response structure is identical to the nested `result` +// element described in the :method:statementexecution/getStatement request, and +// similarly includes the `next_chunk_index` and `next_chunk_internal_link` +// fields for simple iteration through the result set. Depending on +// `disposition`, the response returns chunks of data either inline, or as +// links. +func (c *internalClient) GetResultData(ctx context.Context, req *GetResultDataRequest, opts ...call.Option) (*ResultData, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/statements/") + pb.singleSegment(*req.StatementId) + pb.literal("/result/chunks/") + pb.singleSegment(*req.ChunkIndex) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ResultData + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp resultDataWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = resultDataFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// This request can be used to poll for the statement's status. +// StatementResponse contains `statement_id` and `status`; other fields might be +// absent or present depending on context. When the `status.state` field is +// `SUCCEEDED` it will also return the result manifest and the first chunk of +// the result data. When the statement is in the terminal states `CANCELED`, +// `CLOSED` or `FAILED`, it returns HTTP 200 with the state set. After at least +// 12 hours in terminal state, the statement is removed from the warehouse and +// further calls will receive an HTTP 404 response. +// +// **NOTE** This call currently might take up to 5 seconds to get the latest +// status and result. +func (c *internalClient) GetStatementResult(ctx context.Context, req *GetStatementResultRequest, opts ...call.Option) (*StatementResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/statements/") + pb.singleSegment(*req.StatementId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StatementResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp statementResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = statementResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/statementexecution/v1/genhelper.go b/statementexecution/v1/genhelper.go new file mode 100755 index 0000000..ee93097 --- /dev/null +++ b/statementexecution/v1/genhelper.go @@ -0,0 +1,188 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package statementexecution + +import ( + "context" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/statementexecution/v1/model.go b/statementexecution/v1/model.go new file mode 100755 index 0000000..4e0159d --- /dev/null +++ b/statementexecution/v1/model.go @@ -0,0 +1,460 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package statementexecution + +import "encoding/json" + +// The name of the base data type. This doesn't include details for complex +// types such as STRUCT, MAP or ARRAY. +type ColumnTypeName string + +const ( + ColumnTypeName_Unspecified ColumnTypeName = "" + ColumnTypeName_Boolean ColumnTypeName = "BOOLEAN" + ColumnTypeName_Byte ColumnTypeName = "BYTE" + ColumnTypeName_Short ColumnTypeName = "SHORT" + ColumnTypeName_Int ColumnTypeName = "INT" + ColumnTypeName_Long ColumnTypeName = "LONG" + ColumnTypeName_Float ColumnTypeName = "FLOAT" + ColumnTypeName_Double ColumnTypeName = "DOUBLE" + ColumnTypeName_Date ColumnTypeName = "DATE" + ColumnTypeName_Timestamp ColumnTypeName = "TIMESTAMP" + ColumnTypeName_String ColumnTypeName = "STRING" + ColumnTypeName_Binary ColumnTypeName = "BINARY" + ColumnTypeName_Decimal ColumnTypeName = "DECIMAL" + ColumnTypeName_Interval ColumnTypeName = "INTERVAL" + ColumnTypeName_Array ColumnTypeName = "ARRAY" + ColumnTypeName_Struct ColumnTypeName = "STRUCT" + ColumnTypeName_Map ColumnTypeName = "MAP" + ColumnTypeName_Char ColumnTypeName = "CHAR" + ColumnTypeName_Null ColumnTypeName = "NULL" + ColumnTypeName_UserDefinedType ColumnTypeName = "USER_DEFINED_TYPE" +) + +type Disposition string + +const ( + Disposition_Unspecified Disposition = "" + Disposition_Inline Disposition = "INLINE" + Disposition_ExternalLinks Disposition = "EXTERNAL_LINKS" +) + +type Format string + +const ( + Format_Unspecified Format = "" + Format_JsonArray Format = "JSON_ARRAY" + Format_ArrowStream Format = "ARROW_STREAM" + Format_Csv Format = "CSV" +) + +type ServiceErrorCode string + +const ( + ServiceErrorCode_Unspecified ServiceErrorCode = "" + ServiceErrorCode_Unknown ServiceErrorCode = "UNKNOWN" + ServiceErrorCode_InternalError ServiceErrorCode = "INTERNAL_ERROR" + ServiceErrorCode_TemporarilyUnavailable ServiceErrorCode = "TEMPORARILY_UNAVAILABLE" + ServiceErrorCode_IoError ServiceErrorCode = "IO_ERROR" + ServiceErrorCode_BadRequest ServiceErrorCode = "BAD_REQUEST" + ServiceErrorCode_ServiceUnderMaintenance ServiceErrorCode = "SERVICE_UNDER_MAINTENANCE" + ServiceErrorCode_WorkspaceTemporarilyUnavailable ServiceErrorCode = "WORKSPACE_TEMPORARILY_UNAVAILABLE" + ServiceErrorCode_DeadlineExceeded ServiceErrorCode = "DEADLINE_EXCEEDED" + ServiceErrorCode_Cancelled ServiceErrorCode = "CANCELLED" + ServiceErrorCode_ResourceExhausted ServiceErrorCode = "RESOURCE_EXHAUSTED" + ServiceErrorCode_Aborted ServiceErrorCode = "ABORTED" + ServiceErrorCode_NotFound ServiceErrorCode = "NOT_FOUND" + ServiceErrorCode_AlreadyExists ServiceErrorCode = "ALREADY_EXISTS" + ServiceErrorCode_Unauthenticated ServiceErrorCode = "UNAUTHENTICATED" +) + +// When `wait_timeout > 0s`, the call will block up to the specified time. If +// the statement execution doesn't finish within this time, `on_wait_timeout` +// determines whether the execution should continue or be canceled. When set to +// `CONTINUE`, the statement execution continues asynchronously and the call +// returns a statement ID which can be used for polling with +// :method:statementexecution/getStatement. When set to `CANCEL`, the statement +// execution is canceled and the call returns with a `CANCELED` state. +type TimeoutAction string + +const ( + TimeoutAction_Unspecified TimeoutAction = "" + TimeoutAction_Continue TimeoutAction = "CONTINUE" + TimeoutAction_Cancel TimeoutAction = "CANCEL" +) + +type StatementStatus_State string + +const ( + StatementStatus_State_Unspecified StatementStatus_State = "" + StatementStatus_State_Pending StatementStatus_State = "PENDING" + StatementStatus_State_Running StatementStatus_State = "RUNNING" + StatementStatus_State_Succeeded StatementStatus_State = "SUCCEEDED" + StatementStatus_State_Failed StatementStatus_State = "FAILED" + StatementStatus_State_Canceled StatementStatus_State = "CANCELED" + StatementStatus_State_Closed StatementStatus_State = "CLOSED" +) + +type CancelStatementRequest struct { + // The statement ID is returned upon successfully submitting a SQL statement, + // and is a required reference for all subsequent calls. + StatementId *string +} + +type CancelStatementResponse struct { +} + +type ChunkInfo struct { + // The position within the sequence of result set chunks. + ChunkIndex *int + // The starting row offset within the result set. + RowOffset *int64 + // The number of rows within the result chunk. + RowCount *int64 + // The number of bytes in the result chunk. This field is not available when + // using `INLINE` disposition. + ByteCount *int64 + // When fetching, provides the `chunk_index` for the _next_ chunk. If absent, + // indicates there are no more chunks. The next chunk can be fetched with a + // :method:statementexecution/getstatementresultchunkn request. + NextChunkIndex *int + // When fetching, provides a link to fetch the _next_ chunk. If absent, + // indicates there are no more chunks. This link is an absolute `path` to be + // joined with your `$DATABRICKS_HOST`, and should be treated as an opaque link. + // This is an alternative to using `next_chunk_index`. + NextChunkInternalLink *string +} + +type ColumnInfo struct { + // The name of the column. + Name *string + // The full SQL type specification. + TypeText *string + // The name of the base data type. This doesn't include details for complex + // types such as STRUCT, MAP or ARRAY. + TypeName ColumnTypeName + // The ordinal position of the column (starting at position 0). + Position *int + // Specifies the number of digits in a number. This applies to the DECIMAL type. + TypePrecision *int + // Specifies the number of digits to the right of the decimal point in a number. + // This applies to the DECIMAL type. + TypeScale *int + // The format of the interval type. + TypeIntervalType *string +} + +type ExecuteStatementRequest struct { + // The SQL statement to execute. The statement can optionally be parameterized, + // see `parameters`. The maximum query text size is 16 MiB. + Statement *string + // Warehouse upon which to execute a statement. See also [What are SQL + // warehouses?] + // + // [What are SQL warehouses?]: https://docs.databricks.com/sql/admin/warehouse-type.html + WarehouseId *string + // Sets default catalog for statement execution, similar to [`USE CATALOG`] in + // SQL. + // + // [`USE CATALOG`]: https://docs.databricks.com/sql/language-manual/sql-ref-syntax-ddl-use-catalog.html + Catalog *string + // Sets default schema for statement execution, similar to [`USE SCHEMA`] in + // SQL. + // + // [`USE SCHEMA`]: https://docs.databricks.com/sql/language-manual/sql-ref-syntax-ddl-use-schema.html + Schema *string + // Applies the given row limit to the statement's result set, but unlike the + // `LIMIT` clause in SQL, it also sets the `truncated` field in the response to + // indicate whether the result was trimmed due to the limit or not. + RowLimit *int64 + // Applies the given byte limit to the statement's result size. Byte counts are + // based on internal data representations and might not match the final size in + // the requested `format`. If the result was truncated due to the byte limit, + // then `truncated` in the response is set to `true`. When using + // `EXTERNAL_LINKS` disposition, a default `byte_limit` of 100 GiB is applied if + // `byte_limit` is not explicitly set. + ByteLimit *int64 + // Statement execution supports three result formats: `JSON_ARRAY` (default), + // `ARROW_STREAM`, and `CSV`. + // + // Important: The formats `ARROW_STREAM` and `CSV` are supported only with + // `EXTERNAL_LINKS` disposition. `JSON_ARRAY` is supported in `INLINE` and + // `EXTERNAL_LINKS` disposition. + // + // When specifying `format=JSON_ARRAY`, result data will be formatted as an + // array of arrays of values, where each value is either the *string + // representation* of a value, or `null`. For example, the output of `SELECT + // concat('id-', id) AS strCol, id AS intCol, null AS nullCol FROM range(3)` + // would look like this: + // + // ``` [ [ "id-1", "1", null ], [ "id-2", "2", null ], [ "id-3", "3", null ], ] + // ``` + // + // When specifying `format=JSON_ARRAY` and `disposition=EXTERNAL_LINKS`, each + // chunk in the result contains compact JSON with no indentation or extra + // whitespace. + // + // When specifying `format=ARROW_STREAM` and `disposition=EXTERNAL_LINKS`, each + // chunk in the result will be formatted as Apache Arrow Stream. See the [Apache + // Arrow streaming format]. + // + // When specifying `format=CSV` and `disposition=EXTERNAL_LINKS`, each chunk in + // the result will be a CSV according to [RFC 4180] standard. All the columns + // values will have *string representation* similar to the `JSON_ARRAY` format, + // and `null` values will be encoded as “null”. Only the first chunk in the + // result would contain a header row with column names. For example, the output + // of `SELECT concat('id-', id) AS strCol, id AS intCol, null as nullCol FROM + // range(3)` would look like this: + // + // ``` strCol,intCol,nullCol id-1,1,null id-2,2,null id-3,3,null ``` + // + // [Apache Arrow streaming format]: https://arrow.apache.org/docs/format/Columnar.html#ipc-streaming-format + // [RFC 4180]: https://www.rfc-editor.org/rfc/rfc4180 + Format Format + // The fetch disposition provides two modes of fetching results: `INLINE` and + // `EXTERNAL_LINKS`. + // + // Statements executed with `INLINE` disposition will return result data inline, + // in `JSON_ARRAY` format, in a series of chunks. If a given statement produces + // a result set with a size larger than 25 MiB, that statement execution is + // aborted, and no result set will be available. + // + // **NOTE** Byte limits are computed based upon internal representations of the + // result set data, and might not match the sizes visible in JSON responses. + // + // Statements executed with `EXTERNAL_LINKS` disposition will return result data + // as external links: URLs that point to cloud storage internal to the + // workspace. Using `EXTERNAL_LINKS` disposition allows statements to generate + // arbitrarily sized result sets for fetching up to 100 GiB. The resulting links + // have two important properties: + // + // 1. They point to resources _external_ to the compute; therefore + // any associated authentication information (typically a personal access token, + // OAuth token, or similar) _must be removed_ when fetching from these links. + // + // 2. These are URLs with a specific expiration, indicated in the response. The + // behavior when attempting to use an expired link is cloud specific. + Disposition Disposition + // The time in seconds the call will wait for the statement's result set as + // `Ns`, where `N` can be set to 0 or to a value between 5 and 50. + // + // When set to `0s`, the statement will execute in asynchronous mode and the + // call will not wait for the execution to finish. In this case, the call + // returns directly with `PENDING` state and a statement ID which can be used + // for polling with :method:statementexecution/getStatement. + // + // When set between 5 and 50 seconds, the call will behave synchronously up to + // this timeout and wait for the statement execution to finish. If the execution + // finishes within this time, the call returns immediately with a manifest and + // result data (or a `FAILED` state in case of an execution error). If the + // statement takes longer to execute, `on_wait_timeout` determines what should + // happen after the timeout is reached. + WaitTimeout *string + // When `wait_timeout > 0s`, the call will block up to the specified time. If + // the statement execution doesn't finish within this time, `on_wait_timeout` + // determines whether the execution should continue or be canceled. When set to + // `CONTINUE`, the statement execution continues asynchronously and the call + // returns a statement ID which can be used for polling with + // :method:statementexecution/getStatement. When set to `CANCEL`, the statement + // execution is canceled and the call returns with a `CANCELED` state. + OnWaitTimeout TimeoutAction + // A list of parameters to pass into a SQL statement containing parameter + // markers. A parameter consists of a name, a value, and optionally a type. To + // represent a NULL value, the `value` field may be omitted or set to `null` + // explicitly. If the `type` field is omitted, the value is interpreted as a + // string. + // + // If the type is given, parameters will be checked for type correctness + // according to the given type. A value is correct if the provided string can be + // converted to the requested type using the `cast` function. The exact + // semantics are described in the section [`cast` function] of the SQL language + // reference. + // + // For example, the following statement contains two parameters, `my_name` and + // `my_date`: + // + // ``` SELECT * FROM my_table WHERE name = :my_name AND date = :my_date ``` + // + // The parameters can be passed in the request body as follows: + // + // ` { ..., "statement": "SELECT * FROM my_table WHERE name = :my_name AND date + // = :my_date", "parameters": [ { "name": "my_name", "value": "the name" }, { + // "name": "my_date", "value": "2020-01-01", "type": "DATE" } ] } ` + // + // Currently, positional parameters denoted by a `?` marker are not supported by + // the Databricks SQL Statement Execution API. + // + // Also see the section [Parameter markers] of the SQL language reference. + // + // [Parameter markers]: https://docs.databricks.com/sql/language-manual/sql-ref-parameter-marker.html + // [`cast` function]: https://docs.databricks.com/sql/language-manual/functions/cast.html + Parameters []StatementParameter + // An array of query tags to annotate a SQL statement. A query tag consists of a + // non-empty key and, optionally, a value. To represent a NULL value, either + // omit the `value` field or manually set it to `null` or white space. Refer to + // the SQL language reference for the format specification of query tags. + // There's no significance to the order of tags. Only one value per key will be + // recorded. A sequence in excess of 20 query tags will be coerced to 20. + // Example: + // + // { ..., "query_tags": [ { "key": "team", "value": "eng" }, { "key": "some key + // only tag" } ] } + QueryTags []QueryTag +} + +type ExternalLink struct { + // A URL pointing to a chunk of result data, hosted by an external service, with + // a short expiration time (<= 15 minutes). As this URL contains a temporary + // credential, it should be considered sensitive and the client should not + // expose this URL in a log. + ExternalLink *string + // Indicates the date-time that the given external link will expire and becomes + // invalid, after which point a new `external_link` must be requested. + Expiration *string + // HTTP headers that must be included with a GET request to the `external_link`. + // Each header is provided as a key-value pair. Headers are typically used to + // pass a decryption key to the external service. The values of these headers + // should be considered sensitive and the client should not expose these values + // in a log. + HttpHeaders map[string]string + // The position within the sequence of result set chunks. + ChunkIndex *int + // The starting row offset within the result set. + RowOffset *int64 + // The number of rows within the result chunk. + RowCount *int64 + // The number of bytes in the result chunk. This field is not available when + // using `INLINE` disposition. + ByteCount *int64 + // When fetching, provides the `chunk_index` for the _next_ chunk. If absent, + // indicates there are no more chunks. The next chunk can be fetched with a + // :method:statementexecution/getstatementresultchunkn request. + NextChunkIndex *int + // When fetching, provides a link to fetch the _next_ chunk. If absent, + // indicates there are no more chunks. This link is an absolute `path` to be + // joined with your `$DATABRICKS_HOST`, and should be treated as an opaque link. + // This is an alternative to using `next_chunk_index`. + NextChunkInternalLink *string +} + +type GetResultDataRequest struct { + // The statement ID is returned upon successfully submitting a SQL statement, + // and is a required reference for all subsequent calls. + StatementId *string + ChunkIndex *int +} + +type GetStatementResultRequest struct { + // The statement ID is returned upon successfully submitting a SQL statement, + // and is a required reference for all subsequent calls. + StatementId *string +} + +// * A query execution can be annotated with an optional key-value pair to allow +// users to attribute the executions by key and optional value to filter by. +// QueryTag is the user-facing representation.. +type QueryTag struct { + Key *string + Value *string +} + +// Contains the result data of a single chunk when using `INLINE` disposition. +// When using `EXTERNAL_LINKS` disposition, the array `external_links` is used +// instead to provide URLs to the result data in cloud storage. Exactly one of +// these alternatives is used. (While the `external_links` array prepares the +// API to return multiple links in a single response. Currently only a single +// link is returned.). +type ResultData struct { + ExternalLinks []ExternalLink + // The `JSON_ARRAY` format is an array of arrays of values, where each non-null + // value is formatted as a string. Null values are encoded as JSON `null`. + DataArray [][]json.RawMessage + // The position within the sequence of result set chunks. + ChunkIndex *int + // The starting row offset within the result set. + RowOffset *int64 + // The number of rows within the result chunk. + RowCount *int64 + // The number of bytes in the result chunk. This field is not available when + // using `INLINE` disposition. + ByteCount *int64 + // When fetching, provides the `chunk_index` for the _next_ chunk. If absent, + // indicates there are no more chunks. The next chunk can be fetched with a + // :method:statementexecution/getstatementresultchunkn request. + NextChunkIndex *int + // When fetching, provides a link to fetch the _next_ chunk. If absent, + // indicates there are no more chunks. This link is an absolute `path` to be + // joined with your `$DATABRICKS_HOST`, and should be treated as an opaque link. + // This is an alternative to using `next_chunk_index`. + NextChunkInternalLink *string +} + +// The result manifest provides schema and metadata for the result set.. +type ResultManifest struct { + Format Format + Schema *Schema + // The total number of chunks that the result set has been divided into. + TotalChunkCount *int + // Array of result set chunk metadata. + Chunks []ChunkInfo + // The total number of rows in the result set. + TotalRowCount *int64 + // The total number of bytes in the result set. This field is not available when + // using `INLINE` disposition. + TotalByteCount *int64 + // Indicates whether the result is truncated due to `row_limit` or `byte_limit`. + Truncated *bool +} + +// The schema is an ordered list of column descriptions.. +type Schema struct { + ColumnCount *int + Columns []ColumnInfo +} + +type ServiceError struct { + ErrorCode ServiceErrorCode + // A brief summary of the error condition. + Message *string +} + +type StatementParameter struct { + // The name of a parameter marker to be substituted in the statement. + Name *string + // The value to substitute, represented as a string. If omitted, the value is + // interpreted as NULL. + Value *string + // The data type, given as a string. For example: `INT`, `STRING`, + // `DECIMAL(10,2)`. If no type is given the type is assumed to be `STRING`. + // Complex types, such as `ARRAY`, `MAP`, and `STRUCT` are not supported. For + // valid types, refer to the section [Data types] of the SQL language reference. + // + // [Data types]: https://docs.databricks.com/sql/language-manual/functions/cast.html + Type *string +} + +type StatementResponse struct { + // The statement ID is returned upon successfully submitting a SQL statement, + // and is a required reference for all subsequent calls. + StatementId *string + Status *StatementStatus + Manifest *ResultManifest + Result *ResultData +} + +// The status response includes execution state and if relevant, error +// information.. +type StatementStatus struct { + // Statement execution state: - `PENDING`: waiting for warehouse - `RUNNING`: + // running - `SUCCEEDED`: execution was successful, result data available for + // fetch - `FAILED`: execution failed; reason for failure described in + // accompanying error message - `CANCELED`: user canceled; can come from + // explicit cancel call, or timeout with `on_wait_timeout=CANCEL` - `CLOSED`: + // execution successful, and statement closed; result no longer available for + // fetch + State StatementStatus_State + Error *ServiceError + // SQLSTATE error code returned when the statement execution fails. Only + // populated when the statement status is `FAILED`. + SqlState *string +} diff --git a/statementexecution/v1/wire.go b/statementexecution/v1/wire.go new file mode 100755 index 0000000..61b43c9 --- /dev/null +++ b/statementexecution/v1/wire.go @@ -0,0 +1,338 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package statementexecution + +import ( + "encoding/json" + "fmt" +) + +type cancelStatementRequestWire struct { + StatementId *string `json:"statement_id,omitempty"` +} + +func cancelStatementRequestToWire(v *CancelStatementRequest) (*cancelStatementRequestWire, error) { + if v == nil { + return nil, nil + } + return &cancelStatementRequestWire{ + StatementId: v.StatementId, + }, nil +} + +type chunkInfoWire struct { + ChunkIndex *int `json:"chunk_index,omitempty"` + RowOffset *int64 `json:"row_offset,omitempty"` + RowCount *int64 `json:"row_count,omitempty"` + ByteCount *int64 `json:"byte_count,omitempty"` + NextChunkIndex *int `json:"next_chunk_index,omitempty"` + NextChunkInternalLink *string `json:"next_chunk_internal_link,omitempty"` +} + +func chunkInfoFromWire(w *chunkInfoWire) (*ChunkInfo, error) { + if w == nil { + return nil, nil + } + return &ChunkInfo{ + ChunkIndex: w.ChunkIndex, + RowOffset: w.RowOffset, + RowCount: w.RowCount, + ByteCount: w.ByteCount, + NextChunkIndex: w.NextChunkIndex, + NextChunkInternalLink: w.NextChunkInternalLink, + }, nil +} + +type columnInfoWire struct { + Name *string `json:"name,omitempty"` + TypeText *string `json:"type_text,omitempty"` + TypeName ColumnTypeName `json:"type_name,omitempty"` + Position *int `json:"position,omitempty"` + TypePrecision *int `json:"type_precision,omitempty"` + TypeScale *int `json:"type_scale,omitempty"` + TypeIntervalType *string `json:"type_interval_type,omitempty"` +} + +func columnInfoFromWire(w *columnInfoWire) (*ColumnInfo, error) { + if w == nil { + return nil, nil + } + return &ColumnInfo{ + Name: w.Name, + TypeText: w.TypeText, + TypeName: w.TypeName, + Position: w.Position, + TypePrecision: w.TypePrecision, + TypeScale: w.TypeScale, + TypeIntervalType: w.TypeIntervalType, + }, nil +} + +type executeStatementRequestWire struct { + Statement *string `json:"statement,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` + Catalog *string `json:"catalog,omitempty"` + Schema *string `json:"schema,omitempty"` + RowLimit *int64 `json:"row_limit,omitempty"` + ByteLimit *int64 `json:"byte_limit,omitempty"` + Format Format `json:"format,omitempty"` + Disposition Disposition `json:"disposition,omitempty"` + WaitTimeout *string `json:"wait_timeout,omitempty"` + OnWaitTimeout TimeoutAction `json:"on_wait_timeout,omitempty"` + Parameters []statementParameterWire `json:"parameters,omitempty"` + QueryTags []queryTagWire `json:"query_tags,omitempty"` +} + +func executeStatementRequestToWire(v *ExecuteStatementRequest) (*executeStatementRequestWire, error) { + if v == nil { + return nil, nil + } + parametersWireValue, err := convertSlice(v.Parameters, statementParameterToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExecuteStatementRequest.Parameters", err) + } + queryTagsWireValue, err := convertSlice(v.QueryTags, queryTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExecuteStatementRequest.QueryTags", err) + } + return &executeStatementRequestWire{ + Statement: v.Statement, + WarehouseId: v.WarehouseId, + Catalog: v.Catalog, + Schema: v.Schema, + RowLimit: v.RowLimit, + ByteLimit: v.ByteLimit, + Format: v.Format, + Disposition: v.Disposition, + WaitTimeout: v.WaitTimeout, + OnWaitTimeout: v.OnWaitTimeout, + Parameters: parametersWireValue, + QueryTags: queryTagsWireValue, + }, nil +} + +type externalLinkWire struct { + ExternalLink *string `json:"external_link,omitempty"` + Expiration *string `json:"expiration,omitempty"` + HttpHeaders map[string]string `json:"http_headers,omitempty"` + ChunkIndex *int `json:"chunk_index,omitempty"` + RowOffset *int64 `json:"row_offset,omitempty"` + RowCount *int64 `json:"row_count,omitempty"` + ByteCount *int64 `json:"byte_count,omitempty"` + NextChunkIndex *int `json:"next_chunk_index,omitempty"` + NextChunkInternalLink *string `json:"next_chunk_internal_link,omitempty"` +} + +func externalLinkFromWire(w *externalLinkWire) (*ExternalLink, error) { + if w == nil { + return nil, nil + } + return &ExternalLink{ + ExternalLink: w.ExternalLink, + Expiration: w.Expiration, + HttpHeaders: w.HttpHeaders, + ChunkIndex: w.ChunkIndex, + RowOffset: w.RowOffset, + RowCount: w.RowCount, + ByteCount: w.ByteCount, + NextChunkIndex: w.NextChunkIndex, + NextChunkInternalLink: w.NextChunkInternalLink, + }, nil +} + +type queryTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func queryTagToWire(v *QueryTag) (*queryTagWire, error) { + if v == nil { + return nil, nil + } + return &queryTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +type resultDataWire struct { + ExternalLinks []externalLinkWire `json:"external_links,omitempty"` + DataArray [][]json.RawMessage `json:"data_array,omitempty"` + ChunkIndex *int `json:"chunk_index,omitempty"` + RowOffset *int64 `json:"row_offset,omitempty"` + RowCount *int64 `json:"row_count,omitempty"` + ByteCount *int64 `json:"byte_count,omitempty"` + NextChunkIndex *int `json:"next_chunk_index,omitempty"` + NextChunkInternalLink *string `json:"next_chunk_internal_link,omitempty"` +} + +func resultDataFromWire(w *resultDataWire) (*ResultData, error) { + if w == nil { + return nil, nil + } + externalLinksPublicValue, err := convertSlice(w.ExternalLinks, externalLinkFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResultData.ExternalLinks", err) + } + return &ResultData{ + ExternalLinks: externalLinksPublicValue, + DataArray: w.DataArray, + ChunkIndex: w.ChunkIndex, + RowOffset: w.RowOffset, + RowCount: w.RowCount, + ByteCount: w.ByteCount, + NextChunkIndex: w.NextChunkIndex, + NextChunkInternalLink: w.NextChunkInternalLink, + }, nil +} + +type resultManifestWire struct { + Format Format `json:"format,omitempty"` + Schema *schemaWire `json:"schema,omitempty"` + TotalChunkCount *int `json:"total_chunk_count,omitempty"` + Chunks []chunkInfoWire `json:"chunks,omitempty"` + TotalRowCount *int64 `json:"total_row_count,omitempty"` + TotalByteCount *int64 `json:"total_byte_count,omitempty"` + Truncated *bool `json:"truncated,omitempty"` +} + +func resultManifestFromWire(w *resultManifestWire) (*ResultManifest, error) { + if w == nil { + return nil, nil + } + schemaPublicValue, err := schemaFromWire(w.Schema) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResultManifest.Schema", err) + } + chunksPublicValue, err := convertSlice(w.Chunks, chunkInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResultManifest.Chunks", err) + } + return &ResultManifest{ + Format: w.Format, + Schema: schemaPublicValue, + TotalChunkCount: w.TotalChunkCount, + Chunks: chunksPublicValue, + TotalRowCount: w.TotalRowCount, + TotalByteCount: w.TotalByteCount, + Truncated: w.Truncated, + }, nil +} + +type schemaWire struct { + ColumnCount *int `json:"column_count,omitempty"` + Columns []columnInfoWire `json:"columns,omitempty"` +} + +func schemaFromWire(w *schemaWire) (*Schema, error) { + if w == nil { + return nil, nil + } + columnsPublicValue, err := convertSlice(w.Columns, columnInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Schema.Columns", err) + } + return &Schema{ + ColumnCount: w.ColumnCount, + Columns: columnsPublicValue, + }, nil +} + +type serviceErrorWire struct { + ErrorCode ServiceErrorCode `json:"error_code,omitempty"` + Message *string `json:"message,omitempty"` +} + +func serviceErrorFromWire(w *serviceErrorWire) (*ServiceError, error) { + if w == nil { + return nil, nil + } + return &ServiceError{ + ErrorCode: w.ErrorCode, + Message: w.Message, + }, nil +} + +type statementParameterWire struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` + Type *string `json:"type,omitempty"` +} + +func statementParameterToWire(v *StatementParameter) (*statementParameterWire, error) { + if v == nil { + return nil, nil + } + return &statementParameterWire{ + Name: v.Name, + Value: v.Value, + Type: v.Type, + }, nil +} + +type statementResponseWire struct { + StatementId *string `json:"statement_id,omitempty"` + Status *statementStatusWire `json:"status,omitempty"` + Manifest *resultManifestWire `json:"manifest,omitempty"` + Result *resultDataWire `json:"result,omitempty"` +} + +func statementResponseFromWire(w *statementResponseWire) (*StatementResponse, error) { + if w == nil { + return nil, nil + } + statusPublicValue, err := statementStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StatementResponse.Status", err) + } + manifestPublicValue, err := resultManifestFromWire(w.Manifest) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StatementResponse.Manifest", err) + } + resultPublicValue, err := resultDataFromWire(w.Result) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StatementResponse.Result", err) + } + return &StatementResponse{ + StatementId: w.StatementId, + Status: statusPublicValue, + Manifest: manifestPublicValue, + Result: resultPublicValue, + }, nil +} + +type statementStatusWire struct { + State StatementStatus_State `json:"state,omitempty"` + Error *serviceErrorWire `json:"error,omitempty"` + SqlState *string `json:"sql_state,omitempty"` +} + +func statementStatusFromWire(w *statementStatusWire) (*StatementStatus, error) { + if w == nil { + return nil, nil + } + errorPublicValue, err := serviceErrorFromWire(w.Error) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StatementStatus.Error", err) + } + return &StatementStatus{ + State: w.State, + Error: errorPublicValue, + SqlState: w.SqlState, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/storageconfigurations/.package.json b/storageconfigurations/.package.json new file mode 100644 index 0000000..61793f2 --- /dev/null +++ b/storageconfigurations/.package.json @@ -0,0 +1,3 @@ +{ + "package": "storageconfigurations" +} diff --git a/storageconfigurations/CHANGELOG.md b/storageconfigurations/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/storageconfigurations/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/storageconfigurations/README.md b/storageconfigurations/README.md new file mode 100644 index 0000000..1ecf15d --- /dev/null +++ b/storageconfigurations/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/storageconfigurations + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/storageconfigurations@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/storageconfigurations/v1" + +client, err := storageconfigurations.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/storageconfigurations/go.mod b/storageconfigurations/go.mod new file mode 100644 index 0000000..3b742f1 --- /dev/null +++ b/storageconfigurations/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/storageconfigurations + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/storageconfigurations/internal/version.go b/storageconfigurations/internal/version.go new file mode 100644 index 0000000..995b192 --- /dev/null +++ b/storageconfigurations/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-storageconfigurations" + +const Version = "0.0.1-dev.1" diff --git a/storageconfigurations/v1/client.go b/storageconfigurations/v1/client.go new file mode 100755 index 0000000..d022306 --- /dev/null +++ b/storageconfigurations/v1/client.go @@ -0,0 +1,343 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package storageconfigurations + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/storageconfigurations/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a storage configuration for an account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateStorageConfigurationPublic(ctx context.Context, req *CreateStorageConfigurationRequest, opts ...call.Option) (*StorageConfiguration, error) { + wireReq, err := createStorageConfigurationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/storage-configurations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StorageConfiguration + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp storageConfigurationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = storageConfigurationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a storage configuration. You cannot delete a storage +// configuration that is associated with any workspace. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteStorageConfigurationPublic(ctx context.Context, req *DeleteStorageConfigurationRequest, opts ...call.Option) (*StorageConfiguration, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/storage-configurations/") + pb.singleSegment(*req.StorageConfigurationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StorageConfiguration + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp storageConfigurationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = storageConfigurationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a storage configuration for an account, both specified by +// ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetStorageConfigurationPublic(ctx context.Context, req *GetStorageConfigurationRequest, opts ...call.Option) (*StorageConfiguration, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/storage-configurations/") + pb.singleSegment(*req.StorageConfigurationId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StorageConfiguration + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp storageConfigurationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = storageConfigurationFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists storage configurations for an account, specified by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListStorageConfigurationPublic(ctx context.Context, req *ListStorageConfigurationRequest, opts ...call.Option) (*ListStorageConfigurationResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/storage-configurations") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListStorageConfigurationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp []storageConfigurationWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + convertedResponseBody, err := convertSlice(wireResp, storageConfigurationFromWire) + if err != nil { + return fmt.Errorf("ListStorageConfigurationResponse.StorageConfigurations: %w", err) + } + resp = &ListStorageConfigurationResponse{ + StorageConfigurations: convertedResponseBody, + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/storageconfigurations/v1/genhelper.go b/storageconfigurations/v1/genhelper.go new file mode 100755 index 0000000..d94b43b --- /dev/null +++ b/storageconfigurations/v1/genhelper.go @@ -0,0 +1,188 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package storageconfigurations + +import ( + "context" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/storageconfigurations/v1/model.go b/storageconfigurations/v1/model.go new file mode 100755 index 0000000..1af1b6e --- /dev/null +++ b/storageconfigurations/v1/model.go @@ -0,0 +1,61 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package storageconfigurations + +type CreateStorageConfigurationRequest struct { + AccountId *string + // The human-readable name of the storage configuration. + StorageConfigurationName *string + // Root S3 bucket information. + RootBucketInfo *RootBucketInfo + // Optional IAM role that is used to access the workspace catalog which is + // created during workspace creation for UC by Default. If a storage + // configuration with this field populated is used to create a workspace, then a + // workspace catalog is created together with the workspace. The workspace + // catalog shares the root bucket with internal workspace storage (including + // DBFS root) but uses a dedicated bucket path prefix. + RoleArn *string +} + +type DeleteStorageConfigurationRequest struct { + StorageConfigurationId *string + AccountId *string +} + +type GetStorageConfigurationRequest struct { + StorageConfigurationId *string + AccountId *string +} + +type ListStorageConfigurationRequest struct { + AccountId *string +} + +type ListStorageConfigurationResponse struct { + StorageConfigurations []StorageConfiguration +} + +type RootBucketInfo struct { + // Name of the S3 bucket + BucketName *string +} + +type StorageConfiguration struct { + // storage configuration ID. + StorageConfigurationId *string + // The account ID associated with this storage configuration. + AccountId *string + // The root bucket information for the storage configuration. + RootBucketInfo *RootBucketInfo + // The human-readable name of the storage configuration. + StorageConfigurationName *string + // Time in epoch milliseconds when the storage configuration was created. + CreationTime *int64 + // Optional IAM role that is used to access the workspace catalog which is + // created during workspace creation for UC by Default. If a storage + // configuration with this field populated is used to create a workspace, then a + // workspace catalog is created together with the workspace. The workspace + // catalog shares the root bucket with internal workspace storage (including + // DBFS root) but uses a dedicated bucket path prefix. + RoleArn *string +} diff --git a/storageconfigurations/v1/wire.go b/storageconfigurations/v1/wire.go new file mode 100755 index 0000000..2decfa2 --- /dev/null +++ b/storageconfigurations/v1/wire.go @@ -0,0 +1,94 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package storageconfigurations + +import ( + "fmt" +) + +type createStorageConfigurationRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + StorageConfigurationName *string `json:"storage_configuration_name,omitempty"` + RootBucketInfo *rootBucketInfoWire `json:"root_bucket_info,omitempty"` + RoleArn *string `json:"role_arn,omitempty"` +} + +func createStorageConfigurationRequestToWire(v *CreateStorageConfigurationRequest) (*createStorageConfigurationRequestWire, error) { + if v == nil { + return nil, nil + } + rootBucketInfoWireValue, err := rootBucketInfoToWire(v.RootBucketInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateStorageConfigurationRequest.RootBucketInfo", err) + } + return &createStorageConfigurationRequestWire{ + AccountId: v.AccountId, + StorageConfigurationName: v.StorageConfigurationName, + RootBucketInfo: rootBucketInfoWireValue, + RoleArn: v.RoleArn, + }, nil +} + +type rootBucketInfoWire struct { + BucketName *string `json:"bucket_name,omitempty"` +} + +func rootBucketInfoToWire(v *RootBucketInfo) (*rootBucketInfoWire, error) { + if v == nil { + return nil, nil + } + return &rootBucketInfoWire{ + BucketName: v.BucketName, + }, nil +} + +func rootBucketInfoFromWire(w *rootBucketInfoWire) (*RootBucketInfo, error) { + if w == nil { + return nil, nil + } + return &RootBucketInfo{ + BucketName: w.BucketName, + }, nil +} + +type storageConfigurationWire struct { + StorageConfigurationId *string `json:"storage_configuration_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + RootBucketInfo *rootBucketInfoWire `json:"root_bucket_info,omitempty"` + StorageConfigurationName *string `json:"storage_configuration_name,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + RoleArn *string `json:"role_arn,omitempty"` +} + +func storageConfigurationFromWire(w *storageConfigurationWire) (*StorageConfiguration, error) { + if w == nil { + return nil, nil + } + rootBucketInfoPublicValue, err := rootBucketInfoFromWire(w.RootBucketInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StorageConfiguration.RootBucketInfo", err) + } + return &StorageConfiguration{ + StorageConfigurationId: w.StorageConfigurationId, + AccountId: w.AccountId, + RootBucketInfo: rootBucketInfoPublicValue, + StorageConfigurationName: w.StorageConfigurationName, + CreationTime: w.CreationTime, + RoleArn: w.RoleArn, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/supervisoragents/.package.json b/supervisoragents/.package.json new file mode 100644 index 0000000..3105c5a --- /dev/null +++ b/supervisoragents/.package.json @@ -0,0 +1,3 @@ +{ + "package": "supervisoragents" +} diff --git a/supervisoragents/CHANGELOG.md b/supervisoragents/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/supervisoragents/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/supervisoragents/README.md b/supervisoragents/README.md new file mode 100644 index 0000000..8ed21e2 --- /dev/null +++ b/supervisoragents/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/supervisoragents + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/supervisoragents@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/supervisoragents/v1" + +client, err := supervisoragents.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/supervisoragents/go.mod b/supervisoragents/go.mod new file mode 100644 index 0000000..86243a9 --- /dev/null +++ b/supervisoragents/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/supervisoragents + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/supervisoragents/internal/version.go b/supervisoragents/internal/version.go new file mode 100644 index 0000000..15ba9ac --- /dev/null +++ b/supervisoragents/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-supervisoragents" + +const Version = "0.0.1-dev.1" diff --git a/supervisoragents/v1/client.go b/supervisoragents/v1/client.go new file mode 100755 index 0000000..6263c43 --- /dev/null +++ b/supervisoragents/v1/client.go @@ -0,0 +1,1184 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package supervisoragents + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/supervisoragents/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates an example for a Supervisor Agent. +func (c *internalClient) CreateExample(ctx context.Context, req *CreateExampleRequest, opts ...call.Option) (*Example, error) { + wireReq, err := createExampleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Example) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Parent) + pb.literal("/examples") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Example + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp exampleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = exampleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new Supervisor Agent. +func (c *internalClient) CreateSupervisorAgent(ctx context.Context, req *CreateSupervisorAgentRequest, opts ...call.Option) (*SupervisorAgent, error) { + wireReq, err := createSupervisorAgentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.SupervisorAgent) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/supervisor-agents" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SupervisorAgent + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp supervisorAgentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = supervisorAgentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a Tool under a Supervisor Agent. Specify one of "genie_space", +// "knowledge_assistant", "uc_function", "uc_connection", "app", "volume", +// "dashboard", "table", "vector_search_index", "catalog", "schema", +// "supervisor_agent", "databricks_web_search", "skill" in the request body. The +// legacy values "lakeview_dashboard", "uc_table", and "web_search" are also +// accepted and remain equivalent to "dashboard", "table", and +// "databricks_web_search" respectively. The "databricks_web_search" tool_type +// maps to the `web_search` spec field. +func (c *internalClient) CreateTool(ctx context.Context, req *CreateToolRequest, opts ...call.Option) (*Tool, error) { + wireReq, err := createToolRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Tool) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Parent) + pb.literal("/tools") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "tool_id", wireReq.ToolId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Tool + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp toolWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = toolFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes an example from a Supervisor Agent. +func (c *internalClient) DeleteExample(ctx context.Context, req *DeleteExampleRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Deletes a Supervisor Agent. +func (c *internalClient) DeleteSupervisorAgent(ctx context.Context, req *DeleteSupervisorAgentRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Deletes a Tool. +func (c *internalClient) DeleteTool(ctx context.Context, req *DeleteToolRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets an example from a Supervisor Agent. +func (c *internalClient) GetExample(ctx context.Context, req *GetExampleRequest, opts ...call.Option) (*Example, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Example + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp exampleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = exampleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a Supervisor Agent. +func (c *internalClient) GetSupervisorAgent(ctx context.Context, req *GetSupervisorAgentRequest, opts ...call.Option) (*SupervisorAgent, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SupervisorAgent + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp supervisorAgentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = supervisorAgentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a Tool. +func (c *internalClient) GetTool(ctx context.Context, req *GetToolRequest, opts ...call.Option) (*Tool, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Tool + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp toolWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = toolFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists examples under a Supervisor Agent. +func (c *internalClient) ListExamples(ctx context.Context, req *ListExamplesRequest, opts ...call.Option) (*ListExamplesResponse, error) { + wireReq, err := listExamplesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Parent) + pb.literal("/examples") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListExamplesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listExamplesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listExamplesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListExamplesIter returns an iterator that iterates +// over the results of ListExamples. +// +// For example: +// +// for item, err := range c.ListExamplesIter(ctx, &ListExamplesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListExamples call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListExamples directly. +func (c *internalClient) ListExamplesIter(ctx context.Context, req *ListExamplesRequest, opts ...call.Option) iter.Seq2[*Example, error] { + return func(yield func(*Example, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListExamplesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListExamples(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Examples { + if !yield(&resp.Examples[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Lists Supervisor Agents. +func (c *internalClient) ListSupervisorAgents(ctx context.Context, req *ListSupervisorAgentsRequest, opts ...call.Option) (*ListSupervisorAgentsResponse, error) { + wireReq, err := listSupervisorAgentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/supervisor-agents" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListSupervisorAgentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listSupervisorAgentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listSupervisorAgentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListSupervisorAgentsIter returns an iterator that iterates +// over the results of ListSupervisorAgents. +// +// For example: +// +// for item, err := range c.ListSupervisorAgentsIter(ctx, &ListSupervisorAgentsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListSupervisorAgents call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListSupervisorAgents directly. +func (c *internalClient) ListSupervisorAgentsIter(ctx context.Context, req *ListSupervisorAgentsRequest, opts ...call.Option) iter.Seq2[*SupervisorAgent, error] { + return func(yield func(*SupervisorAgent, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListSupervisorAgentsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListSupervisorAgents(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.SupervisorAgents { + if !yield(&resp.SupervisorAgents[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Lists Tools under a Supervisor Agent. +func (c *internalClient) ListTools(ctx context.Context, req *ListToolsRequest, opts ...call.Option) (*ListToolsResponse, error) { + wireReq, err := listToolsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Parent) + pb.literal("/tools") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListToolsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listToolsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listToolsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListToolsIter returns an iterator that iterates +// over the results of ListTools. +// +// For example: +// +// for item, err := range c.ListToolsIter(ctx, &ListToolsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListTools call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListTools directly. +func (c *internalClient) ListToolsIter(ctx context.Context, req *ListToolsRequest, opts ...call.Option) iter.Seq2[*Tool, error] { + return func(yield func(*Tool, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListToolsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListTools(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Tools { + if !yield(&resp.Tools[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates an example in a Supervisor Agent. +func (c *internalClient) UpdateExample(ctx context.Context, req *UpdateExampleRequest, opts ...call.Option) (*Example, error) { + wireReq, err := updateExampleRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Example) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Example + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp exampleWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = exampleFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a Supervisor Agent. The fields that are required depend on the paths +// specified in `update_mask`. Only fields included in the mask will be updated. +func (c *internalClient) UpdateSupervisorAgent(ctx context.Context, req *UpdateSupervisorAgentRequest, opts ...call.Option) (*SupervisorAgent, error) { + wireReq, err := updateSupervisorAgentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.SupervisorAgent) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.SupervisorAgent.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SupervisorAgent + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp supervisorAgentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = supervisorAgentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a Tool. Only the `description` field can be updated. To change +// immutable fields such as tool type, spec, or tool ID, delete the tool and +// recreate it. +func (c *internalClient) UpdateTool(ctx context.Context, req *UpdateToolRequest, opts ...call.Option) (*Tool, error) { + wireReq, err := updateToolRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Tool) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/") + pb.singleSegment(*req.Tool.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Tool + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp toolWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = toolFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/supervisoragents/v1/genhelper.go b/supervisoragents/v1/genhelper.go new file mode 100755 index 0000000..a9b9198 --- /dev/null +++ b/supervisoragents/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package supervisoragents + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/supervisoragents/v1/model.go b/supervisoragents/v1/model.go new file mode 100755 index 0000000..7eca0eb --- /dev/null +++ b/supervisoragents/v1/model.go @@ -0,0 +1,294 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package supervisoragents + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// app. Supported app: custom mcp, custom agent.. +type App struct { + // App name + Name *string `fieldmask:"name"` +} + +// Create an example.. +type CreateExampleRequest struct { + // Parent resource where this example will be created. Format: + // supervisor-agents/{supervisor_agent_id} + Parent *string + // The example to create under the parent Supervisor Agent. + Example *Example +} + +type CreateSupervisorAgentRequest struct { + // The Supervisor Agent to create. + SupervisorAgent *SupervisorAgent +} + +type CreateToolRequest struct { + // Parent resource where this tool will be created. Format: + // supervisor-agents/{supervisor_agent_id} + Parent *string + Tool *Tool + // The ID to use for the tool, which will become the final component of the + // tool's resource name. + ToolId *string +} + +// Delete an example.. +type DeleteExampleRequest struct { + // The resource name of the example to delete. Format: + // supervisor-agents/{supervisor_agent_id}/examples/{example_id} + Name *string +} + +type DeleteSupervisorAgentRequest struct { + // The resource name of the Supervisor Agent. Format: + // supervisor-agents/{supervisor_agent_id} + Name *string +} + +type DeleteToolRequest struct { + // The resource name of the Tool. Format: + // supervisor-agents/{supervisor_agent_id}/tools/{tool_id} + Name *string +} + +// An example associated with a Supervisor Agent. Contains a question and +// guidelines for how the agent should respond.. +type Example struct { + // Full resource name: + // supervisor-agents/{supervisor_agent_id}/examples/{example_id} + Name *string `fieldmask:"name"` + // The example question. + Question *string `fieldmask:"question"` + // Guidelines for answering the question. + Guidelines []string `fieldmask:"guidelines"` + // The universally unique identifier (UUID) of the example. + ExampleId *string `fieldmask:"example_id"` +} + +type GenieSpace struct { + // Deprecated: use space_id instead. Still REQUIRED for backward compatibility + // until a future API version removes it. + Id *string `fieldmask:"id"` +} + +// Get an example.. +type GetExampleRequest struct { + // The resource name of the example. Format: + // supervisor-agents/{supervisor_agent_id}/examples/{example_id} + Name *string +} + +type GetSupervisorAgentRequest struct { + // The resource name of the Supervisor Agent. Format: + // supervisor-agents/{supervisor_agent_id} + Name *string +} + +type GetToolRequest struct { + // The resource name of the Tool. Format: + // supervisor-agents/{supervisor_agent_id}/tools/{tool_id} + Name *string +} + +type KnowledgeAssistant struct { + // Deprecated: use knowledge_assistant_id instead. + ServingEndpointName *string `fieldmask:"serving_endpoint_name"` + // The ID of the knowledge assistant. + KnowledgeAssistantId *string `fieldmask:"knowledge_assistant_id"` +} + +// List examples.. +type ListExamplesRequest struct { + // Parent resource to list from. Format: supervisor-agents/{supervisor_agent_id} + Parent *string + // The maximum number of examples to return. If unspecified, at most 100 + // examples will be returned. The maximum value is 100; values above 100 will be + // coerced to 100. + PageSize *int + // A page token, received from a previous `ListExamples` call. Provide this to + // retrieve the subsequent page. If unspecified, the first page will be + // returned. + PageToken *string +} + +// A list of Supervisor Agent examples.. +type ListExamplesResponse struct { + Examples []Example + NextPageToken *string +} + +type ListSupervisorAgentsRequest struct { + // The maximum number of supervisor agents to return. If unspecified, at most + // 100 supervisor agents will be returned. The maximum value is 100; values + // above 100 will be coerced to 100. + PageSize *int + // A page token, received from a previous `ListSupervisorAgents` call. Provide + // this to retrieve the subsequent page. If unspecified, the first page will be + // returned. + PageToken *string +} + +type ListSupervisorAgentsResponse struct { + SupervisorAgents []SupervisorAgent + // A token that can be sent as `page_token` to retrieve the next page. If this + // field is omitted, there are no subsequent pages. + NextPageToken *string +} + +type ListToolsRequest struct { + // Parent resource to list from. Format: supervisor-agents/{supervisor_agent_id} + Parent *string + PageSize *int + PageToken *string +} + +type ListToolsResponse struct { + Tools []Tool + NextPageToken *string +} + +type SupervisorAgent struct { + // The resource name of the SupervisorAgent. Format: + // supervisor-agents/{supervisor_agent_id} + Name *string `fieldmask:"name"` + // The display name of the Supervisor Agent, unique at workspace level. + DisplayName *string `fieldmask:"display_name"` + // Description of what this agent can do (user-facing). + Description *string `fieldmask:"description"` + // Optional natural-language instructions for the supervisor agent. + Instructions *string `fieldmask:"instructions"` + // Deprecated: Use supervisor_agent_id instead. + Id *string `fieldmask:"id"` + // The universally unique identifier (UUID) of the Supervisor Agent. + SupervisorAgentId *string `fieldmask:"supervisor_agent_id"` + // The creator of the Supervisor Agent. + Creator *string `fieldmask:"creator"` + // Creation timestamp. + CreateTime *types.Time `fieldmask:"create_time"` + // The name of the supervisor agent's serving endpoint. + EndpointName *string `fieldmask:"endpoint_name"` + // The MLflow experiment ID. + ExperimentId *string `fieldmask:"experiment_id"` +} + +type Tool struct { + // Full resource name: supervisor-agents/{supervisor_agent_id}/tools/{tool_id} + Name *string `fieldmask:"name"` + // Deprecated: Use tool_id instead. + Id *string `fieldmask:"id"` + // Tool type. Must be one of: "genie_space", "knowledge_assistant", + // "uc_function", "uc_connection", "uc_mcp", "app", "volume", "dashboard", + // "serving_endpoint", "table", "vector_search_index", "catalog", "schema", + // "supervisor_agent", "databricks_web_search", "skill". The legacy values + // "lakeview_dashboard", "uc_table", and "web_search" are also accepted and + // remain equivalent to "dashboard", "table", and "databricks_web_search" + // respectively. The "databricks_web_search" tool_type maps to the `web_search` + // spec field. + ToolType *string `fieldmask:"tool_type"` + // Specification for the tool type. + Spec isTool_Spec + // Description of what this tool does (user-facing). + Description *string `fieldmask:"description"` + // User specified id of the Tool. + ToolId *string `fieldmask:"tool_id"` + _ [0]toolSpecFieldMaskMetadata `fieldmask_oneof:"Spec"` +} + +type isTool_Spec interface { + isTool_Spec() +} + +// Tool_Spec_GenieSpace selects GenieSpace for Tool.Spec. +type Tool_Spec_GenieSpace struct { + GenieSpace GenieSpace `fieldmask:"genie_space"` +} + +func (*Tool_Spec_GenieSpace) isTool_Spec() {} + +// Tool_Spec_KnowledgeAssistant selects KnowledgeAssistant for Tool.Spec. +type Tool_Spec_KnowledgeAssistant struct { + KnowledgeAssistant KnowledgeAssistant `fieldmask:"knowledge_assistant"` +} + +func (*Tool_Spec_KnowledgeAssistant) isTool_Spec() {} + +// Tool_Spec_UcFunction selects UcFunction for Tool.Spec. +type Tool_Spec_UcFunction struct { + UcFunction UcFunction `fieldmask:"uc_function"` +} + +func (*Tool_Spec_UcFunction) isTool_Spec() {} + +// Tool_Spec_App selects App for Tool.Spec. +type Tool_Spec_App struct { + App App `fieldmask:"app"` +} + +func (*Tool_Spec_App) isTool_Spec() {} + +// Tool_Spec_Volume selects Volume for Tool.Spec. +type Tool_Spec_Volume struct { + Volume Volume `fieldmask:"volume"` +} + +func (*Tool_Spec_Volume) isTool_Spec() {} + +// Tool_Spec_UcConnection selects UcConnection for Tool.Spec. +type Tool_Spec_UcConnection struct { + UcConnection UcConnection `fieldmask:"uc_connection"` +} + +func (*Tool_Spec_UcConnection) isTool_Spec() {} + +type toolSpecFieldMaskMetadata struct { + *Tool_Spec_GenieSpace + *Tool_Spec_KnowledgeAssistant + *Tool_Spec_UcFunction + *Tool_Spec_App + *Tool_Spec_Volume + *Tool_Spec_UcConnection +} + +// Databricks UC connection. Supported connection: external mcp server.. +type UcConnection struct { + Name *string `fieldmask:"name"` +} + +type UcFunction struct { + // Full uc function name + Name *string `fieldmask:"name"` +} + +// Update an example.. +type UpdateExampleRequest struct { + // The resource name of the example to update. Format: + // supervisor-agents/{supervisor_agent_id}/examples/{example_id} + Name *string + Example *Example + // Comma-delimited list of fields to update on the example. Allowed values: + // `question`, `guidelines`. Examples: - `question` - `question,guidelines` + UpdateMask *types.FieldMask[Example] +} + +type UpdateSupervisorAgentRequest struct { + // The SupervisorAgent to update. + SupervisorAgent *SupervisorAgent + // Field mask for fields to be updated. + UpdateMask *types.FieldMask[SupervisorAgent] +} + +type UpdateToolRequest struct { + // The Tool to update. + Tool *Tool + // Field mask for fields to be updated. + UpdateMask *types.FieldMask[Tool] +} + +type Volume struct { + // Full uc volume name + Name *string `fieldmask:"name"` +} diff --git a/supervisoragents/v1/wire.go b/supervisoragents/v1/wire.go new file mode 100755 index 0000000..13f1dbe --- /dev/null +++ b/supervisoragents/v1/wire.go @@ -0,0 +1,636 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package supervisoragents + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type appWire struct { + Name *string `json:"name,omitempty"` +} + +func appToWire(v *App) (*appWire, error) { + if v == nil { + return nil, nil + } + return &appWire{ + Name: v.Name, + }, nil +} + +func appFromWire(w *appWire) (*App, error) { + if w == nil { + return nil, nil + } + return &App{ + Name: w.Name, + }, nil +} + +type createExampleRequestWire struct { + Parent *string `json:"parent,omitempty"` + Example *exampleWire `json:"example,omitempty"` +} + +func createExampleRequestToWire(v *CreateExampleRequest) (*createExampleRequestWire, error) { + if v == nil { + return nil, nil + } + exampleWireValue, err := exampleToWire(v.Example) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExampleRequest.Example", err) + } + return &createExampleRequestWire{ + Parent: v.Parent, + Example: exampleWireValue, + }, nil +} + +type createSupervisorAgentRequestWire struct { + SupervisorAgent *supervisorAgentWire `json:"supervisor_agent,omitempty"` +} + +func createSupervisorAgentRequestToWire(v *CreateSupervisorAgentRequest) (*createSupervisorAgentRequestWire, error) { + if v == nil { + return nil, nil + } + supervisorAgentWireValue, err := supervisorAgentToWire(v.SupervisorAgent) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateSupervisorAgentRequest.SupervisorAgent", err) + } + return &createSupervisorAgentRequestWire{ + SupervisorAgent: supervisorAgentWireValue, + }, nil +} + +type createToolRequestWire struct { + Parent *string `json:"parent,omitempty"` + Tool *toolWire `json:"tool,omitempty"` + ToolId *string `json:"tool_id,omitempty"` +} + +func createToolRequestToWire(v *CreateToolRequest) (*createToolRequestWire, error) { + if v == nil { + return nil, nil + } + toolWireValue, err := toolToWire(v.Tool) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateToolRequest.Tool", err) + } + return &createToolRequestWire{ + Parent: v.Parent, + Tool: toolWireValue, + ToolId: v.ToolId, + }, nil +} + +type exampleWire struct { + Name *string `json:"name,omitempty"` + Question *string `json:"question,omitempty"` + Guidelines []string `json:"guidelines,omitempty"` + ExampleId *string `json:"example_id,omitempty"` +} + +func exampleToWire(v *Example) (*exampleWire, error) { + if v == nil { + return nil, nil + } + return &exampleWire{ + Name: v.Name, + Question: v.Question, + Guidelines: v.Guidelines, + ExampleId: v.ExampleId, + }, nil +} + +func exampleFromWire(w *exampleWire) (*Example, error) { + if w == nil { + return nil, nil + } + return &Example{ + Name: w.Name, + Question: w.Question, + Guidelines: w.Guidelines, + ExampleId: w.ExampleId, + }, nil +} + +type genieSpaceWire struct { + Id *string `json:"id,omitempty"` +} + +func genieSpaceToWire(v *GenieSpace) (*genieSpaceWire, error) { + if v == nil { + return nil, nil + } + return &genieSpaceWire{ + Id: v.Id, + }, nil +} + +func genieSpaceFromWire(w *genieSpaceWire) (*GenieSpace, error) { + if w == nil { + return nil, nil + } + return &GenieSpace{ + Id: w.Id, + }, nil +} + +type knowledgeAssistantWire struct { + ServingEndpointName *string `json:"serving_endpoint_name,omitempty"` + KnowledgeAssistantId *string `json:"knowledge_assistant_id,omitempty"` +} + +func knowledgeAssistantToWire(v *KnowledgeAssistant) (*knowledgeAssistantWire, error) { + if v == nil { + return nil, nil + } + return &knowledgeAssistantWire{ + ServingEndpointName: v.ServingEndpointName, + KnowledgeAssistantId: v.KnowledgeAssistantId, + }, nil +} + +func knowledgeAssistantFromWire(w *knowledgeAssistantWire) (*KnowledgeAssistant, error) { + if w == nil { + return nil, nil + } + return &KnowledgeAssistant{ + ServingEndpointName: w.ServingEndpointName, + KnowledgeAssistantId: w.KnowledgeAssistantId, + }, nil +} + +type listExamplesRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listExamplesRequestToWire(v *ListExamplesRequest) (*listExamplesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listExamplesRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listExamplesResponseWire struct { + Examples []exampleWire `json:"examples,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listExamplesResponseFromWire(w *listExamplesResponseWire) (*ListExamplesResponse, error) { + if w == nil { + return nil, nil + } + examplesPublicValue, err := convertSlice(w.Examples, exampleFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListExamplesResponse.Examples", err) + } + return &ListExamplesResponse{ + Examples: examplesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listSupervisorAgentsRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listSupervisorAgentsRequestToWire(v *ListSupervisorAgentsRequest) (*listSupervisorAgentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSupervisorAgentsRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listSupervisorAgentsResponseWire struct { + SupervisorAgents []supervisorAgentWire `json:"supervisor_agents,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listSupervisorAgentsResponseFromWire(w *listSupervisorAgentsResponseWire) (*ListSupervisorAgentsResponse, error) { + if w == nil { + return nil, nil + } + supervisorAgentsPublicValue, err := convertSlice(w.SupervisorAgents, supervisorAgentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListSupervisorAgentsResponse.SupervisorAgents", err) + } + return &ListSupervisorAgentsResponse{ + SupervisorAgents: supervisorAgentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listToolsRequestWire struct { + Parent *string `json:"parent,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listToolsRequestToWire(v *ListToolsRequest) (*listToolsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listToolsRequestWire{ + Parent: v.Parent, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listToolsResponseWire struct { + Tools []toolWire `json:"tools,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listToolsResponseFromWire(w *listToolsResponseWire) (*ListToolsResponse, error) { + if w == nil { + return nil, nil + } + toolsPublicValue, err := convertSlice(w.Tools, toolFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListToolsResponse.Tools", err) + } + return &ListToolsResponse{ + Tools: toolsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type supervisorAgentWire struct { + Name *string `json:"name,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Description *string `json:"description,omitempty"` + Instructions *string `json:"instructions,omitempty"` + Id *string `json:"id,omitempty"` + SupervisorAgentId *string `json:"supervisor_agent_id,omitempty"` + Creator *string `json:"creator,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + ExperimentId *string `json:"experiment_id,omitempty"` +} + +func supervisorAgentToWire(v *SupervisorAgent) (*supervisorAgentWire, error) { + if v == nil { + return nil, nil + } + return &supervisorAgentWire{ + Name: v.Name, + DisplayName: v.DisplayName, + Description: v.Description, + Instructions: v.Instructions, + Id: v.Id, + SupervisorAgentId: v.SupervisorAgentId, + Creator: v.Creator, + CreateTime: v.CreateTime, + EndpointName: v.EndpointName, + ExperimentId: v.ExperimentId, + }, nil +} + +func supervisorAgentFromWire(w *supervisorAgentWire) (*SupervisorAgent, error) { + if w == nil { + return nil, nil + } + return &SupervisorAgent{ + Name: w.Name, + DisplayName: w.DisplayName, + Description: w.Description, + Instructions: w.Instructions, + Id: w.Id, + SupervisorAgentId: w.SupervisorAgentId, + Creator: w.Creator, + CreateTime: w.CreateTime, + EndpointName: w.EndpointName, + ExperimentId: w.ExperimentId, + }, nil +} + +type toolWire struct { + Name *string `json:"name,omitempty"` + Id *string `json:"id,omitempty"` + ToolType *string `json:"tool_type,omitempty"` + GenieSpace *genieSpaceWire `json:"genie_space,omitempty"` + KnowledgeAssistant *knowledgeAssistantWire `json:"knowledge_assistant,omitempty"` + UcFunction *ucFunctionWire `json:"uc_function,omitempty"` + App *appWire `json:"app,omitempty"` + Volume *volumeWire `json:"volume,omitempty"` + UcConnection *ucConnectionWire `json:"uc_connection,omitempty"` + Description *string `json:"description,omitempty"` + ToolId *string `json:"tool_id,omitempty"` +} + +func toolToWire(v *Tool) (*toolWire, error) { + if v == nil { + return nil, nil + } + var specGenieSpaceWire *genieSpaceWire + var specKnowledgeAssistantWire *knowledgeAssistantWire + var specUcFunctionWire *ucFunctionWire + var specAppWire *appWire + var specVolumeWire *volumeWire + var specUcConnectionWire *ucConnectionWire + switch value := v.Spec.(type) { + case nil: + case *Tool_Spec_GenieSpace: + if value != nil { + specGenieSpaceConverted, err := genieSpaceToWire(&value.GenieSpace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.GenieSpace", err) + } + specGenieSpaceWire = specGenieSpaceConverted + } + case *Tool_Spec_KnowledgeAssistant: + if value != nil { + specKnowledgeAssistantConverted, err := knowledgeAssistantToWire(&value.KnowledgeAssistant) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.KnowledgeAssistant", err) + } + specKnowledgeAssistantWire = specKnowledgeAssistantConverted + } + case *Tool_Spec_UcFunction: + if value != nil { + specUcFunctionConverted, err := ucFunctionToWire(&value.UcFunction) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.UcFunction", err) + } + specUcFunctionWire = specUcFunctionConverted + } + case *Tool_Spec_App: + if value != nil { + specAppConverted, err := appToWire(&value.App) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.App", err) + } + specAppWire = specAppConverted + } + case *Tool_Spec_Volume: + if value != nil { + specVolumeConverted, err := volumeToWire(&value.Volume) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.Volume", err) + } + specVolumeWire = specVolumeConverted + } + case *Tool_Spec_UcConnection: + if value != nil { + specUcConnectionConverted, err := ucConnectionToWire(&value.UcConnection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.UcConnection", err) + } + specUcConnectionWire = specUcConnectionConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Tool.Spec", value) + } + return &toolWire{ + Name: v.Name, + Id: v.Id, + ToolType: v.ToolType, + GenieSpace: specGenieSpaceWire, + KnowledgeAssistant: specKnowledgeAssistantWire, + UcFunction: specUcFunctionWire, + App: specAppWire, + Volume: specVolumeWire, + UcConnection: specUcConnectionWire, + Description: v.Description, + ToolId: v.ToolId, + }, nil +} + +func toolFromWire(w *toolWire) (*Tool, error) { + if w == nil { + return nil, nil + } + specMembers := 0 + if w.GenieSpace != nil { + specMembers++ + } + if w.KnowledgeAssistant != nil { + specMembers++ + } + if w.UcFunction != nil { + specMembers++ + } + if w.App != nil { + specMembers++ + } + if w.Volume != nil { + specMembers++ + } + if w.UcConnection != nil { + specMembers++ + } + if specMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Tool.Spec") + } + var specSelection isTool_Spec + switch { + case w.GenieSpace != nil: + specGenieSpaceConverted, err := genieSpaceFromWire(w.GenieSpace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.GenieSpace", err) + } + specSelection = &Tool_Spec_GenieSpace{GenieSpace: *specGenieSpaceConverted} + case w.KnowledgeAssistant != nil: + specKnowledgeAssistantConverted, err := knowledgeAssistantFromWire(w.KnowledgeAssistant) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.KnowledgeAssistant", err) + } + specSelection = &Tool_Spec_KnowledgeAssistant{KnowledgeAssistant: *specKnowledgeAssistantConverted} + case w.UcFunction != nil: + specUcFunctionConverted, err := ucFunctionFromWire(w.UcFunction) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.UcFunction", err) + } + specSelection = &Tool_Spec_UcFunction{UcFunction: *specUcFunctionConverted} + case w.App != nil: + specAppConverted, err := appFromWire(w.App) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.App", err) + } + specSelection = &Tool_Spec_App{App: *specAppConverted} + case w.Volume != nil: + specVolumeConverted, err := volumeFromWire(w.Volume) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.Volume", err) + } + specSelection = &Tool_Spec_Volume{Volume: *specVolumeConverted} + case w.UcConnection != nil: + specUcConnectionConverted, err := ucConnectionFromWire(w.UcConnection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Tool.Spec.UcConnection", err) + } + specSelection = &Tool_Spec_UcConnection{UcConnection: *specUcConnectionConverted} + } + return &Tool{ + Name: w.Name, + Id: w.Id, + ToolType: w.ToolType, + Description: w.Description, + ToolId: w.ToolId, + Spec: specSelection, + }, nil +} + +type ucConnectionWire struct { + Name *string `json:"name,omitempty"` +} + +func ucConnectionToWire(v *UcConnection) (*ucConnectionWire, error) { + if v == nil { + return nil, nil + } + return &ucConnectionWire{ + Name: v.Name, + }, nil +} + +func ucConnectionFromWire(w *ucConnectionWire) (*UcConnection, error) { + if w == nil { + return nil, nil + } + return &UcConnection{ + Name: w.Name, + }, nil +} + +type ucFunctionWire struct { + Name *string `json:"name,omitempty"` +} + +func ucFunctionToWire(v *UcFunction) (*ucFunctionWire, error) { + if v == nil { + return nil, nil + } + return &ucFunctionWire{ + Name: v.Name, + }, nil +} + +func ucFunctionFromWire(w *ucFunctionWire) (*UcFunction, error) { + if w == nil { + return nil, nil + } + return &UcFunction{ + Name: w.Name, + }, nil +} + +type updateExampleRequestWire struct { + Name *string `json:"name,omitempty"` + Example *exampleWire `json:"example,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateExampleRequestToWire(v *UpdateExampleRequest) (*updateExampleRequestWire, error) { + if v == nil { + return nil, nil + } + exampleWireValue, err := exampleToWire(v.Example) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExampleRequest.Example", err) + } + return &updateExampleRequestWire{ + Name: v.Name, + Example: exampleWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateSupervisorAgentRequestWire struct { + SupervisorAgent *supervisorAgentWire `json:"supervisor_agent,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateSupervisorAgentRequestToWire(v *UpdateSupervisorAgentRequest) (*updateSupervisorAgentRequestWire, error) { + if v == nil { + return nil, nil + } + supervisorAgentWireValue, err := supervisorAgentToWire(v.SupervisorAgent) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateSupervisorAgentRequest.SupervisorAgent", err) + } + return &updateSupervisorAgentRequestWire{ + SupervisorAgent: supervisorAgentWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateToolRequestWire struct { + Tool *toolWire `json:"tool,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateToolRequestToWire(v *UpdateToolRequest) (*updateToolRequestWire, error) { + if v == nil { + return nil, nil + } + toolWireValue, err := toolToWire(v.Tool) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateToolRequest.Tool", err) + } + return &updateToolRequestWire{ + Tool: toolWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type volumeWire struct { + Name *string `json:"name,omitempty"` +} + +func volumeToWire(v *Volume) (*volumeWire, error) { + if v == nil { + return nil, nil + } + return &volumeWire{ + Name: v.Name, + }, nil +} + +func volumeFromWire(w *volumeWire) (*Volume, error) { + if w == nil { + return nil, nil + } + return &Volume{ + Name: w.Name, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/tagassignments/.package.json b/tagassignments/.package.json new file mode 100644 index 0000000..67224fa --- /dev/null +++ b/tagassignments/.package.json @@ -0,0 +1,3 @@ +{ + "package": "tagassignments" +} diff --git a/tagassignments/CHANGELOG.md b/tagassignments/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/tagassignments/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/tagassignments/README.md b/tagassignments/README.md new file mode 100644 index 0000000..8e5f3d0 --- /dev/null +++ b/tagassignments/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/tagassignments + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/tagassignments@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/tagassignments/v1" + +client, err := tagassignments.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/tagassignments/go.mod b/tagassignments/go.mod new file mode 100644 index 0000000..799761f --- /dev/null +++ b/tagassignments/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/tagassignments + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/tagassignments/internal/version.go b/tagassignments/internal/version.go new file mode 100644 index 0000000..0127b1f --- /dev/null +++ b/tagassignments/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-tagassignments" + +const Version = "0.0.1-dev.1" diff --git a/tagassignments/v1/client.go b/tagassignments/v1/client.go new file mode 100755 index 0000000..87a6aa8 --- /dev/null +++ b/tagassignments/v1/client.go @@ -0,0 +1,453 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tagassignments + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/tagassignments/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a tag assignment +func (c *internalClient) CreateTagAssignment(ctx context.Context, req *CreateTagAssignmentRequest, opts ...call.Option) (*TagAssignment, error) { + wireReq, err := createTagAssignmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.TagAssignment) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/entity-tag-assignments" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TagAssignment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp tagAssignmentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = tagAssignmentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete a tag assignment +func (c *internalClient) DeleteTagAssignment(ctx context.Context, req *DeleteTagAssignmentRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/entity-tag-assignments/") + pb.singleSegment(*req.EntityType) + pb.literal("/") + pb.singleSegment(*req.EntityId) + pb.literal("/tags/") + pb.singleSegment(*req.TagKey) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Get a tag assignment +func (c *internalClient) GetTagAssignment(ctx context.Context, req *GetTagAssignmentRequest, opts ...call.Option) (*TagAssignment, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/entity-tag-assignments/") + pb.singleSegment(*req.EntityType) + pb.literal("/") + pb.singleSegment(*req.EntityId) + pb.literal("/tags/") + pb.singleSegment(*req.TagKey) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TagAssignment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp tagAssignmentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = tagAssignmentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List the tag assignments for an entity +func (c *internalClient) ListTagAssignments(ctx context.Context, req *ListTagAssignmentsRequest, opts ...call.Option) (*ListTagAssignmentsResponse, error) { + wireReq, err := listTagAssignmentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/entity-tag-assignments/") + pb.singleSegment(*req.EntityType) + pb.literal("/") + pb.singleSegment(*req.EntityId) + pb.literal("/tags") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListTagAssignmentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listTagAssignmentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listTagAssignmentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListTagAssignmentsIter returns an iterator that iterates +// over the results of ListTagAssignments. +// +// For example: +// +// for item, err := range c.ListTagAssignmentsIter(ctx, &ListTagAssignmentsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListTagAssignments call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListTagAssignments directly. +func (c *internalClient) ListTagAssignmentsIter(ctx context.Context, req *ListTagAssignmentsRequest, opts ...call.Option) iter.Seq2[*TagAssignment, error] { + return func(yield func(*TagAssignment, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListTagAssignmentsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListTagAssignments(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.TagAssignments { + if !yield(&resp.TagAssignments[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Update a tag assignment +func (c *internalClient) UpdateTagAssignment(ctx context.Context, req *UpdateTagAssignmentRequest, opts ...call.Option) (*TagAssignment, error) { + wireReq, err := updateTagAssignmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.TagAssignment) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/entity-tag-assignments/") + pb.singleSegment(*req.TagAssignment.EntityType) + pb.literal("/") + pb.singleSegment(*req.TagAssignment.EntityId) + pb.literal("/tags/") + pb.singleSegment(*req.TagAssignment.TagKey) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TagAssignment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp tagAssignmentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = tagAssignmentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/tagassignments/v1/genhelper.go b/tagassignments/v1/genhelper.go new file mode 100755 index 0000000..5bae68c --- /dev/null +++ b/tagassignments/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tagassignments + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/tagassignments/v1/model.go b/tagassignments/v1/model.go new file mode 100755 index 0000000..9c262fa --- /dev/null +++ b/tagassignments/v1/model.go @@ -0,0 +1,74 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tagassignments + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type CreateTagAssignmentRequest struct { + TagAssignment *TagAssignment +} + +type DeleteTagAssignmentRequest struct { + // The type of entity to which the tag is assigned. Allowed values are apps, + // dashboards, geniespaces, notebooks + EntityType *string + // The identifier of the entity to which the tag is assigned. For apps, the + // entity_id is the app name + EntityId *string + // The key of the tag. The characters , . : / - = and leading/trailing spaces + // are not allowed + TagKey *string +} + +type GetTagAssignmentRequest struct { + // The type of entity to which the tag is assigned. Allowed values are apps, + // dashboards, geniespaces, notebooks + EntityType *string + // The identifier of the entity to which the tag is assigned. For apps, the + // entity_id is the app name + EntityId *string + // The key of the tag. The characters , . : / - = and leading/trailing spaces + // are not allowed + TagKey *string +} + +type ListTagAssignmentsRequest struct { + // The type of entity to which the tag is assigned. Allowed values are apps, + // dashboards, geniespaces, notebooks + EntityType *string + // The identifier of the entity to which the tag is assigned. For apps, the + // entity_id is the app name + EntityId *string + // Optional. Maximum number of tag assignments to return in a single page + PageSize *int + // Pagination token to go to the next page of tag assignments. Requests first + // page if absent. + PageToken *string +} + +type ListTagAssignmentsResponse struct { + TagAssignments []TagAssignment + // Pagination token to request the next page of tag assignments + NextPageToken *string +} + +type TagAssignment struct { + // The type of entity to which the tag is assigned. Allowed values are apps, + // dashboards, geniespaces, notebooks + EntityType *string `fieldmask:"entity_type"` + // The identifier of the entity to which the tag is assigned. For apps, the + // entity_id is the app name + EntityId *string `fieldmask:"entity_id"` + // The key of the tag. The characters , . : / - = and leading/trailing spaces + // are not allowed + TagKey *string `fieldmask:"tag_key"` + // The value of the tag + TagValue *string `fieldmask:"tag_value"` +} + +type UpdateTagAssignmentRequest struct { + TagAssignment *TagAssignment + UpdateMask *types.FieldMask[TagAssignment] +} diff --git a/tagassignments/v1/wire.go b/tagassignments/v1/wire.go new file mode 100755 index 0000000..d330828 --- /dev/null +++ b/tagassignments/v1/wire.go @@ -0,0 +1,137 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tagassignments + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createTagAssignmentRequestWire struct { + TagAssignment *tagAssignmentWire `json:"tag_assignment,omitempty"` +} + +func createTagAssignmentRequestToWire(v *CreateTagAssignmentRequest) (*createTagAssignmentRequestWire, error) { + if v == nil { + return nil, nil + } + tagAssignmentWireValue, err := tagAssignmentToWire(v.TagAssignment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTagAssignmentRequest.TagAssignment", err) + } + return &createTagAssignmentRequestWire{ + TagAssignment: tagAssignmentWireValue, + }, nil +} + +type listTagAssignmentsRequestWire struct { + EntityType *string `json:"entity_type,omitempty"` + EntityId *string `json:"entity_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listTagAssignmentsRequestToWire(v *ListTagAssignmentsRequest) (*listTagAssignmentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listTagAssignmentsRequestWire{ + EntityType: v.EntityType, + EntityId: v.EntityId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listTagAssignmentsResponseWire struct { + TagAssignments []tagAssignmentWire `json:"tag_assignments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listTagAssignmentsResponseFromWire(w *listTagAssignmentsResponseWire) (*ListTagAssignmentsResponse, error) { + if w == nil { + return nil, nil + } + tagAssignmentsPublicValue, err := convertSlice(w.TagAssignments, tagAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListTagAssignmentsResponse.TagAssignments", err) + } + return &ListTagAssignmentsResponse{ + TagAssignments: tagAssignmentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type tagAssignmentWire struct { + EntityType *string `json:"entity_type,omitempty"` + EntityId *string `json:"entity_id,omitempty"` + TagKey *string `json:"tag_key,omitempty"` + TagValue *string `json:"tag_value,omitempty"` +} + +func tagAssignmentToWire(v *TagAssignment) (*tagAssignmentWire, error) { + if v == nil { + return nil, nil + } + return &tagAssignmentWire{ + EntityType: v.EntityType, + EntityId: v.EntityId, + TagKey: v.TagKey, + TagValue: v.TagValue, + }, nil +} + +func tagAssignmentFromWire(w *tagAssignmentWire) (*TagAssignment, error) { + if w == nil { + return nil, nil + } + return &TagAssignment{ + EntityType: w.EntityType, + EntityId: w.EntityId, + TagKey: w.TagKey, + TagValue: w.TagValue, + }, nil +} + +type updateTagAssignmentRequestWire struct { + TagAssignment *tagAssignmentWire `json:"tag_assignment,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateTagAssignmentRequestToWire(v *UpdateTagAssignmentRequest) (*updateTagAssignmentRequestWire, error) { + if v == nil { + return nil, nil + } + tagAssignmentWireValue, err := tagAssignmentToWire(v.TagAssignment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTagAssignmentRequest.TagAssignment", err) + } + return &updateTagAssignmentRequestWire{ + TagAssignment: tagAssignmentWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/tagpolicies/.package.json b/tagpolicies/.package.json new file mode 100644 index 0000000..43fdec5 --- /dev/null +++ b/tagpolicies/.package.json @@ -0,0 +1,3 @@ +{ + "package": "tagpolicies" +} diff --git a/tagpolicies/CHANGELOG.md b/tagpolicies/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/tagpolicies/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/tagpolicies/README.md b/tagpolicies/README.md new file mode 100644 index 0000000..c9be097 --- /dev/null +++ b/tagpolicies/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/tagpolicies + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/tagpolicies@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/tagpolicies/v1" + +client, err := tagpolicies.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/tagpolicies/go.mod b/tagpolicies/go.mod new file mode 100644 index 0000000..6b49834 --- /dev/null +++ b/tagpolicies/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/tagpolicies + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/tagpolicies/internal/version.go b/tagpolicies/internal/version.go new file mode 100644 index 0000000..507405b --- /dev/null +++ b/tagpolicies/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-tagpolicies" + +const Version = "0.0.1-dev.1" diff --git a/tagpolicies/v1/client.go b/tagpolicies/v1/client.go new file mode 100755 index 0000000..7ca0fca --- /dev/null +++ b/tagpolicies/v1/client.go @@ -0,0 +1,459 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tagpolicies + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/tagpolicies/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new tag policy, making the associated tag key governed. For +// Terraform usage, see the [Tag Policy Terraform documentation]. To manage +// permissions for tag policies, use the [Account Access Control Proxy API]. +// +// [Account Access Control Proxy API]: https://docs.databricks.com/api/workspace/accountaccesscontrolproxy +// [Tag Policy Terraform documentation]: https://registry.terraform.io/providers/databricks/databricks/latest/docs/resources/tag_policy +func (c *internalClient) CreateTagPolicy(ctx context.Context, req *CreateTagPolicyRequest, opts ...call.Option) (*TagPolicy, error) { + wireReq, err := createTagPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.TagPolicy) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/tag-policies" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TagPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp tagPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = tagPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a tag policy by its associated governed tag's key, leaving that tag +// key ungoverned. For Terraform usage, see the [Tag Policy Terraform +// documentation]. +// +// [Tag Policy Terraform documentation]: https://registry.terraform.io/providers/databricks/databricks/latest/docs/resources/tag_policy +func (c *internalClient) DeleteTagPolicy(ctx context.Context, req *DeleteTagPolicyRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/tag-policies/") + pb.singleSegment(*req.TagKey) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets a single tag policy by its associated governed tag's key. For Terraform +// usage, see the [Tag Policy Terraform documentation]. To list granted +// permissions for tag policies, use the [Account Access Control Proxy API]. +// +// [Account Access Control Proxy API]: https://docs.databricks.com/api/workspace/accountaccesscontrolproxy +// [Tag Policy Terraform documentation]: https://registry.terraform.io/providers/databricks/databricks/latest/docs/data-sources/tag_policy +func (c *internalClient) GetTagPolicy(ctx context.Context, req *GetTagPolicyRequest, opts ...call.Option) (*TagPolicy, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/tag-policies/") + pb.singleSegment(*req.TagKey) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TagPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp tagPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = tagPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists the tag policies for all governed tags in the account. For Terraform +// usage, see the [Tag Policy Terraform documentation]. To list granted +// permissions for tag policies, use the [Account Access Control Proxy API]. +// +// [Account Access Control Proxy API]: https://docs.databricks.com/api/workspace/accountaccesscontrolproxy +// [Tag Policy Terraform documentation]: https://registry.terraform.io/providers/databricks/databricks/latest/docs/data-sources/tag_policies +func (c *internalClient) ListTagPolicies(ctx context.Context, req *ListTagPoliciesRequest, opts ...call.Option) (*ListTagPoliciesResponse, error) { + wireReq, err := listTagPoliciesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/tag-policies" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListTagPoliciesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listTagPoliciesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listTagPoliciesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListTagPoliciesIter returns an iterator that iterates +// over the results of ListTagPolicies. +// +// For example: +// +// for item, err := range c.ListTagPoliciesIter(ctx, &ListTagPoliciesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListTagPolicies call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListTagPolicies directly. +func (c *internalClient) ListTagPoliciesIter(ctx context.Context, req *ListTagPoliciesRequest, opts ...call.Option) iter.Seq2[*TagPolicy, error] { + return func(yield func(*TagPolicy, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListTagPoliciesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListTagPolicies(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.TagPolicies { + if !yield(&resp.TagPolicies[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates an existing tag policy for a single governed tag. For Terraform +// usage, see the [Tag Policy Terraform documentation]. To manage permissions +// for tag policies, use the [Account Access Control Proxy API]. +// +// [Account Access Control Proxy API]: https://docs.databricks.com/api/workspace/accountaccesscontrolproxy +// [Tag Policy Terraform documentation]: https://registry.terraform.io/providers/databricks/databricks/latest/docs/resources/tag_policy +func (c *internalClient) UpdateTagPolicy(ctx context.Context, req *UpdateTagPolicyRequest, opts ...call.Option) (*TagPolicy, error) { + wireReq, err := updateTagPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.TagPolicy) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/tag-policies/") + pb.singleSegment(*req.TagPolicy.TagKey) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TagPolicy + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp tagPolicyWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = tagPolicyFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/tagpolicies/v1/genhelper.go b/tagpolicies/v1/genhelper.go new file mode 100755 index 0000000..dda3b9b --- /dev/null +++ b/tagpolicies/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tagpolicies + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/tagpolicies/v1/model.go b/tagpolicies/v1/model.go new file mode 100755 index 0000000..e2ec2ba --- /dev/null +++ b/tagpolicies/v1/model.go @@ -0,0 +1,53 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tagpolicies + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type CreateTagPolicyRequest struct { + TagPolicy *TagPolicy +} + +type DeleteTagPolicyRequest struct { + TagKey *string +} + +type GetTagPolicyRequest struct { + TagKey *string +} + +type ListTagPoliciesRequest struct { + // The maximum number of results to return in this request. Fewer results may be + // returned than requested. If unspecified or set to 0, this defaults to 1000. + // The maximum value is 1000; values above 1000 will be coerced down to 1000. + PageSize *int + // An optional page token received from a previous list tag policies call. + PageToken *string +} + +type ListTagPoliciesResponse struct { + TagPolicies []TagPolicy + NextPageToken *string +} + +type TagPolicy struct { + TagKey *string `fieldmask:"tag_key"` + Id *string `fieldmask:"id"` + Description *string `fieldmask:"description"` + Values []Value `fieldmask:"values"` + // Timestamp when the tag policy was created + CreateTime *types.Time `fieldmask:"create_time"` + // Timestamp when the tag policy was last updated + UpdateTime *types.Time `fieldmask:"update_time"` +} + +type UpdateTagPolicyRequest struct { + TagPolicy *TagPolicy + UpdateMask *types.FieldMask[TagPolicy] +} + +type Value struct { + Name *string +} diff --git a/tagpolicies/v1/wire.go b/tagpolicies/v1/wire.go new file mode 100755 index 0000000..090efd7 --- /dev/null +++ b/tagpolicies/v1/wire.go @@ -0,0 +1,169 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tagpolicies + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createTagPolicyRequestWire struct { + TagPolicy *tagPolicyWire `json:"tag_policy,omitempty"` +} + +func createTagPolicyRequestToWire(v *CreateTagPolicyRequest) (*createTagPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + tagPolicyWireValue, err := tagPolicyToWire(v.TagPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTagPolicyRequest.TagPolicy", err) + } + return &createTagPolicyRequestWire{ + TagPolicy: tagPolicyWireValue, + }, nil +} + +type listTagPoliciesRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listTagPoliciesRequestToWire(v *ListTagPoliciesRequest) (*listTagPoliciesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listTagPoliciesRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listTagPoliciesResponseWire struct { + TagPolicies []tagPolicyWire `json:"tag_policies,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listTagPoliciesResponseFromWire(w *listTagPoliciesResponseWire) (*ListTagPoliciesResponse, error) { + if w == nil { + return nil, nil + } + tagPoliciesPublicValue, err := convertSlice(w.TagPolicies, tagPolicyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListTagPoliciesResponse.TagPolicies", err) + } + return &ListTagPoliciesResponse{ + TagPolicies: tagPoliciesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type tagPolicyWire struct { + TagKey *string `json:"tag_key,omitempty"` + Id *string `json:"id,omitempty"` + Description *string `json:"description,omitempty"` + Values []valueWire `json:"values,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` +} + +func tagPolicyToWire(v *TagPolicy) (*tagPolicyWire, error) { + if v == nil { + return nil, nil + } + valuesWireValue, err := convertSlice(v.Values, valueToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TagPolicy.Values", err) + } + return &tagPolicyWire{ + TagKey: v.TagKey, + Id: v.Id, + Description: v.Description, + Values: valuesWireValue, + CreateTime: v.CreateTime, + UpdateTime: v.UpdateTime, + }, nil +} + +func tagPolicyFromWire(w *tagPolicyWire) (*TagPolicy, error) { + if w == nil { + return nil, nil + } + valuesPublicValue, err := convertSlice(w.Values, valueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TagPolicy.Values", err) + } + return &TagPolicy{ + TagKey: w.TagKey, + Id: w.Id, + Description: w.Description, + Values: valuesPublicValue, + CreateTime: w.CreateTime, + UpdateTime: w.UpdateTime, + }, nil +} + +type updateTagPolicyRequestWire struct { + TagPolicy *tagPolicyWire `json:"tag_policy,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateTagPolicyRequestToWire(v *UpdateTagPolicyRequest) (*updateTagPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + tagPolicyWireValue, err := tagPolicyToWire(v.TagPolicy) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTagPolicyRequest.TagPolicy", err) + } + return &updateTagPolicyRequestWire{ + TagPolicy: tagPolicyWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type valueWire struct { + Name *string `json:"name,omitempty"` +} + +func valueToWire(v *Value) (*valueWire, error) { + if v == nil { + return nil, nil + } + return &valueWire{ + Name: v.Name, + }, nil +} + +func valueFromWire(w *valueWire) (*Value, error) { + if w == nil { + return nil, nil + } + return &Value{ + Name: w.Name, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/tokenmanagement/.package.json b/tokenmanagement/.package.json new file mode 100644 index 0000000..67266dc --- /dev/null +++ b/tokenmanagement/.package.json @@ -0,0 +1,3 @@ +{ + "package": "tokenmanagement" +} diff --git a/tokenmanagement/CHANGELOG.md b/tokenmanagement/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/tokenmanagement/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/tokenmanagement/README.md b/tokenmanagement/README.md new file mode 100644 index 0000000..bee05a8 --- /dev/null +++ b/tokenmanagement/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/tokenmanagement + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/tokenmanagement@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/tokenmanagement/v1" + +client, err := tokenmanagement.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/tokenmanagement/go.mod b/tokenmanagement/go.mod new file mode 100644 index 0000000..b3f18e6 --- /dev/null +++ b/tokenmanagement/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/tokenmanagement + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/tokenmanagement/internal/version.go b/tokenmanagement/internal/version.go new file mode 100644 index 0000000..ed841ed --- /dev/null +++ b/tokenmanagement/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-tokenmanagement" + +const Version = "0.0.1-dev.1" diff --git a/tokenmanagement/v1/client.go b/tokenmanagement/v1/client.go new file mode 100755 index 0000000..c6e2321 --- /dev/null +++ b/tokenmanagement/v1/client.go @@ -0,0 +1,390 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tokenmanagement + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/tokenmanagement/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a token on behalf of a service principal. +func (c *internalClient) CreateOnBehalfOfToken(ctx context.Context, req *CreateOnBehalfOfTokenRequest, opts ...call.Option) (*CreateOnBehalfOfTokenResponse, error) { + wireReq, err := createOnBehalfOfTokenRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/token-management/on-behalf-of/tokens" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateOnBehalfOfTokenResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createOnBehalfOfTokenResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createOnBehalfOfTokenResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a token, specified by its ID. +func (c *internalClient) DeleteToken(ctx context.Context, req *RevokeTokenRequest, opts ...call.Option) (*RevokeTokenResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/token-management/tokens/") + pb.singleSegment(*req.TokenId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RevokeTokenResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &RevokeTokenResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets information about a token, specified by its ID. +func (c *internalClient) GetToken(ctx context.Context, req *GetTokenRequest, opts ...call.Option) (*GetTokenResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/token-management/tokens/") + pb.singleSegment(*req.TokenId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetTokenResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getTokenResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getTokenResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists all tokens associated with the specified workspace or user. +func (c *internalClient) ListTokens(ctx context.Context, req *ListTokensRequest, opts ...call.Option) (*ListTokensResponse, error) { + wireReq, err := listTokensRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/token-management/tokens" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "created_by_id", wireReq.CreatedById); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "created_by_username", wireReq.CreatedByUsername); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListTokensResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listTokensResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listTokensResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a token, specified by its ID. +func (c *internalClient) UpdateToken(ctx context.Context, req *UpdateTokenRequest, opts ...call.Option) (*AdminTokenInfo, error) { + wireReq, err := updateTokenRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/token-management/tokens/") + pb.singleSegment(*req.Token.TokenId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AdminTokenInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp adminTokenInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = adminTokenInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/tokenmanagement/v1/genhelper.go b/tokenmanagement/v1/genhelper.go new file mode 100755 index 0000000..75abc18 --- /dev/null +++ b/tokenmanagement/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tokenmanagement + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/tokenmanagement/v1/model.go b/tokenmanagement/v1/model.go new file mode 100755 index 0000000..6475ddd --- /dev/null +++ b/tokenmanagement/v1/model.go @@ -0,0 +1,128 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tokenmanagement + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// State of inferred scope collection (autoscope) for an external PAT. Mirrored +// in databricks.identity.AutoscopeState in +// common/principal-context/api/proto/tokendetails.proto. Token store and token +// management proto can depend on this. Principal context proto should NOT +// depend on this proto definitions because too many services depend on the +// principal context proto. +type AutoscopeState string + +const ( + AutoscopeState_Unspecified AutoscopeState = "" + AutoscopeState_AutoscopeStateDisabled AutoscopeState = "AUTOSCOPE_STATE_DISABLED" + AutoscopeState_AutoscopeStateRunning AutoscopeState = "AUTOSCOPE_STATE_RUNNING" + AutoscopeState_AutoscopeStateCompleted AutoscopeState = "AUTOSCOPE_STATE_COMPLETED" + AutoscopeState_AutoscopeStateBackfilled AutoscopeState = "AUTOSCOPE_STATE_BACKFILLED" + AutoscopeState_AutoscopeStateUserSelected AutoscopeState = "AUTOSCOPE_STATE_USER_SELECTED" + AutoscopeState_AutoscopeStateApiNotCovered AutoscopeState = "AUTOSCOPE_STATE_API_NOT_COVERED" +) + +type AdminTokenInfo struct { + // ID of the token. + TokenId *string `fieldmask:"token_id"` + // Timestamp when the token was created. + CreationTime *int64 `fieldmask:"creation_time"` + // Timestamp when the token expires. + ExpiryTime *int64 `fieldmask:"expiry_time"` + // Comment that describes the purpose of the token, specified by the token + // creator. + Comment *string `fieldmask:"comment"` + // User ID of the user that created the token. + CreatedById *int64 `fieldmask:"created_by_id"` + // Username of the user that created the token. + CreatedByUsername *string `fieldmask:"created_by_username"` + // User ID of the user that owns the token. + OwnerId *int64 `fieldmask:"owner_id"` + // If applicable, the ID of the workspace that the token was created in. + WorkspaceId *int64 `fieldmask:"workspace_id"` + // Approximate timestamp for the day the token was last used. Accurate up to 1 + // day. + LastUsedDay *int64 `fieldmask:"last_used_day"` + // Scope of the token was created with, if applicable. + Scopes []string `fieldmask:"scopes"` + // Output only. The autoscope state of this token. + AutoscopeState AutoscopeState `fieldmask:"autoscope_state"` + // Output only. Inferred API path scopes collected for this token when autoscope + // is enabled. + InferredScopes []string `fieldmask:"inferred_scopes"` + // Output only. Scopes inferred from offline backfill processing. + BackfillScopes []string `fieldmask:"backfill_scopes"` +} + +// Configuration details for creating on-behalf tokens.. +type CreateOnBehalfOfTokenRequest struct { + // Application ID of the service principal. + ApplicationId *string + // The number of seconds before the token expires. + LifetimeSeconds *int64 + // Comment that describes the purpose of the token. + Comment *string + Scopes []string + // Whether to enable autoscoping for this token. + AutoscopeEnabled *bool +} + +// An on-behalf token was successfully created for the service principal.. +type CreateOnBehalfOfTokenResponse struct { + // Value of the token. + TokenValue *string + TokenInfo *AdminTokenInfo +} + +// !! KEEP THIS IN-SYNC WITH THE WORKSPACE PROTO DEFINITIONS IN SERVICE.PROTO !! +// +// The only differences should be: 1. The OpenAPI labels. 2. The account_id +// request parameter.. +type GetTokenRequest struct { + // The ID of the token to get. + TokenId *string +} + +// Token with specified Token ID was successfully returned.. +type GetTokenResponse struct { + TokenInfo *AdminTokenInfo +} + +// !! KEEP THIS IN-SYNC WITH THE ACCOUNT PROTO DEFINITIONS IN +// ACCOUNT_SERVICE.PROTO !! +// +// The only differences should be: 1. The OpenAPI labels. 2. The account_id +// request parameter. 3. The string filter parameter instead of hard-coded +// filters.. +type ListTokensRequest struct { + // User ID of the user that created the token. + CreatedById *int64 + // Username of the user that created the token. + CreatedByUsername *string +} + +// Tokens were successfully returned.. +type ListTokensResponse struct { + // Token metadata of each user-created token in the workspace + TokenInfos []AdminTokenInfo +} + +type RevokeTokenRequest struct { + // The ID of the token to revoke. + TokenId *string +} + +// The token was successfully deleted.. +type RevokeTokenResponse struct { +} + +// For the list of supported token scopes, see +// https://docs.databricks.com/api/workspace/api/scopes.. +type UpdateTokenRequest struct { + Token *AdminTokenInfo + // A list of field name under token, For example, {"update_mask": + // "comment,scopes"} + UpdateMask *types.FieldMask[AdminTokenInfo] +} diff --git a/tokenmanagement/v1/wire.go b/tokenmanagement/v1/wire.go new file mode 100755 index 0000000..280664e --- /dev/null +++ b/tokenmanagement/v1/wire.go @@ -0,0 +1,198 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tokenmanagement + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type adminTokenInfoWire struct { + TokenId *string `json:"token_id,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + ExpiryTime *int64 `json:"expiry_time,omitempty"` + Comment *string `json:"comment,omitempty"` + CreatedById *int64 `json:"created_by_id,omitempty"` + CreatedByUsername *string `json:"created_by_username,omitempty"` + OwnerId *int64 `json:"owner_id,omitempty"` + WorkspaceId *int64 `json:"workspace_id,omitempty"` + LastUsedDay *int64 `json:"last_used_day,omitempty"` + Scopes []string `json:"scopes,omitempty"` + AutoscopeState AutoscopeState `json:"autoscope_state,omitempty"` + InferredScopes []string `json:"inferred_scopes,omitempty"` + BackfillScopes []string `json:"backfill_scopes,omitempty"` +} + +func adminTokenInfoToWire(v *AdminTokenInfo) (*adminTokenInfoWire, error) { + if v == nil { + return nil, nil + } + return &adminTokenInfoWire{ + TokenId: v.TokenId, + CreationTime: v.CreationTime, + ExpiryTime: v.ExpiryTime, + Comment: v.Comment, + CreatedById: v.CreatedById, + CreatedByUsername: v.CreatedByUsername, + OwnerId: v.OwnerId, + WorkspaceId: v.WorkspaceId, + LastUsedDay: v.LastUsedDay, + Scopes: v.Scopes, + AutoscopeState: v.AutoscopeState, + InferredScopes: v.InferredScopes, + BackfillScopes: v.BackfillScopes, + }, nil +} + +func adminTokenInfoFromWire(w *adminTokenInfoWire) (*AdminTokenInfo, error) { + if w == nil { + return nil, nil + } + return &AdminTokenInfo{ + TokenId: w.TokenId, + CreationTime: w.CreationTime, + ExpiryTime: w.ExpiryTime, + Comment: w.Comment, + CreatedById: w.CreatedById, + CreatedByUsername: w.CreatedByUsername, + OwnerId: w.OwnerId, + WorkspaceId: w.WorkspaceId, + LastUsedDay: w.LastUsedDay, + Scopes: w.Scopes, + AutoscopeState: w.AutoscopeState, + InferredScopes: w.InferredScopes, + BackfillScopes: w.BackfillScopes, + }, nil +} + +type createOnBehalfOfTokenRequestWire struct { + ApplicationId *string `json:"application_id,omitempty"` + LifetimeSeconds *int64 `json:"lifetime_seconds,omitempty"` + Comment *string `json:"comment,omitempty"` + Scopes []string `json:"scopes,omitempty"` + AutoscopeEnabled *bool `json:"autoscope_enabled,omitempty"` +} + +func createOnBehalfOfTokenRequestToWire(v *CreateOnBehalfOfTokenRequest) (*createOnBehalfOfTokenRequestWire, error) { + if v == nil { + return nil, nil + } + return &createOnBehalfOfTokenRequestWire{ + ApplicationId: v.ApplicationId, + LifetimeSeconds: v.LifetimeSeconds, + Comment: v.Comment, + Scopes: v.Scopes, + AutoscopeEnabled: v.AutoscopeEnabled, + }, nil +} + +type createOnBehalfOfTokenResponseWire struct { + TokenValue *string `json:"token_value,omitempty"` + TokenInfo *adminTokenInfoWire `json:"token_info,omitempty"` +} + +func createOnBehalfOfTokenResponseFromWire(w *createOnBehalfOfTokenResponseWire) (*CreateOnBehalfOfTokenResponse, error) { + if w == nil { + return nil, nil + } + tokenInfoPublicValue, err := adminTokenInfoFromWire(w.TokenInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateOnBehalfOfTokenResponse.TokenInfo", err) + } + return &CreateOnBehalfOfTokenResponse{ + TokenValue: w.TokenValue, + TokenInfo: tokenInfoPublicValue, + }, nil +} + +type getTokenResponseWire struct { + TokenInfo *adminTokenInfoWire `json:"token_info,omitempty"` +} + +func getTokenResponseFromWire(w *getTokenResponseWire) (*GetTokenResponse, error) { + if w == nil { + return nil, nil + } + tokenInfoPublicValue, err := adminTokenInfoFromWire(w.TokenInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetTokenResponse.TokenInfo", err) + } + return &GetTokenResponse{ + TokenInfo: tokenInfoPublicValue, + }, nil +} + +type listTokensRequestWire struct { + CreatedById *int64 `json:"created_by_id,omitempty"` + CreatedByUsername *string `json:"created_by_username,omitempty"` +} + +func listTokensRequestToWire(v *ListTokensRequest) (*listTokensRequestWire, error) { + if v == nil { + return nil, nil + } + return &listTokensRequestWire{ + CreatedById: v.CreatedById, + CreatedByUsername: v.CreatedByUsername, + }, nil +} + +type listTokensResponseWire struct { + TokenInfos []adminTokenInfoWire `json:"token_infos,omitempty"` +} + +func listTokensResponseFromWire(w *listTokensResponseWire) (*ListTokensResponse, error) { + if w == nil { + return nil, nil + } + tokenInfosPublicValue, err := convertSlice(w.TokenInfos, adminTokenInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListTokensResponse.TokenInfos", err) + } + return &ListTokensResponse{ + TokenInfos: tokenInfosPublicValue, + }, nil +} + +type updateTokenRequestWire struct { + Token *adminTokenInfoWire `json:"token,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateTokenRequestToWire(v *UpdateTokenRequest) (*updateTokenRequestWire, error) { + if v == nil { + return nil, nil + } + tokenWireValue, err := adminTokenInfoToWire(v.Token) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTokenRequest.Token", err) + } + return &updateTokenRequestWire{ + Token: tokenWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/tokens/.package.json b/tokens/.package.json new file mode 100644 index 0000000..858d0e1 --- /dev/null +++ b/tokens/.package.json @@ -0,0 +1,3 @@ +{ + "package": "tokens" +} diff --git a/tokens/CHANGELOG.md b/tokens/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/tokens/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/tokens/README.md b/tokens/README.md new file mode 100644 index 0000000..f951cb7 --- /dev/null +++ b/tokens/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/tokens + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/tokens@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/tokens/v1" + +client, err := tokens.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/tokens/go.mod b/tokens/go.mod new file mode 100644 index 0000000..64dbc98 --- /dev/null +++ b/tokens/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/tokens + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/tokens/internal/version.go b/tokens/internal/version.go new file mode 100644 index 0000000..ac6da6d --- /dev/null +++ b/tokens/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-tokens" + +const Version = "0.0.1-dev.1" diff --git a/tokens/v1/client.go b/tokens/v1/client.go new file mode 100755 index 0000000..e262933 --- /dev/null +++ b/tokens/v1/client.go @@ -0,0 +1,329 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tokens + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/tokens/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates and returns a token for a user. If this call is made through token +// authentication, it creates a token with the same client ID as the +// authenticated token. If the user's token quota is exceeded, this call returns +// an error **QUOTA_EXCEEDED**. +func (c *internalClient) CreateToken(ctx context.Context, req *CreateTokenRequest, opts ...call.Option) (*CreateTokenResponse, error) { + wireReq, err := createTokenRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/token/create" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateTokenResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createTokenResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createTokenResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists all the valid tokens for a user-workspace pair. +func (c *internalClient) ListTokens(ctx context.Context, req *ListTokensRequest, opts ...call.Option) (*ListTokensResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/token/list" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListTokensResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listTokensResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listTokensResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Revokes an access token. +// +// If a token with the specified ID is not valid, this call returns an error +// **RESOURCE_DOES_NOT_EXIST**. +func (c *internalClient) RevokeToken(ctx context.Context, req *RevokeTokenRequest, opts ...call.Option) (*RevokeTokenResponse, error) { + wireReq, err := revokeTokenRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/token/delete" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RevokeTokenResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &RevokeTokenResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the comment or scopes of a token. +// +// If a token with the specified ID is not valid, this call returns an error +// **NOT_FOUND**. +func (c *internalClient) UpdateToken(ctx context.Context, req *UpdateTokenRequest, opts ...call.Option) (*UpdateTokenResponse, error) { + wireReq, err := updateTokenRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/token/") + pb.singleSegment(*req.TokenId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateTokenResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateTokenResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/tokens/v1/genhelper.go b/tokens/v1/genhelper.go new file mode 100755 index 0000000..d0d3727 --- /dev/null +++ b/tokens/v1/genhelper.go @@ -0,0 +1,188 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tokens + +import ( + "context" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/tokens/v1/model.go b/tokens/v1/model.go new file mode 100755 index 0000000..58901e5 --- /dev/null +++ b/tokens/v1/model.go @@ -0,0 +1,97 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tokens + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// State of inferred scope collection (autoscope) for an external PAT. Mirrored +// in databricks.identity.AutoscopeState in +// common/principal-context/api/proto/tokendetails.proto. Token store and token +// management proto can depend on this. Principal context proto should NOT +// depend on this proto definitions because too many services depend on the +// principal context proto. +type AutoscopeState string + +const ( + AutoscopeState_Unspecified AutoscopeState = "" + AutoscopeState_AutoscopeStateDisabled AutoscopeState = "AUTOSCOPE_STATE_DISABLED" + AutoscopeState_AutoscopeStateRunning AutoscopeState = "AUTOSCOPE_STATE_RUNNING" + AutoscopeState_AutoscopeStateCompleted AutoscopeState = "AUTOSCOPE_STATE_COMPLETED" + AutoscopeState_AutoscopeStateBackfilled AutoscopeState = "AUTOSCOPE_STATE_BACKFILLED" + AutoscopeState_AutoscopeStateUserSelected AutoscopeState = "AUTOSCOPE_STATE_USER_SELECTED" + AutoscopeState_AutoscopeStateApiNotCovered AutoscopeState = "AUTOSCOPE_STATE_API_NOT_COVERED" +) + +type CreateTokenRequest struct { + // The lifetime of the token, in seconds. + // + // If the lifetime is not specified, this token remains valid for 2 years. + LifetimeSeconds *int64 + // Optional description to attach to the token. + Comment *string + // Optional scopes of the token. + Scopes []string + // Whether to enable autoscoping for this token. When true, the token will + // automatically collect inferred API path scopes as it is used. + AutoscopeEnabled *bool +} + +type CreateTokenResponse struct { + // The value of the new token. + TokenValue *string + // The information for the new token. + TokenInfo *PublicTokenInfo +} + +type ListTokensRequest struct { +} + +type ListTokensResponse struct { + // The information for each token. + TokenInfos []PublicTokenInfo +} + +type PublicTokenInfo struct { + // The ID of this token. + TokenId *string `fieldmask:"token_id"` + // Server time (in epoch milliseconds) when the token was created. + CreationTime *int64 `fieldmask:"creation_time"` + // Server time (in epoch milliseconds) when the token will expire, or -1 if not + // applicable. + ExpiryTime *int64 `fieldmask:"expiry_time"` + // Comment the token was created with, if applicable. + Comment *string `fieldmask:"comment"` + // Scope of the token was created with, if applicable. + Scopes []string `fieldmask:"scopes"` + // Output only. The autoscope state of this token. + AutoscopeState AutoscopeState `fieldmask:"autoscope_state"` + // Output only. Inferred API path scopes collected for this token when autoscope + // is enabled. + InferredScopes []string `fieldmask:"inferred_scopes"` + // Output only. Scopes inferred from offline backfill processing. + BackfillScopes []string `fieldmask:"backfill_scopes"` +} + +type RevokeTokenRequest struct { + // The ID of the token to be revoked. + TokenId *string +} + +type RevokeTokenResponse struct { +} + +// For the list of supported token scopes, see +// https://docs.databricks.com/api/workspace/api/scopes.. +type UpdateTokenRequest struct { + // The SHA-256 hash of the token to be updated. + TokenId *string + Token *PublicTokenInfo + // A list of field name under token, For example, {"update_mask": + // "comment,scopes"} + UpdateMask *types.FieldMask[PublicTokenInfo] +} + +type UpdateTokenResponse struct { +} diff --git a/tokens/v1/wire.go b/tokens/v1/wire.go new file mode 100755 index 0000000..f1d57de --- /dev/null +++ b/tokens/v1/wire.go @@ -0,0 +1,164 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tokens + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createTokenRequestWire struct { + LifetimeSeconds *int64 `json:"lifetime_seconds,omitempty"` + Comment *string `json:"comment,omitempty"` + Scopes []string `json:"scopes,omitempty"` + AutoscopeEnabled *bool `json:"autoscope_enabled,omitempty"` +} + +func createTokenRequestToWire(v *CreateTokenRequest) (*createTokenRequestWire, error) { + if v == nil { + return nil, nil + } + return &createTokenRequestWire{ + LifetimeSeconds: v.LifetimeSeconds, + Comment: v.Comment, + Scopes: v.Scopes, + AutoscopeEnabled: v.AutoscopeEnabled, + }, nil +} + +type createTokenResponseWire struct { + TokenValue *string `json:"token_value,omitempty"` + TokenInfo *publicTokenInfoWire `json:"token_info,omitempty"` +} + +func createTokenResponseFromWire(w *createTokenResponseWire) (*CreateTokenResponse, error) { + if w == nil { + return nil, nil + } + tokenInfoPublicValue, err := publicTokenInfoFromWire(w.TokenInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTokenResponse.TokenInfo", err) + } + return &CreateTokenResponse{ + TokenValue: w.TokenValue, + TokenInfo: tokenInfoPublicValue, + }, nil +} + +type listTokensResponseWire struct { + TokenInfos []publicTokenInfoWire `json:"token_infos,omitempty"` +} + +func listTokensResponseFromWire(w *listTokensResponseWire) (*ListTokensResponse, error) { + if w == nil { + return nil, nil + } + tokenInfosPublicValue, err := convertSlice(w.TokenInfos, publicTokenInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListTokensResponse.TokenInfos", err) + } + return &ListTokensResponse{ + TokenInfos: tokenInfosPublicValue, + }, nil +} + +type publicTokenInfoWire struct { + TokenId *string `json:"token_id,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + ExpiryTime *int64 `json:"expiry_time,omitempty"` + Comment *string `json:"comment,omitempty"` + Scopes []string `json:"scopes,omitempty"` + AutoscopeState AutoscopeState `json:"autoscope_state,omitempty"` + InferredScopes []string `json:"inferred_scopes,omitempty"` + BackfillScopes []string `json:"backfill_scopes,omitempty"` +} + +func publicTokenInfoToWire(v *PublicTokenInfo) (*publicTokenInfoWire, error) { + if v == nil { + return nil, nil + } + return &publicTokenInfoWire{ + TokenId: v.TokenId, + CreationTime: v.CreationTime, + ExpiryTime: v.ExpiryTime, + Comment: v.Comment, + Scopes: v.Scopes, + AutoscopeState: v.AutoscopeState, + InferredScopes: v.InferredScopes, + BackfillScopes: v.BackfillScopes, + }, nil +} + +func publicTokenInfoFromWire(w *publicTokenInfoWire) (*PublicTokenInfo, error) { + if w == nil { + return nil, nil + } + return &PublicTokenInfo{ + TokenId: w.TokenId, + CreationTime: w.CreationTime, + ExpiryTime: w.ExpiryTime, + Comment: w.Comment, + Scopes: w.Scopes, + AutoscopeState: w.AutoscopeState, + InferredScopes: w.InferredScopes, + BackfillScopes: w.BackfillScopes, + }, nil +} + +type revokeTokenRequestWire struct { + TokenId *string `json:"token_id,omitempty"` +} + +func revokeTokenRequestToWire(v *RevokeTokenRequest) (*revokeTokenRequestWire, error) { + if v == nil { + return nil, nil + } + return &revokeTokenRequestWire{ + TokenId: v.TokenId, + }, nil +} + +type updateTokenRequestWire struct { + TokenId *string `json:"token_id,omitempty"` + Token *publicTokenInfoWire `json:"token,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateTokenRequestToWire(v *UpdateTokenRequest) (*updateTokenRequestWire, error) { + if v == nil { + return nil, nil + } + tokenWireValue, err := publicTokenInfoToWire(v.Token) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTokenRequest.Token", err) + } + return &updateTokenRequestWire{ + TokenId: v.TokenId, + Token: tokenWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/abacpolicies/.package.json b/uc/abacpolicies/.package.json new file mode 100644 index 0000000..32345c3 --- /dev/null +++ b/uc/abacpolicies/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/abacpolicies" +} diff --git a/uc/abacpolicies/CHANGELOG.md b/uc/abacpolicies/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/abacpolicies/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/abacpolicies/README.md b/uc/abacpolicies/README.md new file mode 100644 index 0000000..ebca522 --- /dev/null +++ b/uc/abacpolicies/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/abacpolicies + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/abacpolicies@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/abacpolicies/v1" + +client, err := abacpolicies.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/abacpolicies/go.mod b/uc/abacpolicies/go.mod new file mode 100644 index 0000000..836252e --- /dev/null +++ b/uc/abacpolicies/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/abacpolicies + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/abacpolicies/internal/version.go b/uc/abacpolicies/internal/version.go new file mode 100644 index 0000000..cdd62d5 --- /dev/null +++ b/uc/abacpolicies/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-abacpolicies" + +const Version = "0.0.1-dev.1" diff --git a/uc/abacpolicies/v1/client.go b/uc/abacpolicies/v1/client.go new file mode 100755 index 0000000..249a235 --- /dev/null +++ b/uc/abacpolicies/v1/client.go @@ -0,0 +1,465 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package abacpolicies + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/abacpolicies/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new policy on a securable. The new policy applies to the securable +// and all its descendants. +func (c *internalClient) CreatePolicy(ctx context.Context, req *CreatePolicyRequest, opts ...call.Option) (*PolicyInfo, error) { + wireReq, err := createPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.PolicyInfo) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/policies" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PolicyInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp policyInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = policyInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete an ABAC policy defined on a securable. +func (c *internalClient) DeletePolicy(ctx context.Context, req *DeletePolicyRequest, opts ...call.Option) (*DeletePolicyResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/policies/") + pb.singleSegment(*req.OnSecurableType) + pb.literal("/") + pb.singleSegment(*req.OnSecurableFullname) + pb.literal("/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeletePolicyResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeletePolicyResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get the policy definition on a securable +func (c *internalClient) GetPolicy(ctx context.Context, req *GetPolicyRequest, opts ...call.Option) (*PolicyInfo, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/policies/") + pb.singleSegment(*req.OnSecurableType) + pb.literal("/") + pb.singleSegment(*req.OnSecurableFullname) + pb.literal("/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PolicyInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp policyInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = policyInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List all policies defined on a securable. Optionally, the list can include +// inherited policies defined on the securable's parent schema or catalog. +// +// PAGINATION BEHAVIOR: The API is by default paginated, a page may contain zero +// results while still providing a next_page_token. Clients must continue +// reading pages until next_page_token is absent, which is the only indication +// that the end of results has been reached. +func (c *internalClient) ListPolicies(ctx context.Context, req *ListPoliciesRequest, opts ...call.Option) (*ListPoliciesResponse, error) { + wireReq, err := listPoliciesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/policies/") + pb.singleSegment(*req.OnSecurableType) + pb.literal("/") + pb.singleSegment(*req.OnSecurableFullname) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_inherited", wireReq.IncludeInherited); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPoliciesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listPoliciesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listPoliciesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListPoliciesIter returns an iterator that iterates +// over the results of ListPolicies. +// +// For example: +// +// for item, err := range c.ListPoliciesIter(ctx, &ListPoliciesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListPolicies call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListPolicies directly. +func (c *internalClient) ListPoliciesIter(ctx context.Context, req *ListPoliciesRequest, opts ...call.Option) iter.Seq2[*PolicyInfo, error] { + return func(yield func(*PolicyInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListPoliciesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListPolicies(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Policies { + if !yield(&resp.Policies[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Update an ABAC policy on a securable. +func (c *internalClient) UpdatePolicy(ctx context.Context, req *UpdatePolicyRequest, opts ...call.Option) (*PolicyInfo, error) { + wireReq, err := updatePolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.PolicyInfo) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/policies/") + pb.singleSegment(*req.OnSecurableType) + pb.literal("/") + pb.singleSegment(*req.OnSecurableFullname) + pb.literal("/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PolicyInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp policyInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = policyInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/abacpolicies/v1/genhelper.go b/uc/abacpolicies/v1/genhelper.go new file mode 100755 index 0000000..70c1216 --- /dev/null +++ b/uc/abacpolicies/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package abacpolicies + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/abacpolicies/v1/model.go b/uc/abacpolicies/v1/model.go new file mode 100755 index 0000000..fc8bcb4 --- /dev/null +++ b/uc/abacpolicies/v1/model.go @@ -0,0 +1,269 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package abacpolicies + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type PolicyType string + +const ( + PolicyType_Unspecified PolicyType = "" + PolicyType_PolicyTypeRowFilter PolicyType = "POLICY_TYPE_ROW_FILTER" + PolicyType_PolicyTypeColumnMask PolicyType = "POLICY_TYPE_COLUMN_MASK" + PolicyType_PolicyTypeGrant PolicyType = "POLICY_TYPE_GRANT" +) + +// The type of Unity Catalog securable. +type SecurableType string + +const ( + SecurableType_Unspecified SecurableType = "" + SecurableType_Catalog SecurableType = "CATALOG" + SecurableType_Schema SecurableType = "SCHEMA" + SecurableType_Table SecurableType = "TABLE" + SecurableType_StorageCredential SecurableType = "STORAGE_CREDENTIAL" + SecurableType_ExternalLocation SecurableType = "EXTERNAL_LOCATION" + SecurableType_Function SecurableType = "FUNCTION" + SecurableType_Share SecurableType = "SHARE" + SecurableType_Provider SecurableType = "PROVIDER" + SecurableType_Recipient SecurableType = "RECIPIENT" + SecurableType_CleanRoom SecurableType = "CLEAN_ROOM" + SecurableType_Metastore SecurableType = "METASTORE" + SecurableType_Pipeline SecurableType = "PIPELINE" + SecurableType_Volume SecurableType = "VOLUME" + SecurableType_Connection SecurableType = "CONNECTION" + SecurableType_Credential SecurableType = "CREDENTIAL" + SecurableType_ExternalMetadata SecurableType = "EXTERNAL_METADATA" + // TODO: [UC-2980] Staging tables aren't full-fleged securables yet. + SecurableType_StagingTable SecurableType = "STAGING_TABLE" +) + +type ColumnMaskOptions struct { + // The fully qualified name of the column mask function. The function is called + // on each row of the target table. The function's first argument and its return + // type should match the type of the masked column. Required on create and + // update. + FunctionName *string `fieldmask:"function_name"` + // The alias of the column to be masked. The alias must refer to one of matched + // columns. The values of the column is passed to the column mask function as + // the first argument. Required on create and update. + OnColumn *string `fieldmask:"on_column"` + // Optional list of column aliases or constant literals to be passed as + // additional arguments to the column mask function. The type of each column + // should match the positional argument of the column mask function. + Using []FunctionArgument `fieldmask:"using"` +} + +type CreatePolicyRequest struct { + // Required. The policy to create. + PolicyInfo *PolicyInfo +} + +type DeletePolicyRequest struct { + // Required. The type of the securable to delete the policy from. + OnSecurableType *string + // Required. The fully qualified name of the securable to delete the policy + // from. + OnSecurableFullname *string + // Required. The name of the policy to delete + Name *string +} + +type DeletePolicyResponse struct { +} + +type FunctionArgument struct { + // A positional argument pass to a row filter or column mask function. + Arg isFunctionArgument_Arg +} + +type isFunctionArgument_Arg interface { + isFunctionArgument_Arg() +} + +// FunctionArgument_Arg_Alias selects Alias for FunctionArgument.Arg. +// The alias of a matched column. +type FunctionArgument_Arg_Alias struct { + Alias string +} + +func (*FunctionArgument_Arg_Alias) isFunctionArgument_Arg() {} + +// FunctionArgument_Arg_Constant selects Constant for FunctionArgument.Arg. +// A constant literal. +type FunctionArgument_Arg_Constant struct { + Constant string +} + +func (*FunctionArgument_Arg_Constant) isFunctionArgument_Arg() {} + +type GetPolicyRequest struct { + // Required. The type of the securable to retrieve the policy for. + OnSecurableType *string + // Required. The fully qualified name of securable to retrieve policy for. + OnSecurableFullname *string + // Required. The name of the policy to retrieve. + Name *string +} + +type GrantOptions struct { + // List of privileges to grant. When any of these privileges are requested, the + // policy will grant access if the principal and condition match. Required on + // create and update. + Privileges []string `fieldmask:"privileges"` +} + +type ListPoliciesRequest struct { + // Required. The type of the securable to list policies for. + OnSecurableType *string + // Required. The fully qualified name of securable to list policies for. + OnSecurableFullname *string + // Optional. Whether to include policies defined on parent securables. By + // default, the inherited policies are not included. + IncludeInherited *bool + // Optional. Maximum number of policies to return on a single page (page + // length). - When not set or set to 0, the page length is set to a server + // configured value (recommended); - When set to a value greater than 0, the + // page length is the minimum of this value and a server configured value; + MaxResults *int + // Optional. Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListPoliciesResponse struct { + // The list of retrieved policies. + Policies []PolicyInfo + // Optional opaque token for continuing pagination. `page_token` should be set + // to this value for the next request to retrieve the next page of results. + NextPageToken *string +} + +type MatchColumn struct { + // The condition expression used to match a table column. + Condition *string + // Optional alias of the matched column. + Alias *string +} + +type PolicyInfo struct { + // Unique identifier of the policy. This field is output only and is generated + // by the system. + Id *string `fieldmask:"id"` + // Type of the securable on which the policy is defined. Only `CATALOG`, + // `SCHEMA` and `TABLE` are supported at this moment. Required on create. + OnSecurableType SecurableType `fieldmask:"on_securable_type"` + // Full name of the securable on which the policy is defined. Required on + // create. + OnSecurableFullname *string `fieldmask:"on_securable_fullname"` + // Name of the policy. Required on create and optional on update. To rename the + // policy, set `name` to a different value on update. + Name *string `fieldmask:"name"` + // Optional description of the policy. + Comment *string `fieldmask:"comment"` + // List of user or group names that the policy applies to. Required on create + // and optional on update. + ToPrincipals []string `fieldmask:"to_principals"` + // Optional list of user or group names that should be excluded from the policy. + ExceptPrincipals []string `fieldmask:"except_principals"` + // Type of securables that the policy should take effect on. Required on create + // and optional on update. + ForSecurableType SecurableType `fieldmask:"for_securable_type"` + // Optional condition when the policy should take effect. + WhenCondition *string `fieldmask:"when_condition"` + // Type of the policy. Required on create. + PolicyType PolicyType `fieldmask:"policy_type"` + // (--[Create:REQ Update:OPT] Type-specific options for the Policy--) + // Type-specific options for the policy. + Options isPolicyInfo_Options + // Optional list of condition expressions used to match table columns. Only + // valid when `for_securable_type` is `TABLE`. When specified, the policy only + // applies to tables whose columns satisfy all match conditions. + MatchColumns []MatchColumn `fieldmask:"match_columns"` + // Time at which the policy was created, in epoch milliseconds. Output only. + CreatedAt *int64 `fieldmask:"created_at"` + // Username of the user who created the policy. Output only. + CreatedBy *string `fieldmask:"created_by"` + // Time at which the policy was last modified, in epoch milliseconds. Output + // only. + UpdatedAt *int64 `fieldmask:"updated_at"` + // Username of the user who last modified the policy. Output only. + UpdatedBy *string `fieldmask:"updated_by"` + _ [0]policyInfoOptionsFieldMaskMetadata `fieldmask_oneof:"Options"` +} + +type isPolicyInfo_Options interface { + isPolicyInfo_Options() +} + +// PolicyInfo_Options_RowFilter selects RowFilter for PolicyInfo.Options. +// Options for row filter policies. Valid only if `policy_type` is +// `POLICY_TYPE_ROW_FILTER`. Required on create and optional on update. When +// specified on update, the new options will replace the existing options as a +// whole. +type PolicyInfo_Options_RowFilter struct { + RowFilter RowFilterOptions `fieldmask:"row_filter"` +} + +func (*PolicyInfo_Options_RowFilter) isPolicyInfo_Options() {} + +// PolicyInfo_Options_ColumnMask selects ColumnMask for PolicyInfo.Options. +// Options for column mask policies. Valid only if `policy_type` is +// `POLICY_TYPE_COLUMN_MASK`. Required on create and optional on update. When +// specified on update, the new options will replace the existing options as a +// whole. +type PolicyInfo_Options_ColumnMask struct { + ColumnMask ColumnMaskOptions `fieldmask:"column_mask"` +} + +func (*PolicyInfo_Options_ColumnMask) isPolicyInfo_Options() {} + +// PolicyInfo_Options_Grant selects Grant for PolicyInfo.Options. +// Options for grant policies. Valid only if `policy_type` is +// `POLICY_TYPE_GRANT`. Required on create and optional on update. When +// specified on update, the new options will replace the existing options as a +// whole. +type PolicyInfo_Options_Grant struct { + Grant GrantOptions `fieldmask:"grant"` +} + +func (*PolicyInfo_Options_Grant) isPolicyInfo_Options() {} + +type policyInfoOptionsFieldMaskMetadata struct { + *PolicyInfo_Options_RowFilter + *PolicyInfo_Options_ColumnMask + *PolicyInfo_Options_Grant +} + +type RowFilterOptions struct { + // The fully qualified name of the row filter function. The function is called + // on each row of the target table. It should return a boolean value indicating + // whether the row should be visible to the user. Required on create and update. + FunctionName *string `fieldmask:"function_name"` + // Optional list of column aliases or constant literals to be passed as + // arguments to the row filter function. The type of each column should match + // the positional argument of the row filter function. + Using []FunctionArgument `fieldmask:"using"` +} + +type UpdatePolicyRequest struct { + // Required. The type of the securable to update the policy for. + OnSecurableType *string + // Required. The fully qualified name of the securable to update the policy for. + OnSecurableFullname *string + // Required. The name of the policy to update. + Name *string + // Optional fields to update. This is the request body for updating a policy. + // Use `update_mask` field to specify which fields in the request is to be + // updated. - If `update_mask` is empty or "*", all specified fields will be + // updated. - If `update_mask` is specified, only the fields specified in the + // `update_mask` will be updated. If a field is specified in `update_mask` and + // not set in the request, the field will be cleared. Users can use the update + // mask to explicitly unset optional fields such as `exception_principals` and + // `when_condition`. + PolicyInfo *PolicyInfo + // Optional. The update mask field for specifying user intentions on which + // fields to update in the request. + UpdateMask *types.FieldMask[PolicyInfo] +} diff --git a/uc/abacpolicies/v1/wire.go b/uc/abacpolicies/v1/wire.go new file mode 100755 index 0000000..c74f3a0 --- /dev/null +++ b/uc/abacpolicies/v1/wire.go @@ -0,0 +1,431 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package abacpolicies + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type columnMaskOptionsWire struct { + FunctionName *string `json:"function_name,omitempty"` + OnColumn *string `json:"on_column,omitempty"` + Using []functionArgumentWire `json:"using,omitempty"` +} + +func columnMaskOptionsToWire(v *ColumnMaskOptions) (*columnMaskOptionsWire, error) { + if v == nil { + return nil, nil + } + usingWireValue, err := convertSlice(v.Using, functionArgumentToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnMaskOptions.Using", err) + } + return &columnMaskOptionsWire{ + FunctionName: v.FunctionName, + OnColumn: v.OnColumn, + Using: usingWireValue, + }, nil +} + +func columnMaskOptionsFromWire(w *columnMaskOptionsWire) (*ColumnMaskOptions, error) { + if w == nil { + return nil, nil + } + usingPublicValue, err := convertSlice(w.Using, functionArgumentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnMaskOptions.Using", err) + } + return &ColumnMaskOptions{ + FunctionName: w.FunctionName, + OnColumn: w.OnColumn, + Using: usingPublicValue, + }, nil +} + +type createPolicyRequestWire struct { + PolicyInfo *policyInfoWire `json:"policy_info,omitempty"` +} + +func createPolicyRequestToWire(v *CreatePolicyRequest) (*createPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + policyInfoWireValue, err := policyInfoToWire(v.PolicyInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreatePolicyRequest.PolicyInfo", err) + } + return &createPolicyRequestWire{ + PolicyInfo: policyInfoWireValue, + }, nil +} + +type functionArgumentWire struct { + Alias *string `json:"alias,omitempty"` + Constant *string `json:"constant,omitempty"` +} + +func functionArgumentToWire(v *FunctionArgument) (*functionArgumentWire, error) { + if v == nil { + return nil, nil + } + var argAliasWire *string + var argConstantWire *string + switch value := v.Arg.(type) { + case nil: + case *FunctionArgument_Arg_Alias: + if value != nil { + argAliasWire = new(value.Alias) + } + case *FunctionArgument_Arg_Constant: + if value != nil { + argConstantWire = new(value.Constant) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "FunctionArgument.Arg", value) + } + return &functionArgumentWire{ + Alias: argAliasWire, + Constant: argConstantWire, + }, nil +} + +func functionArgumentFromWire(w *functionArgumentWire) (*FunctionArgument, error) { + if w == nil { + return nil, nil + } + argMembers := 0 + if w.Alias != nil { + argMembers++ + } + if w.Constant != nil { + argMembers++ + } + if argMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "FunctionArgument.Arg") + } + var argSelection isFunctionArgument_Arg + switch { + case w.Alias != nil: + argSelection = &FunctionArgument_Arg_Alias{Alias: *w.Alias} + case w.Constant != nil: + argSelection = &FunctionArgument_Arg_Constant{Constant: *w.Constant} + } + return &FunctionArgument{ + Arg: argSelection, + }, nil +} + +type grantOptionsWire struct { + Privileges []string `json:"privileges,omitempty"` +} + +func grantOptionsToWire(v *GrantOptions) (*grantOptionsWire, error) { + if v == nil { + return nil, nil + } + return &grantOptionsWire{ + Privileges: v.Privileges, + }, nil +} + +func grantOptionsFromWire(w *grantOptionsWire) (*GrantOptions, error) { + if w == nil { + return nil, nil + } + return &GrantOptions{ + Privileges: w.Privileges, + }, nil +} + +type listPoliciesRequestWire struct { + OnSecurableType *string `json:"on_securable_type,omitempty"` + OnSecurableFullname *string `json:"on_securable_fullname,omitempty"` + IncludeInherited *bool `json:"include_inherited,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listPoliciesRequestToWire(v *ListPoliciesRequest) (*listPoliciesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listPoliciesRequestWire{ + OnSecurableType: v.OnSecurableType, + OnSecurableFullname: v.OnSecurableFullname, + IncludeInherited: v.IncludeInherited, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listPoliciesResponseWire struct { + Policies []policyInfoWire `json:"policies,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listPoliciesResponseFromWire(w *listPoliciesResponseWire) (*ListPoliciesResponse, error) { + if w == nil { + return nil, nil + } + policiesPublicValue, err := convertSlice(w.Policies, policyInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPoliciesResponse.Policies", err) + } + return &ListPoliciesResponse{ + Policies: policiesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type matchColumnWire struct { + Condition *string `json:"condition,omitempty"` + Alias *string `json:"alias,omitempty"` +} + +func matchColumnToWire(v *MatchColumn) (*matchColumnWire, error) { + if v == nil { + return nil, nil + } + return &matchColumnWire{ + Condition: v.Condition, + Alias: v.Alias, + }, nil +} + +func matchColumnFromWire(w *matchColumnWire) (*MatchColumn, error) { + if w == nil { + return nil, nil + } + return &MatchColumn{ + Condition: w.Condition, + Alias: w.Alias, + }, nil +} + +type policyInfoWire struct { + Id *string `json:"id,omitempty"` + OnSecurableType SecurableType `json:"on_securable_type,omitempty"` + OnSecurableFullname *string `json:"on_securable_fullname,omitempty"` + Name *string `json:"name,omitempty"` + Comment *string `json:"comment,omitempty"` + ToPrincipals []string `json:"to_principals,omitempty"` + ExceptPrincipals []string `json:"except_principals,omitempty"` + ForSecurableType SecurableType `json:"for_securable_type,omitempty"` + WhenCondition *string `json:"when_condition,omitempty"` + PolicyType PolicyType `json:"policy_type,omitempty"` + RowFilter *rowFilterOptionsWire `json:"row_filter,omitempty"` + ColumnMask *columnMaskOptionsWire `json:"column_mask,omitempty"` + Grant *grantOptionsWire `json:"grant,omitempty"` + MatchColumns []matchColumnWire `json:"match_columns,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` +} + +func policyInfoToWire(v *PolicyInfo) (*policyInfoWire, error) { + if v == nil { + return nil, nil + } + matchColumnsWireValue, err := convertSlice(v.MatchColumns, matchColumnToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PolicyInfo.MatchColumns", err) + } + var optionsRowFilterWire *rowFilterOptionsWire + var optionsColumnMaskWire *columnMaskOptionsWire + var optionsGrantWire *grantOptionsWire + switch value := v.Options.(type) { + case nil: + case *PolicyInfo_Options_RowFilter: + if value != nil { + optionsRowFilterConverted, err := rowFilterOptionsToWire(&value.RowFilter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PolicyInfo.Options.RowFilter", err) + } + optionsRowFilterWire = optionsRowFilterConverted + } + case *PolicyInfo_Options_ColumnMask: + if value != nil { + optionsColumnMaskConverted, err := columnMaskOptionsToWire(&value.ColumnMask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PolicyInfo.Options.ColumnMask", err) + } + optionsColumnMaskWire = optionsColumnMaskConverted + } + case *PolicyInfo_Options_Grant: + if value != nil { + optionsGrantConverted, err := grantOptionsToWire(&value.Grant) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PolicyInfo.Options.Grant", err) + } + optionsGrantWire = optionsGrantConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "PolicyInfo.Options", value) + } + return &policyInfoWire{ + Id: v.Id, + OnSecurableType: v.OnSecurableType, + OnSecurableFullname: v.OnSecurableFullname, + Name: v.Name, + Comment: v.Comment, + ToPrincipals: v.ToPrincipals, + ExceptPrincipals: v.ExceptPrincipals, + ForSecurableType: v.ForSecurableType, + WhenCondition: v.WhenCondition, + PolicyType: v.PolicyType, + RowFilter: optionsRowFilterWire, + ColumnMask: optionsColumnMaskWire, + Grant: optionsGrantWire, + MatchColumns: matchColumnsWireValue, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + }, nil +} + +func policyInfoFromWire(w *policyInfoWire) (*PolicyInfo, error) { + if w == nil { + return nil, nil + } + optionsMembers := 0 + if w.RowFilter != nil { + optionsMembers++ + } + if w.ColumnMask != nil { + optionsMembers++ + } + if w.Grant != nil { + optionsMembers++ + } + if optionsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PolicyInfo.Options") + } + matchColumnsPublicValue, err := convertSlice(w.MatchColumns, matchColumnFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PolicyInfo.MatchColumns", err) + } + var optionsSelection isPolicyInfo_Options + switch { + case w.RowFilter != nil: + optionsRowFilterConverted, err := rowFilterOptionsFromWire(w.RowFilter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PolicyInfo.Options.RowFilter", err) + } + optionsSelection = &PolicyInfo_Options_RowFilter{RowFilter: *optionsRowFilterConverted} + case w.ColumnMask != nil: + optionsColumnMaskConverted, err := columnMaskOptionsFromWire(w.ColumnMask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PolicyInfo.Options.ColumnMask", err) + } + optionsSelection = &PolicyInfo_Options_ColumnMask{ColumnMask: *optionsColumnMaskConverted} + case w.Grant != nil: + optionsGrantConverted, err := grantOptionsFromWire(w.Grant) + if err != nil { + return nil, fmt.Errorf("%s: %w", "PolicyInfo.Options.Grant", err) + } + optionsSelection = &PolicyInfo_Options_Grant{Grant: *optionsGrantConverted} + } + return &PolicyInfo{ + Id: w.Id, + OnSecurableType: w.OnSecurableType, + OnSecurableFullname: w.OnSecurableFullname, + Name: w.Name, + Comment: w.Comment, + ToPrincipals: w.ToPrincipals, + ExceptPrincipals: w.ExceptPrincipals, + ForSecurableType: w.ForSecurableType, + WhenCondition: w.WhenCondition, + PolicyType: w.PolicyType, + MatchColumns: matchColumnsPublicValue, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + Options: optionsSelection, + }, nil +} + +type rowFilterOptionsWire struct { + FunctionName *string `json:"function_name,omitempty"` + Using []functionArgumentWire `json:"using,omitempty"` +} + +func rowFilterOptionsToWire(v *RowFilterOptions) (*rowFilterOptionsWire, error) { + if v == nil { + return nil, nil + } + usingWireValue, err := convertSlice(v.Using, functionArgumentToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RowFilterOptions.Using", err) + } + return &rowFilterOptionsWire{ + FunctionName: v.FunctionName, + Using: usingWireValue, + }, nil +} + +func rowFilterOptionsFromWire(w *rowFilterOptionsWire) (*RowFilterOptions, error) { + if w == nil { + return nil, nil + } + usingPublicValue, err := convertSlice(w.Using, functionArgumentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RowFilterOptions.Using", err) + } + return &RowFilterOptions{ + FunctionName: w.FunctionName, + Using: usingPublicValue, + }, nil +} + +type updatePolicyRequestWire struct { + OnSecurableType *string `json:"on_securable_type,omitempty"` + OnSecurableFullname *string `json:"on_securable_fullname,omitempty"` + Name *string `json:"name,omitempty"` + PolicyInfo *policyInfoWire `json:"policy_info,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updatePolicyRequestToWire(v *UpdatePolicyRequest) (*updatePolicyRequestWire, error) { + if v == nil { + return nil, nil + } + policyInfoWireValue, err := policyInfoToWire(v.PolicyInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdatePolicyRequest.PolicyInfo", err) + } + return &updatePolicyRequestWire{ + OnSecurableType: v.OnSecurableType, + OnSecurableFullname: v.OnSecurableFullname, + Name: v.Name, + PolicyInfo: policyInfoWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/artifactallowlists/.package.json b/uc/artifactallowlists/.package.json new file mode 100644 index 0000000..029bd2b --- /dev/null +++ b/uc/artifactallowlists/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/artifactallowlists" +} diff --git a/uc/artifactallowlists/CHANGELOG.md b/uc/artifactallowlists/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/artifactallowlists/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/artifactallowlists/README.md b/uc/artifactallowlists/README.md new file mode 100644 index 0000000..59d8a93 --- /dev/null +++ b/uc/artifactallowlists/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/artifactallowlists + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/artifactallowlists@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/artifactallowlists/v1" + +client, err := artifactallowlists.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/artifactallowlists/go.mod b/uc/artifactallowlists/go.mod new file mode 100644 index 0000000..6432337 --- /dev/null +++ b/uc/artifactallowlists/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/artifactallowlists + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/artifactallowlists/internal/version.go b/uc/artifactallowlists/internal/version.go new file mode 100644 index 0000000..a956af1 --- /dev/null +++ b/uc/artifactallowlists/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-artifactallowlists" + +const Version = "0.0.1-dev.1" diff --git a/uc/artifactallowlists/v1/client.go b/uc/artifactallowlists/v1/client.go new file mode 100755 index 0000000..e4f2357 --- /dev/null +++ b/uc/artifactallowlists/v1/client.go @@ -0,0 +1,213 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package artifactallowlists + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/artifactallowlists/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Get the artifact allowlist of a certain artifact type. The caller must be a +// metastore admin or have the **MANAGE ALLOWLIST** privilege on the metastore. +func (c *internalClient) GetArtifactAllowlist(ctx context.Context, req *GetArtifactAllowlistRequest, opts ...call.Option) (*ArtifactAllowlistInfo, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + if req.ArtifactType == "" { + return nil, fmt.Errorf("path parameter %q is required", "artifact_type") + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/artifact-allowlists/") + pb.singleSegment(req.ArtifactType) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ArtifactAllowlistInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp artifactAllowlistInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = artifactAllowlistInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Set the artifact allowlist of a certain artifact type. The whole artifact +// allowlist is replaced with the new allowlist. The caller must be a metastore +// admin or have the **MANAGE ALLOWLIST** privilege on the metastore. +func (c *internalClient) SetArtifactAllowlist(ctx context.Context, req *SetArtifactAllowlistRequest, opts ...call.Option) (*ArtifactAllowlistInfo, error) { + wireReq, err := setArtifactAllowlistRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + if req.ArtifactType == "" { + return nil, fmt.Errorf("path parameter %q is required", "artifact_type") + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/artifact-allowlists/") + pb.singleSegment(req.ArtifactType) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ArtifactAllowlistInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp artifactAllowlistInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = artifactAllowlistInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/artifactallowlists/v1/genhelper.go b/uc/artifactallowlists/v1/genhelper.go new file mode 100755 index 0000000..cc99424 --- /dev/null +++ b/uc/artifactallowlists/v1/genhelper.go @@ -0,0 +1,188 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package artifactallowlists + +import ( + "context" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/artifactallowlists/v1/model.go b/uc/artifactallowlists/v1/model.go new file mode 100755 index 0000000..0b15567 --- /dev/null +++ b/uc/artifactallowlists/v1/model.go @@ -0,0 +1,57 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package artifactallowlists + +// The artifact type +type ArtifactType string + +const ( + ArtifactType_Unspecified ArtifactType = "" + ArtifactType_InitScript ArtifactType = "INIT_SCRIPT" + ArtifactType_LibraryJar ArtifactType = "LIBRARY_JAR" + ArtifactType_LibraryMaven ArtifactType = "LIBRARY_MAVEN" +) + +// The artifact pattern matching type +type ArtifactMatcher_MatchType string + +const ( + ArtifactMatcher_MatchType_Unspecified ArtifactMatcher_MatchType = "" + ArtifactMatcher_MatchType_PrefixMatch ArtifactMatcher_MatchType = "PREFIX_MATCH" +) + +type ArtifactAllowlistInfo struct { + // A list of allowed artifact match patterns. + ArtifactMatchers []ArtifactMatcher + // Unique identifier of parent metastore. + MetastoreId *string + // Username of the user who set the artifact allowlist. + CreatedBy *string + // Time at which this artifact allowlist was set, in epoch milliseconds. + CreatedAt *int64 +} + +type ArtifactMatcher struct { + // The artifact path or maven coordinate + Artifact *string + // The pattern matching type of the artifact + MatchType ArtifactMatcher_MatchType +} + +type GetArtifactAllowlistRequest struct { + // The artifact type of the allowlist. + ArtifactType ArtifactType +} + +type SetArtifactAllowlistRequest struct { + // The artifact type of the allowlist. + ArtifactType ArtifactType + // A list of allowed artifact match patterns. + ArtifactMatchers []ArtifactMatcher + // Unique identifier of parent metastore. + MetastoreId *string + // Username of the user who set the artifact allowlist. + CreatedBy *string + // Time at which this artifact allowlist was set, in epoch milliseconds. + CreatedAt *int64 +} diff --git a/uc/artifactallowlists/v1/wire.go b/uc/artifactallowlists/v1/wire.go new file mode 100755 index 0000000..ba4232b --- /dev/null +++ b/uc/artifactallowlists/v1/wire.go @@ -0,0 +1,95 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package artifactallowlists + +import ( + "fmt" +) + +type artifactAllowlistInfoWire struct { + ArtifactMatchers []artifactMatcherWire `json:"artifact_matchers,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` +} + +func artifactAllowlistInfoFromWire(w *artifactAllowlistInfoWire) (*ArtifactAllowlistInfo, error) { + if w == nil { + return nil, nil + } + artifactMatchersPublicValue, err := convertSlice(w.ArtifactMatchers, artifactMatcherFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ArtifactAllowlistInfo.ArtifactMatchers", err) + } + return &ArtifactAllowlistInfo{ + ArtifactMatchers: artifactMatchersPublicValue, + MetastoreId: w.MetastoreId, + CreatedBy: w.CreatedBy, + CreatedAt: w.CreatedAt, + }, nil +} + +type artifactMatcherWire struct { + Artifact *string `json:"artifact,omitempty"` + MatchType ArtifactMatcher_MatchType `json:"match_type,omitempty"` +} + +func artifactMatcherToWire(v *ArtifactMatcher) (*artifactMatcherWire, error) { + if v == nil { + return nil, nil + } + return &artifactMatcherWire{ + Artifact: v.Artifact, + MatchType: v.MatchType, + }, nil +} + +func artifactMatcherFromWire(w *artifactMatcherWire) (*ArtifactMatcher, error) { + if w == nil { + return nil, nil + } + return &ArtifactMatcher{ + Artifact: w.Artifact, + MatchType: w.MatchType, + }, nil +} + +type setArtifactAllowlistRequestWire struct { + ArtifactType ArtifactType `json:"artifact_type,omitempty"` + ArtifactMatchers []artifactMatcherWire `json:"artifact_matchers,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` +} + +func setArtifactAllowlistRequestToWire(v *SetArtifactAllowlistRequest) (*setArtifactAllowlistRequestWire, error) { + if v == nil { + return nil, nil + } + artifactMatchersWireValue, err := convertSlice(v.ArtifactMatchers, artifactMatcherToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SetArtifactAllowlistRequest.ArtifactMatchers", err) + } + return &setArtifactAllowlistRequestWire{ + ArtifactType: v.ArtifactType, + ArtifactMatchers: artifactMatchersWireValue, + MetastoreId: v.MetastoreId, + CreatedBy: v.CreatedBy, + CreatedAt: v.CreatedAt, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/catalogs/.package.json b/uc/catalogs/.package.json new file mode 100644 index 0000000..5cc2bf2 --- /dev/null +++ b/uc/catalogs/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/catalogs" +} diff --git a/uc/catalogs/CHANGELOG.md b/uc/catalogs/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/catalogs/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/catalogs/README.md b/uc/catalogs/README.md new file mode 100644 index 0000000..e99fc69 --- /dev/null +++ b/uc/catalogs/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/catalogs + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/catalogs@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/catalogs/v1" + +client, err := catalogs.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/catalogs/go.mod b/uc/catalogs/go.mod new file mode 100644 index 0000000..42b45eb --- /dev/null +++ b/uc/catalogs/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/catalogs + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/catalogs/internal/version.go b/uc/catalogs/internal/version.go new file mode 100644 index 0000000..b21693a --- /dev/null +++ b/uc/catalogs/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-catalogs" + +const Version = "0.0.1-dev.1" diff --git a/uc/catalogs/v1/client.go b/uc/catalogs/v1/client.go new file mode 100755 index 0000000..9bbb1dc --- /dev/null +++ b/uc/catalogs/v1/client.go @@ -0,0 +1,473 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package catalogs + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/catalogs/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new catalog instance in the parent metastore if the caller is a +// metastore admin or has the **CREATE_CATALOG** privilege. +func (c *internalClient) CreateCatalog(ctx context.Context, req *CreateCatalogRequest, opts ...call.Option) (*CatalogInfo, error) { + wireReq, err := createCatalogRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/catalogs" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CatalogInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp catalogInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = catalogInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the catalog that matches the supplied name. The caller must be a +// metastore admin or the owner of the catalog. +func (c *internalClient) DeleteCatalog(ctx context.Context, req *DeleteCatalogRequest, opts ...call.Option) (*DeleteCatalogResponse, error) { + wireReq, err := deleteCatalogRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/catalogs/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteCatalogResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteCatalogResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the specified catalog in a metastore. The caller must be a metastore +// admin, the owner of the catalog, or a user that has the **USE_CATALOG** +// privilege set for their account. +func (c *internalClient) GetCatalog(ctx context.Context, req *GetCatalogRequest, opts ...call.Option) (*CatalogInfo, error) { + wireReq, err := getCatalogRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/catalogs/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CatalogInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp catalogInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = catalogInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of catalogs in the metastore. If the caller is the metastore +// admin, all catalogs will be retrieved. Otherwise, only catalogs owned by the +// caller (or for which the caller has the **USE_CATALOG** privilege) will be +// retrieved. There is no guarantee of a specific ordering of the elements in +// the array. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) ListCatalogs(ctx context.Context, req *ListCatalogsRequest, opts ...call.Option) (*ListCatalogsResponse, error) { + wireReq, err := listCatalogsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/catalogs" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_unbound", wireReq.IncludeUnbound); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCatalogsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCatalogsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCatalogsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCatalogsIter returns an iterator that iterates +// over the results of ListCatalogs. +// +// For example: +// +// for item, err := range c.ListCatalogsIter(ctx, &ListCatalogsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCatalogs call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCatalogs directly. +func (c *internalClient) ListCatalogsIter(ctx context.Context, req *ListCatalogsRequest, opts ...call.Option) iter.Seq2[*CatalogInfo, error] { + return func(yield func(*CatalogInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCatalogsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCatalogs(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Catalogs { + if !yield(&resp.Catalogs[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates the catalog that matches the supplied name. The caller must be either +// the owner of the catalog, or a metastore admin (when changing the owner field +// of the catalog). +func (c *internalClient) UpdateCatalog(ctx context.Context, req *UpdateCatalogRequest, opts ...call.Option) (*CatalogInfo, error) { + wireReq, err := updateCatalogRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/catalogs/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CatalogInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp catalogInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = catalogInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/catalogs/v1/genhelper.go b/uc/catalogs/v1/genhelper.go new file mode 100755 index 0000000..86023d5 --- /dev/null +++ b/uc/catalogs/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package catalogs + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/catalogs/v1/model.go b/uc/catalogs/v1/model.go new file mode 100755 index 0000000..45bd8d0 --- /dev/null +++ b/uc/catalogs/v1/model.go @@ -0,0 +1,317 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package catalogs + +type CatalogIsolationMode string + +const ( + CatalogIsolationMode_Unspecified CatalogIsolationMode = "" + CatalogIsolationMode_Open CatalogIsolationMode = "OPEN" + CatalogIsolationMode_Isolated CatalogIsolationMode = "ISOLATED" +) + +// The type of the catalog. +type CatalogType string + +const ( + CatalogType_Unspecified CatalogType = "" + CatalogType_ManagedCatalog CatalogType = "MANAGED_CATALOG" + CatalogType_DeltasharingCatalog CatalogType = "DELTASHARING_CATALOG" + CatalogType_SystemCatalog CatalogType = "SYSTEM_CATALOG" + CatalogType_InternalCatalog CatalogType = "INTERNAL_CATALOG" + CatalogType_ForeignCatalog CatalogType = "FOREIGN_CATALOG" + CatalogType_ManagedOnlineCatalog CatalogType = "MANAGED_ONLINE_CATALOG" +) + +// The type of Unity Catalog securable. +type SecurableType string + +const ( + SecurableType_Unspecified SecurableType = "" + SecurableType_Catalog SecurableType = "CATALOG" + SecurableType_Schema SecurableType = "SCHEMA" + SecurableType_Table SecurableType = "TABLE" + SecurableType_StorageCredential SecurableType = "STORAGE_CREDENTIAL" + SecurableType_ExternalLocation SecurableType = "EXTERNAL_LOCATION" + SecurableType_Function SecurableType = "FUNCTION" + SecurableType_Share SecurableType = "SHARE" + SecurableType_Provider SecurableType = "PROVIDER" + SecurableType_Recipient SecurableType = "RECIPIENT" + SecurableType_CleanRoom SecurableType = "CLEAN_ROOM" + SecurableType_Metastore SecurableType = "METASTORE" + SecurableType_Pipeline SecurableType = "PIPELINE" + SecurableType_Volume SecurableType = "VOLUME" + SecurableType_Connection SecurableType = "CONNECTION" + SecurableType_Credential SecurableType = "CREDENTIAL" + SecurableType_ExternalMetadata SecurableType = "EXTERNAL_METADATA" + // TODO: [UC-2980] Staging tables aren't full-fleged securables yet. + SecurableType_StagingTable SecurableType = "STAGING_TABLE" +) + +type ProvisioningInfo_State string + +const ( + ProvisioningInfo_State_Unspecified ProvisioningInfo_State = "" + ProvisioningInfo_State_Provisioning ProvisioningInfo_State = "PROVISIONING" + ProvisioningInfo_State_Active ProvisioningInfo_State = "ACTIVE" + ProvisioningInfo_State_Failed ProvisioningInfo_State = "FAILED" + ProvisioningInfo_State_Deleting ProvisioningInfo_State = "DELETING" + ProvisioningInfo_State_Updating ProvisioningInfo_State = "UPDATING" + ProvisioningInfo_State_Degraded ProvisioningInfo_State = "DEGRADED" +) + +type AzureEncryptionSettings struct { + AzureTenantId *string + AzureCmkAccessConnectorId *string + AzureCmkManagedIdentityId *string +} + +type CatalogInfo struct { + // Name of catalog. + Name *string + // Username of current owner of catalog. + Owner *string + // User-provided free-form text description. + Comment *string + // Storage root URL for managed tables within catalog. + StorageRoot *string + // Whether predictive optimization should be enabled for this object and objects + // under it. + EnablePredictiveOptimization *string + CatalogType CatalogType + // The name of delta sharing provider. + // + // A Delta Sharing catalog is a catalog that is based on a Delta share on a + // remote sharing server. + ProviderName *string + // The name of the share under the share provider. + ShareName *string + // The name of the connection to an external data source. + ConnectionName *string + // Unique identifier of parent metastore. + MetastoreId *string + // Time at which this catalog was created, in epoch milliseconds. + CreatedAt *int64 + // Username of catalog creator. + CreatedBy *string + // Time at which this catalog was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified catalog. + UpdatedBy *string + // Storage Location URL (full path) for managed tables within catalog. + StorageLocation *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode CatalogIsolationMode + EffectivePredictiveOptimizationFlag *EffectivePredictiveOptimizationFlag + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + ProvisioningInfo *ProvisioningInfo + // The full name of the catalog. Corresponds with the name field. + FullName *string + SecurableType SecurableType + // Custom maximum retention period in hours for the catalog + CustomMaxRetentionHours *int64 + // Control CMK encryption for managed catalog data + ManagedEncryptionSettings *EncryptionSettings + // A map of key-value properties attached to the securable. + Properties map[string]string + // A map of key-value properties attached to the securable. + Options map[string]string +} + +type CreateCatalogRequest struct { + // Name of catalog. + Name *string + // Username of current owner of catalog. + Owner *string + // User-provided free-form text description. + Comment *string + // Storage root URL for managed tables within catalog. + StorageRoot *string + // Whether predictive optimization should be enabled for this object and objects + // under it. + EnablePredictiveOptimization *string + CatalogType CatalogType + // The name of delta sharing provider. + // + // A Delta Sharing catalog is a catalog that is based on a Delta share on a + // remote sharing server. + ProviderName *string + // The name of the share under the share provider. + ShareName *string + // The name of the connection to an external data source. + ConnectionName *string + // Unique identifier of parent metastore. + MetastoreId *string + // Time at which this catalog was created, in epoch milliseconds. + CreatedAt *int64 + // Username of catalog creator. + CreatedBy *string + // Time at which this catalog was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified catalog. + UpdatedBy *string + // Storage Location URL (full path) for managed tables within catalog. + StorageLocation *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode CatalogIsolationMode + EffectivePredictiveOptimizationFlag *EffectivePredictiveOptimizationFlag + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + ProvisioningInfo *ProvisioningInfo + // The full name of the catalog. Corresponds with the name field. + FullName *string + SecurableType SecurableType + // Custom maximum retention period in hours for the catalog + CustomMaxRetentionHours *int64 + // Control CMK encryption for managed catalog data + ManagedEncryptionSettings *EncryptionSettings + // A map of key-value properties attached to the securable. + Properties map[string]string + // A map of key-value properties attached to the securable. + Options map[string]string +} + +type DeleteCatalogRequest struct { + // The name of the catalog. + NameArg *string + // Force deletion even if the catalog is not empty. + Force *bool +} + +type DeleteCatalogResponse struct { +} + +type EffectivePredictiveOptimizationFlag struct { + // Whether predictive optimization should be enabled for this object and objects + // under it. + Value *string + // The type of the object from which the flag was inherited. If there was no + // inheritance, this field is left blank. + InheritedFromType *string + // The name of the object from which the flag was inherited. If there was no + // inheritance, this field is left blank. + InheritedFromName *string +} + +// Encryption Settings are used to carry metadata for securable encryption at +// rest. Currently used for catalogs, we can use the information supplied here +// to interact with a CMK.. +type EncryptionSettings struct { + // the CMK uuid in AWS and GCP, null otherwise. + CustomerManagedKeyId *string + // the AKV URL in Azure, null otherwise. + AzureKeyVaultKeyId *string + // optional Azure settings - only required if an Azure CMK is used. + AzureEncryptionSettings *AzureEncryptionSettings +} + +type GetCatalogRequest struct { + // The name of the catalog. + NameArg *string + // Whether to include catalogs in the response for which the principal can only + // access selective metadata for + IncludeBrowse *bool +} + +type ListCatalogsRequest struct { + // Whether to include catalogs in the response for which the principal can only + // access selective metadata for + IncludeBrowse *bool + // Maximum number of catalogs to return. - when set to 0, the page length is set + // to a server configured value (recommended); - when set to a value greater + // than 0, the page length is the minimum of this value and a server configured + // value; - when set to a value less than 0, an invalid parameter error is + // returned; - If not set, all valid catalogs are returned (not recommended). - + // Note: The number of returned catalogs might be less than the specified + // max_results size, even zero. The only definitive indication that no further + // catalogs can be fetched is when the next_page_token is unset from the + // response. + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string + // Whether to include catalogs not bound to the workspace. Effective only if the + // user has permission to update the catalog–workspace binding. + IncludeUnbound *bool +} + +type ListCatalogsResponse struct { + // An array of catalog information objects. + Catalogs []CatalogInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +// Status of an asynchronously provisioned resource.. +type ProvisioningInfo struct { + // The provisioning state of the resource. + State ProvisioningInfo_State +} + +type UpdateCatalogRequest struct { + // The name of the catalog. + NameArg *string + // New name for the catalog. + NewName *string + // Name of catalog. + Name *string + // Username of current owner of catalog. + Owner *string + // User-provided free-form text description. + Comment *string + // Storage root URL for managed tables within catalog. + StorageRoot *string + // Whether predictive optimization should be enabled for this object and objects + // under it. + EnablePredictiveOptimization *string + CatalogType CatalogType + // The name of delta sharing provider. + // + // A Delta Sharing catalog is a catalog that is based on a Delta share on a + // remote sharing server. + ProviderName *string + // The name of the share under the share provider. + ShareName *string + // The name of the connection to an external data source. + ConnectionName *string + // Unique identifier of parent metastore. + MetastoreId *string + // Time at which this catalog was created, in epoch milliseconds. + CreatedAt *int64 + // Username of catalog creator. + CreatedBy *string + // Time at which this catalog was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified catalog. + UpdatedBy *string + // Storage Location URL (full path) for managed tables within catalog. + StorageLocation *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode CatalogIsolationMode + EffectivePredictiveOptimizationFlag *EffectivePredictiveOptimizationFlag + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + ProvisioningInfo *ProvisioningInfo + // The full name of the catalog. Corresponds with the name field. + FullName *string + SecurableType SecurableType + // Custom maximum retention period in hours for the catalog + CustomMaxRetentionHours *int64 + // Control CMK encryption for managed catalog data + ManagedEncryptionSettings *EncryptionSettings + // A map of key-value properties attached to the securable. + Properties map[string]string + // A map of key-value properties attached to the securable. + Options map[string]string +} diff --git a/uc/catalogs/v1/wire.go b/uc/catalogs/v1/wire.go new file mode 100755 index 0000000..1619bed --- /dev/null +++ b/uc/catalogs/v1/wire.go @@ -0,0 +1,427 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package catalogs + +import ( + "fmt" +) + +type azureEncryptionSettingsWire struct { + AzureTenantId *string `json:"azure_tenant_id,omitempty"` + AzureCmkAccessConnectorId *string `json:"azure_cmk_access_connector_id,omitempty"` + AzureCmkManagedIdentityId *string `json:"azure_cmk_managed_identity_id,omitempty"` +} + +func azureEncryptionSettingsToWire(v *AzureEncryptionSettings) (*azureEncryptionSettingsWire, error) { + if v == nil { + return nil, nil + } + return &azureEncryptionSettingsWire{ + AzureTenantId: v.AzureTenantId, + AzureCmkAccessConnectorId: v.AzureCmkAccessConnectorId, + AzureCmkManagedIdentityId: v.AzureCmkManagedIdentityId, + }, nil +} + +func azureEncryptionSettingsFromWire(w *azureEncryptionSettingsWire) (*AzureEncryptionSettings, error) { + if w == nil { + return nil, nil + } + return &AzureEncryptionSettings{ + AzureTenantId: w.AzureTenantId, + AzureCmkAccessConnectorId: w.AzureCmkAccessConnectorId, + AzureCmkManagedIdentityId: w.AzureCmkManagedIdentityId, + }, nil +} + +type catalogInfoWire struct { + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + EnablePredictiveOptimization *string `json:"enable_predictive_optimization,omitempty"` + CatalogType CatalogType `json:"catalog_type,omitempty"` + ProviderName *string `json:"provider_name,omitempty"` + ShareName *string `json:"share_name,omitempty"` + ConnectionName *string `json:"connection_name,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + IsolationMode CatalogIsolationMode `json:"isolation_mode,omitempty"` + EffectivePredictiveOptimizationFlag *effectivePredictiveOptimizationFlagWire `json:"effective_predictive_optimization_flag,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + ProvisioningInfo *provisioningInfoWire `json:"provisioning_info,omitempty"` + FullName *string `json:"full_name,omitempty"` + SecurableType SecurableType `json:"securable_type,omitempty"` + CustomMaxRetentionHours *int64 `json:"custom_max_retention_hours,omitempty"` + ManagedEncryptionSettings *encryptionSettingsWire `json:"managed_encryption_settings,omitempty"` + Properties map[string]string `json:"properties,omitempty"` + Options map[string]string `json:"options,omitempty"` +} + +func catalogInfoFromWire(w *catalogInfoWire) (*CatalogInfo, error) { + if w == nil { + return nil, nil + } + effectivePredictiveOptimizationFlagPublicValue, err := effectivePredictiveOptimizationFlagFromWire(w.EffectivePredictiveOptimizationFlag) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CatalogInfo.EffectivePredictiveOptimizationFlag", err) + } + provisioningInfoPublicValue, err := provisioningInfoFromWire(w.ProvisioningInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CatalogInfo.ProvisioningInfo", err) + } + managedEncryptionSettingsPublicValue, err := encryptionSettingsFromWire(w.ManagedEncryptionSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CatalogInfo.ManagedEncryptionSettings", err) + } + return &CatalogInfo{ + Name: w.Name, + Owner: w.Owner, + Comment: w.Comment, + StorageRoot: w.StorageRoot, + EnablePredictiveOptimization: w.EnablePredictiveOptimization, + CatalogType: w.CatalogType, + ProviderName: w.ProviderName, + ShareName: w.ShareName, + ConnectionName: w.ConnectionName, + MetastoreId: w.MetastoreId, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + StorageLocation: w.StorageLocation, + IsolationMode: w.IsolationMode, + EffectivePredictiveOptimizationFlag: effectivePredictiveOptimizationFlagPublicValue, + BrowseOnly: w.BrowseOnly, + ProvisioningInfo: provisioningInfoPublicValue, + FullName: w.FullName, + SecurableType: w.SecurableType, + CustomMaxRetentionHours: w.CustomMaxRetentionHours, + ManagedEncryptionSettings: managedEncryptionSettingsPublicValue, + Properties: w.Properties, + Options: w.Options, + }, nil +} + +type createCatalogRequestWire struct { + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + EnablePredictiveOptimization *string `json:"enable_predictive_optimization,omitempty"` + CatalogType CatalogType `json:"catalog_type,omitempty"` + ProviderName *string `json:"provider_name,omitempty"` + ShareName *string `json:"share_name,omitempty"` + ConnectionName *string `json:"connection_name,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + IsolationMode CatalogIsolationMode `json:"isolation_mode,omitempty"` + EffectivePredictiveOptimizationFlag *effectivePredictiveOptimizationFlagWire `json:"effective_predictive_optimization_flag,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + ProvisioningInfo *provisioningInfoWire `json:"provisioning_info,omitempty"` + FullName *string `json:"full_name,omitempty"` + SecurableType SecurableType `json:"securable_type,omitempty"` + CustomMaxRetentionHours *int64 `json:"custom_max_retention_hours,omitempty"` + ManagedEncryptionSettings *encryptionSettingsWire `json:"managed_encryption_settings,omitempty"` + Properties map[string]string `json:"properties,omitempty"` + Options map[string]string `json:"options,omitempty"` +} + +func createCatalogRequestToWire(v *CreateCatalogRequest) (*createCatalogRequestWire, error) { + if v == nil { + return nil, nil + } + effectivePredictiveOptimizationFlagWireValue, err := effectivePredictiveOptimizationFlagToWire(v.EffectivePredictiveOptimizationFlag) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCatalogRequest.EffectivePredictiveOptimizationFlag", err) + } + provisioningInfoWireValue, err := provisioningInfoToWire(v.ProvisioningInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCatalogRequest.ProvisioningInfo", err) + } + managedEncryptionSettingsWireValue, err := encryptionSettingsToWire(v.ManagedEncryptionSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCatalogRequest.ManagedEncryptionSettings", err) + } + return &createCatalogRequestWire{ + Name: v.Name, + Owner: v.Owner, + Comment: v.Comment, + StorageRoot: v.StorageRoot, + EnablePredictiveOptimization: v.EnablePredictiveOptimization, + CatalogType: v.CatalogType, + ProviderName: v.ProviderName, + ShareName: v.ShareName, + ConnectionName: v.ConnectionName, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + StorageLocation: v.StorageLocation, + IsolationMode: v.IsolationMode, + EffectivePredictiveOptimizationFlag: effectivePredictiveOptimizationFlagWireValue, + BrowseOnly: v.BrowseOnly, + ProvisioningInfo: provisioningInfoWireValue, + FullName: v.FullName, + SecurableType: v.SecurableType, + CustomMaxRetentionHours: v.CustomMaxRetentionHours, + ManagedEncryptionSettings: managedEncryptionSettingsWireValue, + Properties: v.Properties, + Options: v.Options, + }, nil +} + +type deleteCatalogRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + Force *bool `json:"force,omitempty"` +} + +func deleteCatalogRequestToWire(v *DeleteCatalogRequest) (*deleteCatalogRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteCatalogRequestWire{ + NameArg: v.NameArg, + Force: v.Force, + }, nil +} + +type effectivePredictiveOptimizationFlagWire struct { + Value *string `json:"value,omitempty"` + InheritedFromType *string `json:"inherited_from_type,omitempty"` + InheritedFromName *string `json:"inherited_from_name,omitempty"` +} + +func effectivePredictiveOptimizationFlagToWire(v *EffectivePredictiveOptimizationFlag) (*effectivePredictiveOptimizationFlagWire, error) { + if v == nil { + return nil, nil + } + return &effectivePredictiveOptimizationFlagWire{ + Value: v.Value, + InheritedFromType: v.InheritedFromType, + InheritedFromName: v.InheritedFromName, + }, nil +} + +func effectivePredictiveOptimizationFlagFromWire(w *effectivePredictiveOptimizationFlagWire) (*EffectivePredictiveOptimizationFlag, error) { + if w == nil { + return nil, nil + } + return &EffectivePredictiveOptimizationFlag{ + Value: w.Value, + InheritedFromType: w.InheritedFromType, + InheritedFromName: w.InheritedFromName, + }, nil +} + +type encryptionSettingsWire struct { + CustomerManagedKeyId *string `json:"customer_managed_key_id,omitempty"` + AzureKeyVaultKeyId *string `json:"azure_key_vault_key_id,omitempty"` + AzureEncryptionSettings *azureEncryptionSettingsWire `json:"azure_encryption_settings,omitempty"` +} + +func encryptionSettingsToWire(v *EncryptionSettings) (*encryptionSettingsWire, error) { + if v == nil { + return nil, nil + } + azureEncryptionSettingsWireValue, err := azureEncryptionSettingsToWire(v.AzureEncryptionSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EncryptionSettings.AzureEncryptionSettings", err) + } + return &encryptionSettingsWire{ + CustomerManagedKeyId: v.CustomerManagedKeyId, + AzureKeyVaultKeyId: v.AzureKeyVaultKeyId, + AzureEncryptionSettings: azureEncryptionSettingsWireValue, + }, nil +} + +func encryptionSettingsFromWire(w *encryptionSettingsWire) (*EncryptionSettings, error) { + if w == nil { + return nil, nil + } + azureEncryptionSettingsPublicValue, err := azureEncryptionSettingsFromWire(w.AzureEncryptionSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EncryptionSettings.AzureEncryptionSettings", err) + } + return &EncryptionSettings{ + CustomerManagedKeyId: w.CustomerManagedKeyId, + AzureKeyVaultKeyId: w.AzureKeyVaultKeyId, + AzureEncryptionSettings: azureEncryptionSettingsPublicValue, + }, nil +} + +type getCatalogRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` +} + +func getCatalogRequestToWire(v *GetCatalogRequest) (*getCatalogRequestWire, error) { + if v == nil { + return nil, nil + } + return &getCatalogRequestWire{ + NameArg: v.NameArg, + IncludeBrowse: v.IncludeBrowse, + }, nil +} + +type listCatalogsRequestWire struct { + IncludeBrowse *bool `json:"include_browse,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` + IncludeUnbound *bool `json:"include_unbound,omitempty"` +} + +func listCatalogsRequestToWire(v *ListCatalogsRequest) (*listCatalogsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCatalogsRequestWire{ + IncludeBrowse: v.IncludeBrowse, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + IncludeUnbound: v.IncludeUnbound, + }, nil +} + +type listCatalogsResponseWire struct { + Catalogs []catalogInfoWire `json:"catalogs,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCatalogsResponseFromWire(w *listCatalogsResponseWire) (*ListCatalogsResponse, error) { + if w == nil { + return nil, nil + } + catalogsPublicValue, err := convertSlice(w.Catalogs, catalogInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCatalogsResponse.Catalogs", err) + } + return &ListCatalogsResponse{ + Catalogs: catalogsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type provisioningInfoWire struct { + State ProvisioningInfo_State `json:"state,omitempty"` +} + +func provisioningInfoToWire(v *ProvisioningInfo) (*provisioningInfoWire, error) { + if v == nil { + return nil, nil + } + return &provisioningInfoWire{ + State: v.State, + }, nil +} + +func provisioningInfoFromWire(w *provisioningInfoWire) (*ProvisioningInfo, error) { + if w == nil { + return nil, nil + } + return &ProvisioningInfo{ + State: w.State, + }, nil +} + +type updateCatalogRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + EnablePredictiveOptimization *string `json:"enable_predictive_optimization,omitempty"` + CatalogType CatalogType `json:"catalog_type,omitempty"` + ProviderName *string `json:"provider_name,omitempty"` + ShareName *string `json:"share_name,omitempty"` + ConnectionName *string `json:"connection_name,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + IsolationMode CatalogIsolationMode `json:"isolation_mode,omitempty"` + EffectivePredictiveOptimizationFlag *effectivePredictiveOptimizationFlagWire `json:"effective_predictive_optimization_flag,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + ProvisioningInfo *provisioningInfoWire `json:"provisioning_info,omitempty"` + FullName *string `json:"full_name,omitempty"` + SecurableType SecurableType `json:"securable_type,omitempty"` + CustomMaxRetentionHours *int64 `json:"custom_max_retention_hours,omitempty"` + ManagedEncryptionSettings *encryptionSettingsWire `json:"managed_encryption_settings,omitempty"` + Properties map[string]string `json:"properties,omitempty"` + Options map[string]string `json:"options,omitempty"` +} + +func updateCatalogRequestToWire(v *UpdateCatalogRequest) (*updateCatalogRequestWire, error) { + if v == nil { + return nil, nil + } + effectivePredictiveOptimizationFlagWireValue, err := effectivePredictiveOptimizationFlagToWire(v.EffectivePredictiveOptimizationFlag) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCatalogRequest.EffectivePredictiveOptimizationFlag", err) + } + provisioningInfoWireValue, err := provisioningInfoToWire(v.ProvisioningInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCatalogRequest.ProvisioningInfo", err) + } + managedEncryptionSettingsWireValue, err := encryptionSettingsToWire(v.ManagedEncryptionSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCatalogRequest.ManagedEncryptionSettings", err) + } + return &updateCatalogRequestWire{ + NameArg: v.NameArg, + NewName: v.NewName, + Name: v.Name, + Owner: v.Owner, + Comment: v.Comment, + StorageRoot: v.StorageRoot, + EnablePredictiveOptimization: v.EnablePredictiveOptimization, + CatalogType: v.CatalogType, + ProviderName: v.ProviderName, + ShareName: v.ShareName, + ConnectionName: v.ConnectionName, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + StorageLocation: v.StorageLocation, + IsolationMode: v.IsolationMode, + EffectivePredictiveOptimizationFlag: effectivePredictiveOptimizationFlagWireValue, + BrowseOnly: v.BrowseOnly, + ProvisioningInfo: provisioningInfoWireValue, + FullName: v.FullName, + SecurableType: v.SecurableType, + CustomMaxRetentionHours: v.CustomMaxRetentionHours, + ManagedEncryptionSettings: managedEncryptionSettingsWireValue, + Properties: v.Properties, + Options: v.Options, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/connections/.package.json b/uc/connections/.package.json new file mode 100644 index 0000000..5696b44 --- /dev/null +++ b/uc/connections/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/connections" +} diff --git a/uc/connections/CHANGELOG.md b/uc/connections/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/connections/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/connections/README.md b/uc/connections/README.md new file mode 100644 index 0000000..811636c --- /dev/null +++ b/uc/connections/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/connections + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/connections@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/connections/v1" + +client, err := connections.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/connections/go.mod b/uc/connections/go.mod new file mode 100644 index 0000000..4ccb489 --- /dev/null +++ b/uc/connections/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/connections + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/connections/internal/version.go b/uc/connections/internal/version.go new file mode 100644 index 0000000..69a3a38 --- /dev/null +++ b/uc/connections/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-connections" + +const Version = "0.0.1-dev.1" diff --git a/uc/connections/v1/client.go b/uc/connections/v1/client.go new file mode 100755 index 0000000..6476a51 --- /dev/null +++ b/uc/connections/v1/client.go @@ -0,0 +1,450 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package connections + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/connections/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new connection +// +// Creates a new connection to an external data source. It allows users to +// specify connection details and configurations for interaction with the +// external server. +func (c *internalClient) CreateConnection(ctx context.Context, req *CreateConnectionRequest, opts ...call.Option) (*ConnectionInfo, error) { + wireReq, err := createConnectionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/connections" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ConnectionInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp connectionInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = connectionInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the connection that matches the supplied name. +func (c *internalClient) DeleteConnection(ctx context.Context, req *DeleteConnectionRequest, opts ...call.Option) (*DeleteConnectionResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/connections/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteConnectionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteConnectionResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a connection from it's name. +func (c *internalClient) GetConnection(ctx context.Context, req *GetConnectionRequest, opts ...call.Option) (*ConnectionInfo, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/connections/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ConnectionInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp connectionInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = connectionInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List all connections. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) ListConnections(ctx context.Context, req *ListConnectionsRequest, opts ...call.Option) (*ListConnectionsResponse, error) { + wireReq, err := listConnectionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/connections" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "parent", wireReq.Parent); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListConnectionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listConnectionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listConnectionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListConnectionsIter returns an iterator that iterates +// over the results of ListConnections. +// +// For example: +// +// for item, err := range c.ListConnectionsIter(ctx, &ListConnectionsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListConnections call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListConnections directly. +func (c *internalClient) ListConnectionsIter(ctx context.Context, req *ListConnectionsRequest, opts ...call.Option) iter.Seq2[*ConnectionInfo, error] { + return func(yield func(*ConnectionInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListConnectionsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListConnections(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Connections { + if !yield(&resp.Connections[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates the connection that matches the supplied name. +func (c *internalClient) UpdateConnection(ctx context.Context, req *UpdateConnectionRequest, opts ...call.Option) (*ConnectionInfo, error) { + wireReq, err := updateConnectionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/connections/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ConnectionInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp connectionInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = connectionInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/connections/v1/genhelper.go b/uc/connections/v1/genhelper.go new file mode 100755 index 0000000..e5af4d2 --- /dev/null +++ b/uc/connections/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package connections + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/connections/v1/model.go b/uc/connections/v1/model.go new file mode 100755 index 0000000..db33539 --- /dev/null +++ b/uc/connections/v1/model.go @@ -0,0 +1,270 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package connections + +type ConnectionType string + +const ( + ConnectionType_Unspecified ConnectionType = "" + ConnectionType_Mysql ConnectionType = "MYSQL" + ConnectionType_Postgresql ConnectionType = "POSTGRESQL" + ConnectionType_Snowflake ConnectionType = "SNOWFLAKE" + ConnectionType_Redshift ConnectionType = "REDSHIFT" + ConnectionType_Sqldw ConnectionType = "SQLDW" + ConnectionType_Sqlserver ConnectionType = "SQLSERVER" + ConnectionType_Databricks ConnectionType = "DATABRICKS" + ConnectionType_Salesforce ConnectionType = "SALESFORCE" + ConnectionType_Bigquery ConnectionType = "BIGQUERY" + ConnectionType_Netsuite ConnectionType = "NETSUITE" + ConnectionType_WorkdayRaas ConnectionType = "WORKDAY_RAAS" + ConnectionType_HiveMetastore ConnectionType = "HIVE_METASTORE" + ConnectionType_Ga4RawData ConnectionType = "GA4_RAW_DATA" + ConnectionType_Servicenow ConnectionType = "SERVICENOW" + ConnectionType_SalesforceDataCloud ConnectionType = "SALESFORCE_DATA_CLOUD" + ConnectionType_Glue ConnectionType = "GLUE" + ConnectionType_Oracle ConnectionType = "ORACLE" + ConnectionType_Teradata ConnectionType = "TERADATA" + ConnectionType_Http ConnectionType = "HTTP" + ConnectionType_PowerBi ConnectionType = "POWER_BI" + ConnectionType_Dynamics365 ConnectionType = "DYNAMICS365" + ConnectionType_Confluence ConnectionType = "CONFLUENCE" + ConnectionType_Jdbc ConnectionType = "JDBC" + ConnectionType_MetaMarketing ConnectionType = "META_MARKETING" + ConnectionType_Hubspot ConnectionType = "HUBSPOT" + ConnectionType_Zendesk ConnectionType = "ZENDESK" + ConnectionType_Github ConnectionType = "GITHUB" + ConnectionType_Outlook ConnectionType = "OUTLOOK" + ConnectionType_Smartsheet ConnectionType = "SMARTSHEET" +) + +type CredentialType string + +const ( + CredentialType_Unspecified CredentialType = "" + CredentialType_UsernamePassword CredentialType = "USERNAME_PASSWORD" + CredentialType_OauthU2m CredentialType = "OAUTH_U2M" + CredentialType_OauthM2m CredentialType = "OAUTH_M2M" + CredentialType_OauthRefreshToken CredentialType = "OAUTH_REFRESH_TOKEN" + CredentialType_OauthAccessToken CredentialType = "OAUTH_ACCESS_TOKEN" + CredentialType_OauthResourceOwnerPassword CredentialType = "OAUTH_RESOURCE_OWNER_PASSWORD" + CredentialType_ServiceCredential CredentialType = "SERVICE_CREDENTIAL" + CredentialType_BearerToken CredentialType = "BEARER_TOKEN" + CredentialType_OidcToken CredentialType = "OIDC_TOKEN" + CredentialType_PemPrivateKey CredentialType = "PEM_PRIVATE_KEY" + CredentialType_OauthU2mMapping CredentialType = "OAUTH_U2M_MAPPING" + CredentialType_AnyStaticCredential CredentialType = "ANY_STATIC_CREDENTIAL" + CredentialType_OauthMtls CredentialType = "OAUTH_MTLS" + CredentialType_SswsToken CredentialType = "SSWS_TOKEN" + CredentialType_EdgegridAkamai CredentialType = "EDGEGRID_AKAMAI" +) + +// The type of Unity Catalog securable. +type SecurableType string + +const ( + SecurableType_Unspecified SecurableType = "" + SecurableType_Catalog SecurableType = "CATALOG" + SecurableType_Schema SecurableType = "SCHEMA" + SecurableType_Table SecurableType = "TABLE" + SecurableType_StorageCredential SecurableType = "STORAGE_CREDENTIAL" + SecurableType_ExternalLocation SecurableType = "EXTERNAL_LOCATION" + SecurableType_Function SecurableType = "FUNCTION" + SecurableType_Share SecurableType = "SHARE" + SecurableType_Provider SecurableType = "PROVIDER" + SecurableType_Recipient SecurableType = "RECIPIENT" + SecurableType_CleanRoom SecurableType = "CLEAN_ROOM" + SecurableType_Metastore SecurableType = "METASTORE" + SecurableType_Pipeline SecurableType = "PIPELINE" + SecurableType_Volume SecurableType = "VOLUME" + SecurableType_Connection SecurableType = "CONNECTION" + SecurableType_Credential SecurableType = "CREDENTIAL" + SecurableType_ExternalMetadata SecurableType = "EXTERNAL_METADATA" + // TODO: [UC-2980] Staging tables aren't full-fleged securables yet. + SecurableType_StagingTable SecurableType = "STAGING_TABLE" +) + +type ProvisioningInfo_State string + +const ( + ProvisioningInfo_State_Unspecified ProvisioningInfo_State = "" + ProvisioningInfo_State_Provisioning ProvisioningInfo_State = "PROVISIONING" + ProvisioningInfo_State_Active ProvisioningInfo_State = "ACTIVE" + ProvisioningInfo_State_Failed ProvisioningInfo_State = "FAILED" + ProvisioningInfo_State_Deleting ProvisioningInfo_State = "DELETING" + ProvisioningInfo_State_Updating ProvisioningInfo_State = "UPDATING" + ProvisioningInfo_State_Degraded ProvisioningInfo_State = "DEGRADED" +) + +type ConnectionInfo struct { + // Name of the connection. + Name *string + // The type of connection. + ConnectionType ConnectionType + // Username of current owner of the connection. + Owner *string + // If the connection is read only. + ReadOnly *bool + // User-provided free-form text description. + Comment *string + // [Create,Update:OPT] Connection environment settings as EnvironmentSettings + // object. + EnvironmentSettings *EnvironmentSettings + // Full name of connection. + FullName *string + // URL of the remote data source, extracted from options. + Url *string + // The type of credential. + CredentialType CredentialType + // Unique identifier of the Connection. + ConnectionId *string + // Unique identifier of parent metastore. + MetastoreId *string + // Time at which this connection was created, in epoch milliseconds. + CreatedAt *int64 + // Username of connection creator. + CreatedBy *string + // Time at which this connection was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified connection. + UpdatedBy *string + SecurableType SecurableType + ProvisioningInfo *ProvisioningInfo + // A map of key-value properties attached to the securable. + Options map[string]string + // A map of key-value properties attached to the securable. + Properties map[string]string +} + +type CreateConnectionRequest struct { + // Parent schema for schema-level connections, in format + // "schemas/{catalog}.{schema}". Absent for metastore-level (L1) connections. + Parent *string + // Name of the connection. + Name *string + // The type of connection. + ConnectionType ConnectionType + // Username of current owner of the connection. + Owner *string + // If the connection is read only. + ReadOnly *bool + // User-provided free-form text description. + Comment *string + // [Create,Update:OPT] Connection environment settings as EnvironmentSettings + // object. + EnvironmentSettings *EnvironmentSettings + // Full name of connection. + FullName *string + // URL of the remote data source, extracted from options. + Url *string + // The type of credential. + CredentialType CredentialType + // Unique identifier of the Connection. + ConnectionId *string + // Unique identifier of parent metastore. + MetastoreId *string + // Time at which this connection was created, in epoch milliseconds. + CreatedAt *int64 + // Username of connection creator. + CreatedBy *string + // Time at which this connection was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified connection. + UpdatedBy *string + SecurableType SecurableType + ProvisioningInfo *ProvisioningInfo + // A map of key-value properties attached to the securable. + Options map[string]string + // A map of key-value properties attached to the securable. + Properties map[string]string +} + +type DeleteConnectionRequest struct { + // The name of the connection to be deleted. + NameArg *string +} + +type DeleteConnectionResponse struct { +} + +type EnvironmentSettings struct { + JavaDependencies []string + EnvironmentVersion *string +} + +type GetConnectionRequest struct { + // Name of the connection. + NameArg *string +} + +type ListConnectionsRequest struct { + // Maximum number of connections to return. - If not set, all connections are + // returned (not recommended). - when set to a value greater than 0, the page + // length is the minimum of this value and a server configured value; - when set + // to 0, the page length is set to a server configured value (recommended); - + // when set to a value less than 0, an invalid parameter error is returned; + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string + // Optional. Parent schema filter for listing schema-level connections, in + // format "schemas/{catalog}.{schema}". + Parent *string +} + +type ListConnectionsResponse struct { + // An array of connection information objects. + Connections []ConnectionInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +// Status of an asynchronously provisioned resource.. +type ProvisioningInfo struct { + // The provisioning state of the resource. + State ProvisioningInfo_State +} + +type UpdateConnectionRequest struct { + // Name of the connection. + NameArg *string + // New name for the connection. + NewName *string + // Name of the connection. + Name *string + // The type of connection. + ConnectionType ConnectionType + // Username of current owner of the connection. + Owner *string + // If the connection is read only. + ReadOnly *bool + // User-provided free-form text description. + Comment *string + // [Create,Update:OPT] Connection environment settings as EnvironmentSettings + // object. + EnvironmentSettings *EnvironmentSettings + // Full name of connection. + FullName *string + // URL of the remote data source, extracted from options. + Url *string + // The type of credential. + CredentialType CredentialType + // Unique identifier of the Connection. + ConnectionId *string + // Unique identifier of parent metastore. + MetastoreId *string + // Time at which this connection was created, in epoch milliseconds. + CreatedAt *int64 + // Username of connection creator. + CreatedBy *string + // Time at which this connection was updated, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified connection. + UpdatedBy *string + SecurableType SecurableType + ProvisioningInfo *ProvisioningInfo + // A map of key-value properties attached to the securable. + Options map[string]string + // A map of key-value properties attached to the securable. + Properties map[string]string +} diff --git a/uc/connections/v1/wire.go b/uc/connections/v1/wire.go new file mode 100755 index 0000000..7f3c9f3 --- /dev/null +++ b/uc/connections/v1/wire.go @@ -0,0 +1,282 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package connections + +import ( + "fmt" +) + +type connectionInfoWire struct { + Name *string `json:"name,omitempty"` + ConnectionType ConnectionType `json:"connection_type,omitempty"` + Owner *string `json:"owner,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Comment *string `json:"comment,omitempty"` + EnvironmentSettings *environmentSettingsWire `json:"environment_settings,omitempty"` + FullName *string `json:"full_name,omitempty"` + Url *string `json:"url,omitempty"` + CredentialType CredentialType `json:"credential_type,omitempty"` + ConnectionId *string `json:"connection_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + SecurableType SecurableType `json:"securable_type,omitempty"` + ProvisioningInfo *provisioningInfoWire `json:"provisioning_info,omitempty"` + Options map[string]string `json:"options,omitempty"` + Properties map[string]string `json:"properties,omitempty"` +} + +func connectionInfoFromWire(w *connectionInfoWire) (*ConnectionInfo, error) { + if w == nil { + return nil, nil + } + environmentSettingsPublicValue, err := environmentSettingsFromWire(w.EnvironmentSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectionInfo.EnvironmentSettings", err) + } + provisioningInfoPublicValue, err := provisioningInfoFromWire(w.ProvisioningInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ConnectionInfo.ProvisioningInfo", err) + } + return &ConnectionInfo{ + Name: w.Name, + ConnectionType: w.ConnectionType, + Owner: w.Owner, + ReadOnly: w.ReadOnly, + Comment: w.Comment, + EnvironmentSettings: environmentSettingsPublicValue, + FullName: w.FullName, + Url: w.Url, + CredentialType: w.CredentialType, + ConnectionId: w.ConnectionId, + MetastoreId: w.MetastoreId, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + SecurableType: w.SecurableType, + ProvisioningInfo: provisioningInfoPublicValue, + Options: w.Options, + Properties: w.Properties, + }, nil +} + +type createConnectionRequestWire struct { + Parent *string `json:"parent,omitempty"` + Name *string `json:"name,omitempty"` + ConnectionType ConnectionType `json:"connection_type,omitempty"` + Owner *string `json:"owner,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Comment *string `json:"comment,omitempty"` + EnvironmentSettings *environmentSettingsWire `json:"environment_settings,omitempty"` + FullName *string `json:"full_name,omitempty"` + Url *string `json:"url,omitempty"` + CredentialType CredentialType `json:"credential_type,omitempty"` + ConnectionId *string `json:"connection_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + SecurableType SecurableType `json:"securable_type,omitempty"` + ProvisioningInfo *provisioningInfoWire `json:"provisioning_info,omitempty"` + Options map[string]string `json:"options,omitempty"` + Properties map[string]string `json:"properties,omitempty"` +} + +func createConnectionRequestToWire(v *CreateConnectionRequest) (*createConnectionRequestWire, error) { + if v == nil { + return nil, nil + } + environmentSettingsWireValue, err := environmentSettingsToWire(v.EnvironmentSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateConnectionRequest.EnvironmentSettings", err) + } + provisioningInfoWireValue, err := provisioningInfoToWire(v.ProvisioningInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateConnectionRequest.ProvisioningInfo", err) + } + return &createConnectionRequestWire{ + Parent: v.Parent, + Name: v.Name, + ConnectionType: v.ConnectionType, + Owner: v.Owner, + ReadOnly: v.ReadOnly, + Comment: v.Comment, + EnvironmentSettings: environmentSettingsWireValue, + FullName: v.FullName, + Url: v.Url, + CredentialType: v.CredentialType, + ConnectionId: v.ConnectionId, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + SecurableType: v.SecurableType, + ProvisioningInfo: provisioningInfoWireValue, + Options: v.Options, + Properties: v.Properties, + }, nil +} + +type environmentSettingsWire struct { + JavaDependencies []string `json:"java_dependencies,omitempty"` + EnvironmentVersion *string `json:"environment_version,omitempty"` +} + +func environmentSettingsToWire(v *EnvironmentSettings) (*environmentSettingsWire, error) { + if v == nil { + return nil, nil + } + return &environmentSettingsWire{ + JavaDependencies: v.JavaDependencies, + EnvironmentVersion: v.EnvironmentVersion, + }, nil +} + +func environmentSettingsFromWire(w *environmentSettingsWire) (*EnvironmentSettings, error) { + if w == nil { + return nil, nil + } + return &EnvironmentSettings{ + JavaDependencies: w.JavaDependencies, + EnvironmentVersion: w.EnvironmentVersion, + }, nil +} + +type listConnectionsRequestWire struct { + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` + Parent *string `json:"parent,omitempty"` +} + +func listConnectionsRequestToWire(v *ListConnectionsRequest) (*listConnectionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listConnectionsRequestWire{ + MaxResults: v.MaxResults, + PageToken: v.PageToken, + Parent: v.Parent, + }, nil +} + +type listConnectionsResponseWire struct { + Connections []connectionInfoWire `json:"connections,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listConnectionsResponseFromWire(w *listConnectionsResponseWire) (*ListConnectionsResponse, error) { + if w == nil { + return nil, nil + } + connectionsPublicValue, err := convertSlice(w.Connections, connectionInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListConnectionsResponse.Connections", err) + } + return &ListConnectionsResponse{ + Connections: connectionsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type provisioningInfoWire struct { + State ProvisioningInfo_State `json:"state,omitempty"` +} + +func provisioningInfoToWire(v *ProvisioningInfo) (*provisioningInfoWire, error) { + if v == nil { + return nil, nil + } + return &provisioningInfoWire{ + State: v.State, + }, nil +} + +func provisioningInfoFromWire(w *provisioningInfoWire) (*ProvisioningInfo, error) { + if w == nil { + return nil, nil + } + return &ProvisioningInfo{ + State: w.State, + }, nil +} + +type updateConnectionRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + Name *string `json:"name,omitempty"` + ConnectionType ConnectionType `json:"connection_type,omitempty"` + Owner *string `json:"owner,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Comment *string `json:"comment,omitempty"` + EnvironmentSettings *environmentSettingsWire `json:"environment_settings,omitempty"` + FullName *string `json:"full_name,omitempty"` + Url *string `json:"url,omitempty"` + CredentialType CredentialType `json:"credential_type,omitempty"` + ConnectionId *string `json:"connection_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + SecurableType SecurableType `json:"securable_type,omitempty"` + ProvisioningInfo *provisioningInfoWire `json:"provisioning_info,omitempty"` + Options map[string]string `json:"options,omitempty"` + Properties map[string]string `json:"properties,omitempty"` +} + +func updateConnectionRequestToWire(v *UpdateConnectionRequest) (*updateConnectionRequestWire, error) { + if v == nil { + return nil, nil + } + environmentSettingsWireValue, err := environmentSettingsToWire(v.EnvironmentSettings) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateConnectionRequest.EnvironmentSettings", err) + } + provisioningInfoWireValue, err := provisioningInfoToWire(v.ProvisioningInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateConnectionRequest.ProvisioningInfo", err) + } + return &updateConnectionRequestWire{ + NameArg: v.NameArg, + NewName: v.NewName, + Name: v.Name, + ConnectionType: v.ConnectionType, + Owner: v.Owner, + ReadOnly: v.ReadOnly, + Comment: v.Comment, + EnvironmentSettings: environmentSettingsWireValue, + FullName: v.FullName, + Url: v.Url, + CredentialType: v.CredentialType, + ConnectionId: v.ConnectionId, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + SecurableType: v.SecurableType, + ProvisioningInfo: provisioningInfoWireValue, + Options: v.Options, + Properties: v.Properties, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/credentials/.package.json b/uc/credentials/.package.json new file mode 100644 index 0000000..7c0a6c6 --- /dev/null +++ b/uc/credentials/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/credentials" +} diff --git a/uc/credentials/CHANGELOG.md b/uc/credentials/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/credentials/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/credentials/README.md b/uc/credentials/README.md new file mode 100644 index 0000000..c7a61c6 --- /dev/null +++ b/uc/credentials/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/credentials + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/credentials@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/credentials/v1" + +client, err := credentials.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/credentials/go.mod b/uc/credentials/go.mod new file mode 100644 index 0000000..b32b145 --- /dev/null +++ b/uc/credentials/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/credentials + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/credentials/internal/version.go b/uc/credentials/internal/version.go new file mode 100644 index 0000000..eaa7d0a --- /dev/null +++ b/uc/credentials/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-credentials" + +const Version = "0.0.1-dev.1" diff --git a/uc/credentials/v1/client.go b/uc/credentials/v1/client.go new file mode 100755 index 0000000..6b7c491 --- /dev/null +++ b/uc/credentials/v1/client.go @@ -0,0 +1,1940 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package credentials + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/credentials/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new storage credential. The request object is specific to the +// cloud: - **AwsIamRole** for AWS credentials - **AzureServicePrincipal** for +// Azure credentials - **GcpServiceAccountKey** for GCP credentials +// +// The caller must be a metastore admin and have the `CREATE_STORAGE_CREDENTIAL` +// privilege on the metastore. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateAccountsStorageCredential(ctx context.Context, req *AccountsCreateStorageCredentialRequest, opts ...call.Option) (*AccountsCreateStorageCredentialResponse, error) { + wireReq, err := accountsCreateStorageCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + pb.literal("/storage-credentials") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsCreateStorageCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountsCreateStorageCredentialResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountsCreateStorageCredentialResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a storage credential from the metastore. The caller must be an owner +// of the storage credential. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteAccountsStorageCredential(ctx context.Context, req *AccountsDeleteStorageCredentialRequest, opts ...call.Option) (*AccountsDeleteStorageCredentialResponse, error) { + wireReq, err := accountsDeleteStorageCredentialRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + pb.literal("/storage-credentials/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsDeleteStorageCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &AccountsDeleteStorageCredentialResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a storage credential from the metastore. The caller must be a metastore +// admin, the owner of the storage credential, or have a level of privilege on +// the storage credential. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetAccountsStorageCredential(ctx context.Context, req *AccountsGetStorageCredentialRequest, opts ...call.Option) (*AccountsGetStorageCredentialResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + pb.literal("/storage-credentials/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsGetStorageCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountsGetStorageCredentialResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountsGetStorageCredentialResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a list of all storage credentials that have been assigned to given +// metastore. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListAccountsStorageCredentials(ctx context.Context, req *AccountsListStorageCredentialsRequest, opts ...call.Option) (*AccountsListStorageCredentialsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + pb.literal("/storage-credentials") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsListStorageCredentialsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountsListStorageCredentialsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountsListStorageCredentialsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a storage credential on the metastore. The caller must be the owner +// of the storage credential. If the caller is a metastore admin, only the +// **owner** credential can be changed. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateAccountsStorageCredential(ctx context.Context, req *AccountsUpdateStorageCredentialRequest, opts ...call.Option) (*AccountsUpdateStorageCredentialResponse, error) { + wireReq, err := accountsUpdateStorageCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + pb.literal("/storage-credentials/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsUpdateStorageCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountsUpdateStorageCredentialResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountsUpdateStorageCredentialResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new credential. The type of credential to be created is determined +// by the **purpose** field, which should be either **SERVICE** or **STORAGE**. +// +// The caller must be a metastore admin or have the metastore privilege +// **CREATE_STORAGE_CREDENTIAL** for storage credentials, or +// **CREATE_SERVICE_CREDENTIAL** for service credentials. +func (c *internalClient) CreateCredential(ctx context.Context, req *CreateCredentialRequest, opts ...call.Option) (*StorageCredentialInfo, error) { + wireReq, err := createCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StorageCredentialInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp storageCredentialInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = storageCredentialInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new storage credential. +// +// The caller must be a metastore admin or have the +// **CREATE_STORAGE_CREDENTIAL** privilege on the metastore. +func (c *internalClient) CreateStorageCredential(ctx context.Context, req *CreateStorageCredentialRequest, opts ...call.Option) (*StorageCredentialInfo, error) { + wireReq, err := createStorageCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/storage-credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StorageCredentialInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp storageCredentialInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = storageCredentialInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a service or storage credential from the metastore. The caller must +// be an owner of the credential. +func (c *internalClient) DeleteCredential(ctx context.Context, req *DeleteCredentialRequest, opts ...call.Option) (*DeleteCredentialResponse, error) { + wireReq, err := deleteCredentialRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/credentials/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteCredentialResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a storage credential from the metastore. The caller must be an owner +// of the storage credential. +func (c *internalClient) DeleteStorageCredential(ctx context.Context, req *DeleteStorageCredentialRequest, opts ...call.Option) (*DeleteStorageCredentialResponse, error) { + wireReq, err := deleteStorageCredentialRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/storage-credentials/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteStorageCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteStorageCredentialResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a short-lived credential for directly accessing cloud storage locations +// registered in . The Generate Temporary Path Credentials API is +// only supported for external storage paths, specifically external locations +// and external tables. Managed tables are not supported by this API. The +// metastore must have **external_access_enabled** flag set to true (default +// false). The caller must have the **EXTERNAL_USE_LOCATION** privilege on the +// external location; this privilege can only be granted by external location +// owners. For requests on existing external tables, the caller must also have +// the **EXTERNAL_USE_SCHEMA** privilege on the parent schema; this privilege +// can only be granted by catalog owners. +func (c *internalClient) GenerateTemporaryPathCredential(ctx context.Context, req *GenerateTemporaryPathCredentialRequest, opts ...call.Option) (*GenerateTemporaryPathCredentialResponse, error) { + wireReq, err := generateTemporaryPathCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/unity-catalog/temporary-path-credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenerateTemporaryPathCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp generateTemporaryPathCredentialResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = generateTemporaryPathCredentialResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Returns a set of temporary credentials generated using the specified service +// credential. The caller must be a metastore admin or have the metastore +// privilege **ACCESS** on the service credential. +func (c *internalClient) GenerateTemporaryServiceCredential(ctx context.Context, req *GenerateTemporaryServiceCredentialRequest, opts ...call.Option) (*TemporaryCredentials, error) { + wireReq, err := generateTemporaryServiceCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/temporary-service-credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TemporaryCredentials + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp temporaryCredentialsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = temporaryCredentialsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a short-lived credential for directly accessing the table data on cloud +// storage. The metastore must have **external_access_enabled** flag set to true +// (default false). The caller must have the **EXTERNAL_USE_SCHEMA** privilege +// on the parent schema and this privilege can only be granted by catalog +// owners. +func (c *internalClient) GenerateTemporaryTableCredential(ctx context.Context, req *GenerateTemporaryTableCredentialRequest, opts ...call.Option) (*GenerateTemporaryTableCredentialResponse, error) { + wireReq, err := generateTemporaryTableCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/unity-catalog/temporary-table-credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenerateTemporaryTableCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp generateTemporaryTableCredentialResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = generateTemporaryTableCredentialResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a short-lived credential for directly accessing the volume data on cloud +// storage. The metastore must have **external_access_enabled** flag set to true +// (default false). The caller must have the **EXTERNAL_USE_SCHEMA** privilege +// on the parent schema and this privilege can only be granted by catalog +// owners. +func (c *internalClient) GenerateTemporaryVolumeCredential(ctx context.Context, req *GenerateTemporaryVolumeCredentialRequest, opts ...call.Option) (*GenerateTemporaryVolumeCredentialResponse, error) { + wireReq, err := generateTemporaryVolumeCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/unity-catalog/temporary-volume-credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GenerateTemporaryVolumeCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp generateTemporaryVolumeCredentialResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = generateTemporaryVolumeCredentialResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a service or storage credential from the metastore. The caller must be a +// metastore admin, the owner of the credential, or have any permission on the +// credential. +func (c *internalClient) GetCredential(ctx context.Context, req *GetCredentialRequest, opts ...call.Option) (*StorageCredentialInfo, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/credentials/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StorageCredentialInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp storageCredentialInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = storageCredentialInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a storage credential from the metastore. The caller must be a metastore +// admin, the owner of the storage credential, or have some permission on the +// storage credential. +func (c *internalClient) GetStorageCredential(ctx context.Context, req *GetStorageCredentialRequest, opts ...call.Option) (*StorageCredentialInfo, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/storage-credentials/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StorageCredentialInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp storageCredentialInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = storageCredentialInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of credentials (as __CredentialInfo__ objects). +// +// The array is limited to only the credentials that the caller has permission +// to access. If the caller is a metastore admin, retrieval of credentials is +// unrestricted. There is no guarantee of a specific ordering of the elements in +// the array. +// +// PAGINATION BEHAVIOR: The API is by default paginated, a page may contain zero +// results while still providing a next_page_token. Clients must continue +// reading pages until next_page_token is absent, which is the only indication +// that the end of results has been reached. +func (c *internalClient) ListCredentials(ctx context.Context, req *ListCredentialsRequest, opts ...call.Option) (*ListCredentialsRequest_Response, error) { + wireReq, err := listCredentialsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/credentials" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_unbound", wireReq.IncludeUnbound); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCredentialsRequest_Response + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listCredentialsRequest_ResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listCredentialsRequest_ResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListCredentialsIter returns an iterator that iterates +// over the results of ListCredentials. +// +// For example: +// +// for item, err := range c.ListCredentialsIter(ctx, &ListCredentialsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListCredentials call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListCredentials directly. +func (c *internalClient) ListCredentialsIter(ctx context.Context, req *ListCredentialsRequest, opts ...call.Option) iter.Seq2[*CredentialInfo, error] { + return func(yield func(*CredentialInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListCredentialsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListCredentials(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Credentials { + if !yield(&resp.Credentials[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Gets an array of storage credentials (as __StorageCredentialInfo__ objects). +// The array is limited to only those storage credentials the caller has +// permission to access. If the caller is a metastore admin, retrieval of +// credentials is unrestricted. There is no guarantee of a specific ordering of +// the elements in the array. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) ListStorageCredentials(ctx context.Context, req *ListStorageCredentialsRequest, opts ...call.Option) (*ListStorageCredentialsResponse, error) { + wireReq, err := listStorageCredentialsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/storage-credentials" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_unbound", wireReq.IncludeUnbound); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListStorageCredentialsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listStorageCredentialsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listStorageCredentialsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListStorageCredentialsIter returns an iterator that iterates +// over the results of ListStorageCredentials. +// +// For example: +// +// for item, err := range c.ListStorageCredentialsIter(ctx, &ListStorageCredentialsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListStorageCredentials call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListStorageCredentials directly. +func (c *internalClient) ListStorageCredentialsIter(ctx context.Context, req *ListStorageCredentialsRequest, opts ...call.Option) iter.Seq2[*StorageCredentialInfo, error] { + return func(yield func(*StorageCredentialInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListStorageCredentialsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListStorageCredentials(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.StorageCredentials { + if !yield(&resp.StorageCredentials[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates a service or storage credential on the metastore. +// +// The caller must be the owner of the credential or a metastore admin or have +// the `MANAGE` permission. If the caller is a metastore admin, only the +// __owner__ field can be changed. +func (c *internalClient) UpdateCredential(ctx context.Context, req *UpdateCredentialRequest, opts ...call.Option) (*StorageCredentialInfo, error) { + wireReq, err := updateCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/credentials/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StorageCredentialInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp storageCredentialInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = storageCredentialInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a storage credential on the metastore. +// +// The caller must be the owner of the storage credential or a metastore admin. +// If the caller is a metastore admin, only the **owner** field can be changed. +func (c *internalClient) UpdateStorageCredential(ctx context.Context, req *UpdateStorageCredentialRequest, opts ...call.Option) (*StorageCredentialInfo, error) { + wireReq, err := updateStorageCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/storage-credentials/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StorageCredentialInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp storageCredentialInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = storageCredentialInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Validates a credential. +// +// For service credentials (purpose is **SERVICE**), either the +// __credential_name__ or the cloud-specific credential must be provided. +// +// For storage credentials (purpose is **STORAGE**), at least one of +// __external_location_name__ and __url__ need to be provided. If only one of +// them is provided, it will be used for validation. And if both are provided, +// the __url__ will be used for validation, and __external_location_name__ will +// be ignored when checking overlapping urls. Either the __credential_name__ or +// the cloud-specific credential must be provided. +// +// The caller must be a metastore admin or the credential owner or have the +// required permission on the metastore and the credential (e.g., +// **CREATE_EXTERNAL_LOCATION** when purpose is **STORAGE**). +func (c *internalClient) ValidateCredential(ctx context.Context, req *ValidateCredentialRequest, opts ...call.Option) (*ValidateCredentialResponse, error) { + wireReq, err := validateCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/validate-credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ValidateCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp validateCredentialResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = validateCredentialResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Validates a storage credential. At least one of __external_location_name__ +// and __url__ need to be provided. If only one of them is provided, it will be +// used for validation. And if both are provided, the __url__ will be used for +// validation, and __external_location_name__ will be ignored when checking +// overlapping urls. +// +// Either the __storage_credential_name__ or the cloud-specific credential must +// be provided. +// +// The caller must be a metastore admin or the storage credential owner or have +// the **CREATE_EXTERNAL_LOCATION** privilege on the metastore and the storage +// credential. +func (c *internalClient) ValidateStorageCredential(ctx context.Context, req *ValidateStorageCredentialRequest, opts ...call.Option) (*ValidateStorageCredentialResponse, error) { + wireReq, err := validateStorageCredentialRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/validate-storage-credentials" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ValidateStorageCredentialResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp validateStorageCredentialResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = validateStorageCredentialResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a credential configuration that represents cloud +// cross-account credentials for a specified account. uses this to +// set up network infrastructure properly to host clusters. For +// your AWS IAM role, you need to trust the External ID (the Databricks Account +// API account ID) in the returned credential object, and configure the required +// access policy. +// +// Save the response's `credentials_id` field, which is the ID for your new +// credential configuration object. +// +// For information about how to create a new workspace with this API, see +// [Create a new workspace using the Account API] +// +// [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateCredentialsPublic(ctx context.Context, req *CreateCredentialsRequest, opts ...call.Option) (*Credentials, error) { + wireReq, err := createCredentialsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/credentials") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Credentials + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp credentialsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = credentialsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a credential configuration object for an account, both +// specified by ID. You cannot delete a credential that is associated with any +// workspace. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteCredentialsPublic(ctx context.Context, req *DeleteCredentialsRequest, opts ...call.Option) (*Credentials, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/credentials/") + pb.singleSegment(*req.CredentialsId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Credentials + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp credentialsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = credentialsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a credential configuration object for an account, both +// specified by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetCredentialsPublic(ctx context.Context, req *GetCredentialsRequest, opts ...call.Option) (*Credentials, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/credentials/") + pb.singleSegment(*req.CredentialsId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Credentials + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp credentialsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = credentialsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List credential configuration objects for an account, specified +// by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListCredentialsPublic(ctx context.Context, req *ListCredentialsPublicRequest, opts ...call.Option) (*ListCredentialsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/credentials") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListCredentialsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp []credentialsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + convertedResponseBody, err := convertSlice(wireResp, credentialsFromWire) + if err != nil { + return fmt.Errorf("ListCredentialsResponse.Credentials: %w", err) + } + resp = &ListCredentialsResponse{ + Credentials: convertedResponseBody, + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/credentials/v1/genhelper.go b/uc/credentials/v1/genhelper.go new file mode 100755 index 0000000..8aeef03 --- /dev/null +++ b/uc/credentials/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package credentials + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/credentials/v1/model.go b/uc/credentials/v1/model.go new file mode 100755 index 0000000..f806ad7 --- /dev/null +++ b/uc/credentials/v1/model.go @@ -0,0 +1,1655 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package credentials + +type IsolationMode string + +const ( + IsolationMode_Unspecified IsolationMode = "" + IsolationMode_IsolationModeOpen IsolationMode = "ISOLATION_MODE_OPEN" + IsolationMode_IsolationModeIsolated IsolationMode = "ISOLATION_MODE_ISOLATED" +) + +type PathOperation string + +const ( + PathOperation_Unspecified PathOperation = "" + PathOperation_PathRead PathOperation = "PATH_READ" + PathOperation_PathReadWrite PathOperation = "PATH_READ_WRITE" + PathOperation_PathCreateTable PathOperation = "PATH_CREATE_TABLE" +) + +type TableOperation string + +const ( + TableOperation_Unspecified TableOperation = "" + TableOperation_Read TableOperation = "READ" + TableOperation_ReadWrite TableOperation = "READ_WRITE" +) + +type VolumeOperation string + +const ( + VolumeOperation_Unspecified VolumeOperation = "" + VolumeOperation_ReadVolume VolumeOperation = "READ_VOLUME" + VolumeOperation_WriteVolume VolumeOperation = "WRITE_VOLUME" +) + +// A enum represents the result of the file operation +type ValidateCredentialRequest_Result string + +const ( + ValidateCredentialRequest_Result_Unspecified ValidateCredentialRequest_Result = "" + ValidateCredentialRequest_Result_Pass ValidateCredentialRequest_Result = "PASS" + ValidateCredentialRequest_Result_Fail ValidateCredentialRequest_Result = "FAIL" + ValidateCredentialRequest_Result_Skip ValidateCredentialRequest_Result = "SKIP" +) + +// A enum represents the file operation performed on the external location with +// the storage credential +type ValidateStorageCredentialRequest_FileOperation string + +const ( + ValidateStorageCredentialRequest_FileOperation_Unspecified ValidateStorageCredentialRequest_FileOperation = "" + ValidateStorageCredentialRequest_FileOperation_Read ValidateStorageCredentialRequest_FileOperation = "READ" + ValidateStorageCredentialRequest_FileOperation_Write ValidateStorageCredentialRequest_FileOperation = "WRITE" + ValidateStorageCredentialRequest_FileOperation_Delete ValidateStorageCredentialRequest_FileOperation = "DELETE" + ValidateStorageCredentialRequest_FileOperation_PathExists ValidateStorageCredentialRequest_FileOperation = "PATH_EXISTS" +) + +// A enum represents the result of the file operation +type ValidateStorageCredentialRequest_Result string + +const ( + ValidateStorageCredentialRequest_Result_Unspecified ValidateStorageCredentialRequest_Result = "" + ValidateStorageCredentialRequest_Result_Fail ValidateStorageCredentialRequest_Result = "FAIL" + ValidateStorageCredentialRequest_Result_Skip ValidateStorageCredentialRequest_Result = "SKIP" +) + +type AccountsCreateStorageCredentialRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Unity Catalog metastore ID + MetastoreId *string + CredentialInfo *CreateAccountsStorageCredential + // Optional, default false. Supplying true to this argument skips validation of + // the created set of credentials. + SkipValidation *bool +} + +type AccountsCreateStorageCredentialResponse struct { + CredentialInfo *StorageCredentialInfo +} + +// Deletes a storage credential for an account. +type AccountsDeleteStorageCredentialRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Unity Catalog metastore ID + MetastoreId *string + // Name of the storage credential. + NameArg *string + // Force deletion even if the Storage Credential is not empty. Default is false. + Force *bool +} + +// The storage credential was successfully deleted.. +type AccountsDeleteStorageCredentialResponse struct { +} + +// Retrieves a single storage credential. +type AccountsGetStorageCredentialRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Unity Catalog metastore ID + MetastoreId *string + // Required. Name of the storage credential. + NameArg *string +} + +// The storage credential was successfully retrieved.. +type AccountsGetStorageCredentialResponse struct { + CredentialInfo *StorageCredentialInfo +} + +// Lists all storage credentials for the given account and metastore. +type AccountsListStorageCredentialsRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Unity Catalog metastore ID + MetastoreId *string +} + +// The metastore storage credentials were successfully returned.. +type AccountsListStorageCredentialsResponse struct { + // An array of metastore storage credentials. + StorageCredentials []StorageCredentialInfo +} + +// The storage credential to update.. +type AccountsUpdateStorageCredentialRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Unity Catalog metastore ID + MetastoreId *string + // Name of the storage credential. + NameArg *string + CredentialInfo *UpdateAccountsStorageCredential + // Optional. Supplying true to this argument skips validation of the updated set + // of credentials. + SkipValidation *bool +} + +// The storage credential was successfully updated.. +type AccountsUpdateStorageCredentialResponse struct { + CredentialInfo *StorageCredentialInfo +} + +type AwsCredentials struct { + Creds isAwsCredentials_Creds +} + +type isAwsCredentials_Creds interface { + isAwsCredentials_Creds() +} + +// AwsCredentials_Creds_StsRole selects StsRole for AwsCredentials.Creds. +type AwsCredentials_Creds_StsRole struct { + StsRole AwsCredentials_StsRole +} + +func (*AwsCredentials_Creds_StsRole) isAwsCredentials_Creds() {} + +type AwsCredentials_StsRole struct { + // The Amazon Resource Name (ARN) of the cross account IAM role. + RoleArn *string +} + +// The AWS IAM role configuration. +type AwsIamRole struct { + // The Amazon Resource Name (ARN) of the AWS IAM role used to vend temporary + // credentials. + RoleArn *string + // The Amazon Resource Name (ARN) of the AWS IAM user managed by . + // This is the identity that is going to assume the AWS IAM role. + UnityCatalogIamArn *string + // The external ID used in role assumption to prevent the confused deputy + // problem. + ExternalId *string +} + +// Azure Active Directory token, essentially the Oauth token for Azure Service +// Principal or Managed Identity. Read more at +// https://learn.microsoft.com/en-us/azure/databricks/dev-tools/api/latest/aad/service-prin-aad-token. +type AzureActiveDirectoryToken struct { + // Opaque token that contains claims that you can use in Azure Active Directory + // to access cloud services. + AadToken *string +} + +// The Azure managed identity configuration.. +type AzureManagedIdentity struct { + // The Azure resource ID of the Azure Databricks Access Connector. Use the + // format + // `/subscriptions/{guid}/resourceGroups/{rg-name}/providers/Microsoft.Databricks/accessConnectors/{connector-name}`. + AccessConnectorId *string + // The Azure resource ID of the managed identity. Use the format, + // `/subscriptions/{guid}/resourceGroups/{rg-name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identity-name}` + // This is only available for user-assgined identities. For system-assigned + // identities, the access_connector_id is used to identify the identity. If this + // field is not provided, then we assume the AzureManagedIdentity is using the + // system-assigned identity. + ManagedIdentityId *string + // The internal ID that represents this managed identity. + CredentialId *string +} + +// The Azure service principal configuration. Only applicable when purpose is +// **STORAGE**.. +type AzureServicePrincipal struct { + // The directory ID corresponding to the Azure Active Directory (AAD) tenant of + // the application. + DirectoryId *string + // The application ID of the application registration within the referenced AAD + // tenant. + ApplicationId *string + // The client secret generated for the above app ID in AAD. + ClientSecret *string +} + +// Azure temporary credentials for API authentication. Read more at +// https://docs.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas. +type AzureUserDelegationSas struct { + // The signed URI (SAS Token) used to access blob services for a given path + SasToken *string +} + +// The Cloudflare API token configuration. Read more at +// https://developers.cloudflare.com/r2/api/s3/tokens/. +type CloudflareApiToken struct { + // The access key ID associated with the API token. + AccessKeyId *string + // The secret access token generated for the above access key ID. + SecretAccessKey *string + // The ID of the account associated with the API token. + AccountId *string +} + +type CreateAccountsStorageCredential struct { + // The credential name. The name must be unique among storage and service + // credentials within the metastore. + Name *string + // (--[Create:REQ, Update:OPT] The long-lived cloud credential.--) + Credential isCreateAccountsStorageCredential_Credential + // Comment associated with the credential. + Comment *string + // Whether the credential is usable only for read operations. Only applicable + // when purpose is **STORAGE**. + ReadOnly *bool + // Username of current owner of credential. + Owner *string + // The unique identifier of the credential. + Id *string + // Unique identifier of the parent metastore. + MetastoreId *string + // Time at which this credential was created, in epoch milliseconds. + CreatedAt *int64 + // Username of credential creator. + CreatedBy *string + // Time at which this credential was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the credential. + UpdatedBy *string + // Whether this credential is the current metastore's root storage credential. + // Only applicable when purpose is **STORAGE**. + UsedForManagedStorage *bool + // The full name of the credential. + FullName *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode IsolationMode +} + +type isCreateAccountsStorageCredential_Credential interface { + isCreateAccountsStorageCredential_Credential() +} + +// CreateAccountsStorageCredential_Credential_AwsIamRole selects AwsIamRole for CreateAccountsStorageCredential.Credential. +// The AWS IAM role configuration. +type CreateAccountsStorageCredential_Credential_AwsIamRole struct { + AwsIamRole AwsIamRole +} + +func (*CreateAccountsStorageCredential_Credential_AwsIamRole) isCreateAccountsStorageCredential_Credential() { +} + +// CreateAccountsStorageCredential_Credential_AzureServicePrincipal selects AzureServicePrincipal for CreateAccountsStorageCredential.Credential. +// The Azure service principal configuration. +type CreateAccountsStorageCredential_Credential_AzureServicePrincipal struct { + AzureServicePrincipal AzureServicePrincipal +} + +func (*CreateAccountsStorageCredential_Credential_AzureServicePrincipal) isCreateAccountsStorageCredential_Credential() { +} + +// CreateAccountsStorageCredential_Credential_GcpServiceAccountKey selects GcpServiceAccountKey for CreateAccountsStorageCredential.Credential. +type CreateAccountsStorageCredential_Credential_GcpServiceAccountKey struct { + GcpServiceAccountKey GcpServiceAccountKey +} + +func (*CreateAccountsStorageCredential_Credential_GcpServiceAccountKey) isCreateAccountsStorageCredential_Credential() { +} + +// CreateAccountsStorageCredential_Credential_AzureManagedIdentity selects AzureManagedIdentity for CreateAccountsStorageCredential.Credential. +// The Azure managed identity configuration. +type CreateAccountsStorageCredential_Credential_AzureManagedIdentity struct { + AzureManagedIdentity AzureManagedIdentity +} + +func (*CreateAccountsStorageCredential_Credential_AzureManagedIdentity) isCreateAccountsStorageCredential_Credential() { +} + +// CreateAccountsStorageCredential_Credential_DatabricksGcpServiceAccount selects DatabricksGcpServiceAccount for CreateAccountsStorageCredential.Credential. +// The managed GCP service account configuration. +type CreateAccountsStorageCredential_Credential_DatabricksGcpServiceAccount struct { + DatabricksGcpServiceAccount DatabricksGcpServiceAccount +} + +func (*CreateAccountsStorageCredential_Credential_DatabricksGcpServiceAccount) isCreateAccountsStorageCredential_Credential() { +} + +// CreateAccountsStorageCredential_Credential_CloudflareApiToken selects CloudflareApiToken for CreateAccountsStorageCredential.Credential. +// The Cloudflare API token configuration. +type CreateAccountsStorageCredential_Credential_CloudflareApiToken struct { + CloudflareApiToken CloudflareApiToken +} + +func (*CreateAccountsStorageCredential_Credential_CloudflareApiToken) isCreateAccountsStorageCredential_Credential() { +} + +type CreateCredentialAwsCredentials struct { + Creds isCreateCredentialAwsCredentials_Creds +} + +type isCreateCredentialAwsCredentials_Creds interface { + isCreateCredentialAwsCredentials_Creds() +} + +// CreateCredentialAwsCredentials_Creds_StsRole selects StsRole for CreateCredentialAwsCredentials.Creds. +type CreateCredentialAwsCredentials_Creds_StsRole struct { + StsRole AwsCredentials_StsRole +} + +func (*CreateCredentialAwsCredentials_Creds_StsRole) isCreateCredentialAwsCredentials_Creds() {} + +type CreateCredentialRequest struct { + // Optional. Supplying true to this argument skips validation of the created set + // of credentials. + SkipValidation *bool + // The credential name. The name must be unique among storage and service + // credentials within the metastore. + Name *string + // (--[Create:REQ, Update:OPT] The long-lived cloud credential.--) + Credential isCreateCredentialRequest_Credential + // Comment associated with the credential. + Comment *string + // Whether the credential is usable only for read operations. Only applicable + // when purpose is **STORAGE**. + ReadOnly *bool + // Username of current owner of credential. + Owner *string + // The unique identifier of the credential. + Id *string + // Unique identifier of the parent metastore. + MetastoreId *string + // Time at which this credential was created, in epoch milliseconds. + CreatedAt *int64 + // Username of credential creator. + CreatedBy *string + // Time at which this credential was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the credential. + UpdatedBy *string + // Whether this credential is the current metastore's root storage credential. + // Only applicable when purpose is **STORAGE**. + UsedForManagedStorage *bool + // The full name of the credential. + FullName *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode IsolationMode +} + +type isCreateCredentialRequest_Credential interface { + isCreateCredentialRequest_Credential() +} + +// CreateCredentialRequest_Credential_AwsIamRole selects AwsIamRole for CreateCredentialRequest.Credential. +// The AWS IAM role configuration. +type CreateCredentialRequest_Credential_AwsIamRole struct { + AwsIamRole AwsIamRole +} + +func (*CreateCredentialRequest_Credential_AwsIamRole) isCreateCredentialRequest_Credential() {} + +// CreateCredentialRequest_Credential_AzureServicePrincipal selects AzureServicePrincipal for CreateCredentialRequest.Credential. +// The Azure service principal configuration. +type CreateCredentialRequest_Credential_AzureServicePrincipal struct { + AzureServicePrincipal AzureServicePrincipal +} + +func (*CreateCredentialRequest_Credential_AzureServicePrincipal) isCreateCredentialRequest_Credential() { +} + +// CreateCredentialRequest_Credential_GcpServiceAccountKey selects GcpServiceAccountKey for CreateCredentialRequest.Credential. +type CreateCredentialRequest_Credential_GcpServiceAccountKey struct { + GcpServiceAccountKey GcpServiceAccountKey +} + +func (*CreateCredentialRequest_Credential_GcpServiceAccountKey) isCreateCredentialRequest_Credential() { +} + +// CreateCredentialRequest_Credential_AzureManagedIdentity selects AzureManagedIdentity for CreateCredentialRequest.Credential. +// The Azure managed identity configuration. +type CreateCredentialRequest_Credential_AzureManagedIdentity struct { + AzureManagedIdentity AzureManagedIdentity +} + +func (*CreateCredentialRequest_Credential_AzureManagedIdentity) isCreateCredentialRequest_Credential() { +} + +// CreateCredentialRequest_Credential_DatabricksGcpServiceAccount selects DatabricksGcpServiceAccount for CreateCredentialRequest.Credential. +// The managed GCP service account configuration. +type CreateCredentialRequest_Credential_DatabricksGcpServiceAccount struct { + DatabricksGcpServiceAccount DatabricksGcpServiceAccount +} + +func (*CreateCredentialRequest_Credential_DatabricksGcpServiceAccount) isCreateCredentialRequest_Credential() { +} + +// CreateCredentialRequest_Credential_CloudflareApiToken selects CloudflareApiToken for CreateCredentialRequest.Credential. +// The Cloudflare API token configuration. +type CreateCredentialRequest_Credential_CloudflareApiToken struct { + CloudflareApiToken CloudflareApiToken +} + +func (*CreateCredentialRequest_Credential_CloudflareApiToken) isCreateCredentialRequest_Credential() { +} + +type CreateCredentialsRequest struct { + AccountId *string + // The human-readable name of the credential configuration object. + CredentialsName *string + // (-- NOTE(austin) This oneof is a future-looking definition when we add other + // clouds --) + CloudCredentials isCreateCredentialsRequest_CloudCredentials +} + +type isCreateCredentialsRequest_CloudCredentials interface { + isCreateCredentialsRequest_CloudCredentials() +} + +// CreateCredentialsRequest_CloudCredentials_AwsCredentials selects AwsCredentials for CreateCredentialsRequest.CloudCredentials. +type CreateCredentialsRequest_CloudCredentials_AwsCredentials struct { + AwsCredentials CreateCredentialAwsCredentials +} + +func (*CreateCredentialsRequest_CloudCredentials_AwsCredentials) isCreateCredentialsRequest_CloudCredentials() { +} + +type CreateStorageCredentialRequest struct { + // Supplying true to this argument skips validation of the created credential. + SkipValidation *bool + // The credential name. The name must be unique among storage and service + // credentials within the metastore. + Name *string + // (--[Create:REQ, Update:OPT] The long-lived cloud credential.--) + Credential isCreateStorageCredentialRequest_Credential + // Comment associated with the credential. + Comment *string + // Whether the credential is usable only for read operations. Only applicable + // when purpose is **STORAGE**. + ReadOnly *bool + // Username of current owner of credential. + Owner *string + // The unique identifier of the credential. + Id *string + // Unique identifier of the parent metastore. + MetastoreId *string + // Time at which this credential was created, in epoch milliseconds. + CreatedAt *int64 + // Username of credential creator. + CreatedBy *string + // Time at which this credential was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the credential. + UpdatedBy *string + // Whether this credential is the current metastore's root storage credential. + // Only applicable when purpose is **STORAGE**. + UsedForManagedStorage *bool + // The full name of the credential. + FullName *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode IsolationMode +} + +type isCreateStorageCredentialRequest_Credential interface { + isCreateStorageCredentialRequest_Credential() +} + +// CreateStorageCredentialRequest_Credential_AwsIamRole selects AwsIamRole for CreateStorageCredentialRequest.Credential. +// The AWS IAM role configuration. +type CreateStorageCredentialRequest_Credential_AwsIamRole struct { + AwsIamRole AwsIamRole +} + +func (*CreateStorageCredentialRequest_Credential_AwsIamRole) isCreateStorageCredentialRequest_Credential() { +} + +// CreateStorageCredentialRequest_Credential_AzureServicePrincipal selects AzureServicePrincipal for CreateStorageCredentialRequest.Credential. +// The Azure service principal configuration. +type CreateStorageCredentialRequest_Credential_AzureServicePrincipal struct { + AzureServicePrincipal AzureServicePrincipal +} + +func (*CreateStorageCredentialRequest_Credential_AzureServicePrincipal) isCreateStorageCredentialRequest_Credential() { +} + +// CreateStorageCredentialRequest_Credential_GcpServiceAccountKey selects GcpServiceAccountKey for CreateStorageCredentialRequest.Credential. +type CreateStorageCredentialRequest_Credential_GcpServiceAccountKey struct { + GcpServiceAccountKey GcpServiceAccountKey +} + +func (*CreateStorageCredentialRequest_Credential_GcpServiceAccountKey) isCreateStorageCredentialRequest_Credential() { +} + +// CreateStorageCredentialRequest_Credential_AzureManagedIdentity selects AzureManagedIdentity for CreateStorageCredentialRequest.Credential. +// The Azure managed identity configuration. +type CreateStorageCredentialRequest_Credential_AzureManagedIdentity struct { + AzureManagedIdentity AzureManagedIdentity +} + +func (*CreateStorageCredentialRequest_Credential_AzureManagedIdentity) isCreateStorageCredentialRequest_Credential() { +} + +// CreateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount selects DatabricksGcpServiceAccount for CreateStorageCredentialRequest.Credential. +// The managed GCP service account configuration. +type CreateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount struct { + DatabricksGcpServiceAccount DatabricksGcpServiceAccount +} + +func (*CreateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount) isCreateStorageCredentialRequest_Credential() { +} + +// CreateStorageCredentialRequest_Credential_CloudflareApiToken selects CloudflareApiToken for CreateStorageCredentialRequest.Credential. +// The Cloudflare API token configuration. +type CreateStorageCredentialRequest_Credential_CloudflareApiToken struct { + CloudflareApiToken CloudflareApiToken +} + +func (*CreateStorageCredentialRequest_Credential_CloudflareApiToken) isCreateStorageCredentialRequest_Credential() { +} + +type CredentialInfo struct { + // The credential name. The name must be unique among storage and service + // credentials within the metastore. + Name *string + // (--[Create:REQ, Update:OPT] The long-lived cloud credential.--) + Credential isCredentialInfo_Credential + // Comment associated with the credential. + Comment *string + // Whether the credential is usable only for read operations. Only applicable + // when purpose is **STORAGE**. + ReadOnly *bool + // Username of current owner of credential. + Owner *string + // The unique identifier of the credential. + Id *string + // Unique identifier of the parent metastore. + MetastoreId *string + // Time at which this credential was created, in epoch milliseconds. + CreatedAt *int64 + // Username of credential creator. + CreatedBy *string + // Time at which this credential was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the credential. + UpdatedBy *string + // Whether this credential is the current metastore's root storage credential. + // Only applicable when purpose is **STORAGE**. + UsedForManagedStorage *bool + // The full name of the credential. + FullName *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode IsolationMode +} + +type isCredentialInfo_Credential interface { + isCredentialInfo_Credential() +} + +// CredentialInfo_Credential_AwsIamRole selects AwsIamRole for CredentialInfo.Credential. +// The AWS IAM role configuration. +type CredentialInfo_Credential_AwsIamRole struct { + AwsIamRole AwsIamRole +} + +func (*CredentialInfo_Credential_AwsIamRole) isCredentialInfo_Credential() {} + +// CredentialInfo_Credential_AzureServicePrincipal selects AzureServicePrincipal for CredentialInfo.Credential. +// The Azure service principal configuration. +type CredentialInfo_Credential_AzureServicePrincipal struct { + AzureServicePrincipal AzureServicePrincipal +} + +func (*CredentialInfo_Credential_AzureServicePrincipal) isCredentialInfo_Credential() {} + +// CredentialInfo_Credential_GcpServiceAccountKey selects GcpServiceAccountKey for CredentialInfo.Credential. +type CredentialInfo_Credential_GcpServiceAccountKey struct { + GcpServiceAccountKey GcpServiceAccountKey +} + +func (*CredentialInfo_Credential_GcpServiceAccountKey) isCredentialInfo_Credential() {} + +// CredentialInfo_Credential_AzureManagedIdentity selects AzureManagedIdentity for CredentialInfo.Credential. +// The Azure managed identity configuration. +type CredentialInfo_Credential_AzureManagedIdentity struct { + AzureManagedIdentity AzureManagedIdentity +} + +func (*CredentialInfo_Credential_AzureManagedIdentity) isCredentialInfo_Credential() {} + +// CredentialInfo_Credential_DatabricksGcpServiceAccount selects DatabricksGcpServiceAccount for CredentialInfo.Credential. +// The managed GCP service account configuration. +type CredentialInfo_Credential_DatabricksGcpServiceAccount struct { + DatabricksGcpServiceAccount DatabricksGcpServiceAccount +} + +func (*CredentialInfo_Credential_DatabricksGcpServiceAccount) isCredentialInfo_Credential() {} + +// CredentialInfo_Credential_CloudflareApiToken selects CloudflareApiToken for CredentialInfo.Credential. +// The Cloudflare API token configuration. +type CredentialInfo_Credential_CloudflareApiToken struct { + CloudflareApiToken CloudflareApiToken +} + +func (*CredentialInfo_Credential_CloudflareApiToken) isCredentialInfo_Credential() {} + +type Credentials struct { + // credential configuration ID. + CredentialsId *string + // The account ID that hosts the credential. + AccountId *string + // (-- NOTE(austin) This oneof is a future-looking definition when we add other + // clouds --) + CloudCredentials isCredentials_CloudCredentials + // The human-readable name of the credential configuration object. + CredentialsName *string + // Time in epoch milliseconds when the credential was created. + CreationTime *int64 +} + +type isCredentials_CloudCredentials interface { + isCredentials_CloudCredentials() +} + +// Credentials_CloudCredentials_AwsCredentials selects AwsCredentials for Credentials.CloudCredentials. +type Credentials_CloudCredentials_AwsCredentials struct { + AwsCredentials AwsCredentials +} + +func (*Credentials_CloudCredentials_AwsCredentials) isCredentials_CloudCredentials() {} + +// GCP long-lived credential. -created Google Cloud Storage service +// account.. +type DatabricksGcpServiceAccount struct { + // The email of the service account. + Email *string + // The ID that represents the private key for this Service Account + PrivateKeyId *string + // The internal ID that represents this managed identity. + CredentialId *string +} + +type DeleteCredentialRequest struct { + // Name of the credential. + NameArg *string + // Force an update even if there are dependent services (when purpose is + // **SERVICE**) or dependent external locations and external tables (when + // purpose is **STORAGE**). + Force *bool +} + +type DeleteCredentialResponse struct { +} + +type DeleteCredentialsRequest struct { + // Databricks Account API credential configuration ID + CredentialsId *string + AccountId *string +} + +type DeleteStorageCredentialRequest struct { + // Name of the storage credential. + NameArg *string + // Force an update even if there are dependent external locations or external + // tables (when purpose is **STORAGE**) or dependent services (when purpose is + // **SERVICE**). + Force *bool +} + +type DeleteStorageCredentialResponse struct { +} + +// GCP temporary credentials for API authentication. Read more at +// https://developers.google.com/identity/protocols/oauth2/service-account. +type GcpOauthToken struct { + OauthToken *string +} + +// GCP long-lived credential. GCP Service Account.. +type GcpServiceAccountKey struct { + // The email of the service account. + Email *string + // The ID of the service account's private key. + PrivateKeyId *string + // The service account's RSA private key. + PrivateKey *string +} + +type GenerateTemporaryPathCredentialRequest struct { + // URL for path-based access. + Url *string + // The operation being performed on the path. + Operation PathOperation + // Optional. When set to true, the service will not validate that the generated + // credentials can perform write operations, therefore no new paths will be + // created and the response will not contain valid credentials. Defaults to + // false. + DryRun *bool +} + +type GenerateTemporaryPathCredentialResponse struct { + // The temporary credential. + Credentials isGenerateTemporaryPathCredentialResponse_Credentials + // Server time when the credential will expire, in epoch milliseconds. The API + // client is advised to cache the credential given this expiration time. + ExpirationTime *int64 + // The URL of the storage path accessible by the temporary credential. + Url *string +} + +type isGenerateTemporaryPathCredentialResponse_Credentials interface { + isGenerateTemporaryPathCredentialResponse_Credentials() +} + +// GenerateTemporaryPathCredentialResponse_Credentials_AwsTempCredentials selects AwsTempCredentials for GenerateTemporaryPathCredentialResponse.Credentials. +type GenerateTemporaryPathCredentialResponse_Credentials_AwsTempCredentials struct { + AwsTempCredentials TemporaryAwsCredentials +} + +func (*GenerateTemporaryPathCredentialResponse_Credentials_AwsTempCredentials) isGenerateTemporaryPathCredentialResponse_Credentials() { +} + +// GenerateTemporaryPathCredentialResponse_Credentials_AzureUserDelegationSas selects AzureUserDelegationSas for GenerateTemporaryPathCredentialResponse.Credentials. +type GenerateTemporaryPathCredentialResponse_Credentials_AzureUserDelegationSas struct { + AzureUserDelegationSas AzureUserDelegationSas +} + +func (*GenerateTemporaryPathCredentialResponse_Credentials_AzureUserDelegationSas) isGenerateTemporaryPathCredentialResponse_Credentials() { +} + +// GenerateTemporaryPathCredentialResponse_Credentials_GcpOauthToken selects GcpOauthToken for GenerateTemporaryPathCredentialResponse.Credentials. +type GenerateTemporaryPathCredentialResponse_Credentials_GcpOauthToken struct { + GcpOauthToken GcpOauthToken +} + +func (*GenerateTemporaryPathCredentialResponse_Credentials_GcpOauthToken) isGenerateTemporaryPathCredentialResponse_Credentials() { +} + +// GenerateTemporaryPathCredentialResponse_Credentials_AzureAad selects AzureAad for GenerateTemporaryPathCredentialResponse.Credentials. +type GenerateTemporaryPathCredentialResponse_Credentials_AzureAad struct { + AzureAad AzureActiveDirectoryToken +} + +func (*GenerateTemporaryPathCredentialResponse_Credentials_AzureAad) isGenerateTemporaryPathCredentialResponse_Credentials() { +} + +// GenerateTemporaryPathCredentialResponse_Credentials_R2TempCredentials selects R2TempCredentials for GenerateTemporaryPathCredentialResponse.Credentials. +type GenerateTemporaryPathCredentialResponse_Credentials_R2TempCredentials struct { + R2TempCredentials R2Credentials +} + +func (*GenerateTemporaryPathCredentialResponse_Credentials_R2TempCredentials) isGenerateTemporaryPathCredentialResponse_Credentials() { +} + +type GenerateTemporaryServiceCredentialRequest struct { + // The name of the service credential used to generate a temporary credential + CredentialName *string + Options isGenerateTemporaryServiceCredentialRequest_Options +} + +type isGenerateTemporaryServiceCredentialRequest_Options interface { + isGenerateTemporaryServiceCredentialRequest_Options() +} + +// GenerateTemporaryServiceCredentialRequest_Options_AzureOptions selects AzureOptions for GenerateTemporaryServiceCredentialRequest.Options. +type GenerateTemporaryServiceCredentialRequest_Options_AzureOptions struct { + AzureOptions GenerateTemporaryServiceCredentialRequest_AzureOptions +} + +func (*GenerateTemporaryServiceCredentialRequest_Options_AzureOptions) isGenerateTemporaryServiceCredentialRequest_Options() { +} + +// GenerateTemporaryServiceCredentialRequest_Options_GcpOptions selects GcpOptions for GenerateTemporaryServiceCredentialRequest.Options. +type GenerateTemporaryServiceCredentialRequest_Options_GcpOptions struct { + GcpOptions GenerateTemporaryServiceCredentialRequest_GcpOptions +} + +func (*GenerateTemporaryServiceCredentialRequest_Options_GcpOptions) isGenerateTemporaryServiceCredentialRequest_Options() { +} + +// The Azure cloud options to customize the requested temporary credential. +type GenerateTemporaryServiceCredentialRequest_AzureOptions struct { + // The resources to which the temporary Azure credential should apply. These + // resources are the scopes that are passed to the token provider (see + // https://learn.microsoft.com/python/api/azure-core/azure.core.credentials.tokencredential?view=azure-python) + Resources []string +} + +// The GCP cloud options to customize the requested temporary credential. +type GenerateTemporaryServiceCredentialRequest_GcpOptions struct { + // The scopes to which the temporary GCP credential should apply. These + // resources are the scopes that are passed to the token provider (see + // https://google-auth.readthedocs.io/en/latest/reference/google.auth.html#google.auth.credentials.Credentials) + Scopes []string +} + +type GenerateTemporaryTableCredentialRequest struct { + // UUID of the table to read or write. + TableId *string + // The operation performed against the table data, either READ or READ_WRITE. If + // READ_WRITE is specified, the credentials returned will have write + // permissions, otherwise, it will be read only. + Operation TableOperation +} + +type GenerateTemporaryTableCredentialResponse struct { + // The temporary credential. + Credentials isGenerateTemporaryTableCredentialResponse_Credentials + // Server time when the credential will expire, in epoch milliseconds. The API + // client is advised to cache the credential given this expiration time. + ExpirationTime *int64 + // The URL of the storage path accessible by the temporary credential. + Url *string +} + +type isGenerateTemporaryTableCredentialResponse_Credentials interface { + isGenerateTemporaryTableCredentialResponse_Credentials() +} + +// GenerateTemporaryTableCredentialResponse_Credentials_AwsTempCredentials selects AwsTempCredentials for GenerateTemporaryTableCredentialResponse.Credentials. +type GenerateTemporaryTableCredentialResponse_Credentials_AwsTempCredentials struct { + AwsTempCredentials TemporaryAwsCredentials +} + +func (*GenerateTemporaryTableCredentialResponse_Credentials_AwsTempCredentials) isGenerateTemporaryTableCredentialResponse_Credentials() { +} + +// GenerateTemporaryTableCredentialResponse_Credentials_AzureUserDelegationSas selects AzureUserDelegationSas for GenerateTemporaryTableCredentialResponse.Credentials. +type GenerateTemporaryTableCredentialResponse_Credentials_AzureUserDelegationSas struct { + AzureUserDelegationSas AzureUserDelegationSas +} + +func (*GenerateTemporaryTableCredentialResponse_Credentials_AzureUserDelegationSas) isGenerateTemporaryTableCredentialResponse_Credentials() { +} + +// GenerateTemporaryTableCredentialResponse_Credentials_GcpOauthToken selects GcpOauthToken for GenerateTemporaryTableCredentialResponse.Credentials. +type GenerateTemporaryTableCredentialResponse_Credentials_GcpOauthToken struct { + GcpOauthToken GcpOauthToken +} + +func (*GenerateTemporaryTableCredentialResponse_Credentials_GcpOauthToken) isGenerateTemporaryTableCredentialResponse_Credentials() { +} + +// GenerateTemporaryTableCredentialResponse_Credentials_AzureAad selects AzureAad for GenerateTemporaryTableCredentialResponse.Credentials. +type GenerateTemporaryTableCredentialResponse_Credentials_AzureAad struct { + AzureAad AzureActiveDirectoryToken +} + +func (*GenerateTemporaryTableCredentialResponse_Credentials_AzureAad) isGenerateTemporaryTableCredentialResponse_Credentials() { +} + +// GenerateTemporaryTableCredentialResponse_Credentials_R2TempCredentials selects R2TempCredentials for GenerateTemporaryTableCredentialResponse.Credentials. +type GenerateTemporaryTableCredentialResponse_Credentials_R2TempCredentials struct { + R2TempCredentials R2Credentials +} + +func (*GenerateTemporaryTableCredentialResponse_Credentials_R2TempCredentials) isGenerateTemporaryTableCredentialResponse_Credentials() { +} + +// Generate volume credentials RPC. +type GenerateTemporaryVolumeCredentialRequest struct { + // Id of the volume to read or write. + VolumeId *string + // The operation performed against the volume data, either READ_VOLUME or + // WRITE_VOLUME. If WRITE_VOLUME is specified, the credentials returned will + // have write permissions, otherwise, it will be read only. + Operation VolumeOperation +} + +type GenerateTemporaryVolumeCredentialResponse struct { + // The temporary credential. + Credentials isGenerateTemporaryVolumeCredentialResponse_Credentials + // Server time when the credential will expire, in epoch milliseconds. The API + // client is advised to cache the credential given this expiration time. + ExpirationTime *int64 + // The URL of the storage path accessible by the temporary credential. + Url *string +} + +type isGenerateTemporaryVolumeCredentialResponse_Credentials interface { + isGenerateTemporaryVolumeCredentialResponse_Credentials() +} + +// GenerateTemporaryVolumeCredentialResponse_Credentials_AwsTempCredentials selects AwsTempCredentials for GenerateTemporaryVolumeCredentialResponse.Credentials. +type GenerateTemporaryVolumeCredentialResponse_Credentials_AwsTempCredentials struct { + AwsTempCredentials TemporaryAwsCredentials +} + +func (*GenerateTemporaryVolumeCredentialResponse_Credentials_AwsTempCredentials) isGenerateTemporaryVolumeCredentialResponse_Credentials() { +} + +// GenerateTemporaryVolumeCredentialResponse_Credentials_AzureUserDelegationSas selects AzureUserDelegationSas for GenerateTemporaryVolumeCredentialResponse.Credentials. +type GenerateTemporaryVolumeCredentialResponse_Credentials_AzureUserDelegationSas struct { + AzureUserDelegationSas AzureUserDelegationSas +} + +func (*GenerateTemporaryVolumeCredentialResponse_Credentials_AzureUserDelegationSas) isGenerateTemporaryVolumeCredentialResponse_Credentials() { +} + +// GenerateTemporaryVolumeCredentialResponse_Credentials_GcpOauthToken selects GcpOauthToken for GenerateTemporaryVolumeCredentialResponse.Credentials. +type GenerateTemporaryVolumeCredentialResponse_Credentials_GcpOauthToken struct { + GcpOauthToken GcpOauthToken +} + +func (*GenerateTemporaryVolumeCredentialResponse_Credentials_GcpOauthToken) isGenerateTemporaryVolumeCredentialResponse_Credentials() { +} + +// GenerateTemporaryVolumeCredentialResponse_Credentials_AzureAad selects AzureAad for GenerateTemporaryVolumeCredentialResponse.Credentials. +type GenerateTemporaryVolumeCredentialResponse_Credentials_AzureAad struct { + AzureAad AzureActiveDirectoryToken +} + +func (*GenerateTemporaryVolumeCredentialResponse_Credentials_AzureAad) isGenerateTemporaryVolumeCredentialResponse_Credentials() { +} + +// GenerateTemporaryVolumeCredentialResponse_Credentials_R2TempCredentials selects R2TempCredentials for GenerateTemporaryVolumeCredentialResponse.Credentials. +type GenerateTemporaryVolumeCredentialResponse_Credentials_R2TempCredentials struct { + R2TempCredentials R2Credentials +} + +func (*GenerateTemporaryVolumeCredentialResponse_Credentials_R2TempCredentials) isGenerateTemporaryVolumeCredentialResponse_Credentials() { +} + +type GetCredentialRequest struct { + // Name of the credential. + NameArg *string +} + +type GetCredentialsRequest struct { + // Credential configuration ID + CredentialsId *string + AccountId *string +} + +// TODO(UC-1710): The legacy /storage-credentials API is being deprecated. +// Please use the new consolidated /credentials API instead. See +// https://github.com/databricks-eng/universe/pull/857047#discussion_r1924779791 +// for an example of a case when that wasn't possible.. +type GetStorageCredentialRequest struct { + // Name of the storage credential. + NameArg *string +} + +type ListCredentialsPublicRequest struct { + AccountId *string +} + +// ListCredentialsRequest is used to list credentials in the metastore. Returns +// an array of credentials (as CredentialInfo objects). The array is limited to +// the credentials that the caller has permission to access. If the caller is a +// metastore admin, retrieval of credentials is unrestricted. +// +// There is no guarantee of a specific ordering of the elements in the array.. +type ListCredentialsRequest struct { + // Whether to include credentials not bound to the workspace. Effective only if + // the user has permission to update the credential–workspace binding. + IncludeUnbound *bool + // Maximum number of credentials to return. - If not set, the default max page + // size is used. - When set to a value greater than 0, the page length is the + // minimum of this value and a server-configured value. - When set to 0, the + // page length is set to a server-configured value (recommended). - When set to + // a value less than 0, an invalid parameter error is returned. + MaxResults *int + // Opaque token to retrieve the next page of results. + PageToken *string +} + +type ListCredentialsRequest_Response struct { + Credentials []CredentialInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type ListCredentialsResponse struct { + Credentials []Credentials +} + +type ListStorageCredentialsRequest struct { + // Whether to include credentials not bound to the workspace. Effective only if + // the user has permission to update the credential–workspace binding. + IncludeUnbound *bool + // Maximum number of storage credentials to return. If not set, all the storage + // credentials are returned (not recommended). - when set to a value greater + // than 0, the page length is the minimum of this value and a server configured + // value; - when set to 0, the page length is set to a server configured value + // (recommended); - when set to a value less than 0, an invalid parameter error + // is returned; + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListStorageCredentialsResponse struct { + StorageCredentials []StorageCredentialInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +// R2 temporary credentials for API authentication. Read more at +// https://developers.cloudflare.com/r2/api/s3/tokens/.. +type R2Credentials struct { + // The access key ID that identifies the temporary credentials. + AccessKeyId *string + // The secret access key associated with the access key. + SecretAccessKey *string + // The generated JWT that users must pass to use the temporary credentials. + SessionToken *string +} + +type StorageCredentialInfo struct { + // The credential name. The name must be unique among storage and service + // credentials within the metastore. + Name *string + // (--[Create:REQ, Update:OPT] The long-lived cloud credential.--) + Credential isStorageCredentialInfo_Credential + // Comment associated with the credential. + Comment *string + // Whether the credential is usable only for read operations. Only applicable + // when purpose is **STORAGE**. + ReadOnly *bool + // Username of current owner of credential. + Owner *string + // The unique identifier of the credential. + Id *string + // Unique identifier of the parent metastore. + MetastoreId *string + // Time at which this credential was created, in epoch milliseconds. + CreatedAt *int64 + // Username of credential creator. + CreatedBy *string + // Time at which this credential was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the credential. + UpdatedBy *string + // Whether this credential is the current metastore's root storage credential. + // Only applicable when purpose is **STORAGE**. + UsedForManagedStorage *bool + // The full name of the credential. + FullName *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode IsolationMode +} + +type isStorageCredentialInfo_Credential interface { + isStorageCredentialInfo_Credential() +} + +// StorageCredentialInfo_Credential_AwsIamRole selects AwsIamRole for StorageCredentialInfo.Credential. +// The AWS IAM role configuration. +type StorageCredentialInfo_Credential_AwsIamRole struct { + AwsIamRole AwsIamRole +} + +func (*StorageCredentialInfo_Credential_AwsIamRole) isStorageCredentialInfo_Credential() {} + +// StorageCredentialInfo_Credential_AzureServicePrincipal selects AzureServicePrincipal for StorageCredentialInfo.Credential. +// The Azure service principal configuration. +type StorageCredentialInfo_Credential_AzureServicePrincipal struct { + AzureServicePrincipal AzureServicePrincipal +} + +func (*StorageCredentialInfo_Credential_AzureServicePrincipal) isStorageCredentialInfo_Credential() {} + +// StorageCredentialInfo_Credential_GcpServiceAccountKey selects GcpServiceAccountKey for StorageCredentialInfo.Credential. +type StorageCredentialInfo_Credential_GcpServiceAccountKey struct { + GcpServiceAccountKey GcpServiceAccountKey +} + +func (*StorageCredentialInfo_Credential_GcpServiceAccountKey) isStorageCredentialInfo_Credential() {} + +// StorageCredentialInfo_Credential_AzureManagedIdentity selects AzureManagedIdentity for StorageCredentialInfo.Credential. +// The Azure managed identity configuration. +type StorageCredentialInfo_Credential_AzureManagedIdentity struct { + AzureManagedIdentity AzureManagedIdentity +} + +func (*StorageCredentialInfo_Credential_AzureManagedIdentity) isStorageCredentialInfo_Credential() {} + +// StorageCredentialInfo_Credential_DatabricksGcpServiceAccount selects DatabricksGcpServiceAccount for StorageCredentialInfo.Credential. +// The managed GCP service account configuration. +type StorageCredentialInfo_Credential_DatabricksGcpServiceAccount struct { + DatabricksGcpServiceAccount DatabricksGcpServiceAccount +} + +func (*StorageCredentialInfo_Credential_DatabricksGcpServiceAccount) isStorageCredentialInfo_Credential() { +} + +// StorageCredentialInfo_Credential_CloudflareApiToken selects CloudflareApiToken for StorageCredentialInfo.Credential. +// The Cloudflare API token configuration. +type StorageCredentialInfo_Credential_CloudflareApiToken struct { + CloudflareApiToken CloudflareApiToken +} + +func (*StorageCredentialInfo_Credential_CloudflareApiToken) isStorageCredentialInfo_Credential() {} + +// AWS temporary credentials for API authentication. Read more at +// https://docs.aws.amazon.com/STS/latest/APIReference/API_Credentials.html.. +type TemporaryAwsCredentials struct { + // The access key ID that identifies the temporary credentials. + AccessKeyId *string + // The secret access key that can be used to sign AWS API requests. + SecretAccessKey *string + // The token that users must pass to AWS API to use the temporary credentials. + SessionToken *string + // The Amazon Resource Name (ARN) of the S3 access point for temporary + // credentials related the external location. + AccessPoint *string +} + +type TemporaryCredentials struct { + // The temporary credential. + Credentials isTemporaryCredentials_Credentials + // Server time when the credential will expire, in epoch milliseconds. The API + // client is advised to cache the credential given this expiration time. + ExpirationTime *int64 + // The URL of the storage path accessible by the temporary credential. + Url *string +} + +type isTemporaryCredentials_Credentials interface { + isTemporaryCredentials_Credentials() +} + +// TemporaryCredentials_Credentials_AwsTempCredentials selects AwsTempCredentials for TemporaryCredentials.Credentials. +type TemporaryCredentials_Credentials_AwsTempCredentials struct { + AwsTempCredentials TemporaryAwsCredentials +} + +func (*TemporaryCredentials_Credentials_AwsTempCredentials) isTemporaryCredentials_Credentials() {} + +// TemporaryCredentials_Credentials_AzureUserDelegationSas selects AzureUserDelegationSas for TemporaryCredentials.Credentials. +type TemporaryCredentials_Credentials_AzureUserDelegationSas struct { + AzureUserDelegationSas AzureUserDelegationSas +} + +func (*TemporaryCredentials_Credentials_AzureUserDelegationSas) isTemporaryCredentials_Credentials() { +} + +// TemporaryCredentials_Credentials_GcpOauthToken selects GcpOauthToken for TemporaryCredentials.Credentials. +type TemporaryCredentials_Credentials_GcpOauthToken struct { + GcpOauthToken GcpOauthToken +} + +func (*TemporaryCredentials_Credentials_GcpOauthToken) isTemporaryCredentials_Credentials() {} + +// TemporaryCredentials_Credentials_AzureAad selects AzureAad for TemporaryCredentials.Credentials. +type TemporaryCredentials_Credentials_AzureAad struct { + AzureAad AzureActiveDirectoryToken +} + +func (*TemporaryCredentials_Credentials_AzureAad) isTemporaryCredentials_Credentials() {} + +// TemporaryCredentials_Credentials_R2TempCredentials selects R2TempCredentials for TemporaryCredentials.Credentials. +type TemporaryCredentials_Credentials_R2TempCredentials struct { + R2TempCredentials R2Credentials +} + +func (*TemporaryCredentials_Credentials_R2TempCredentials) isTemporaryCredentials_Credentials() {} + +type UpdateAccountsStorageCredential struct { + // The credential name. The name must be unique among storage and service + // credentials within the metastore. + Name *string + // (--[Create:REQ, Update:OPT] The long-lived cloud credential.--) + Credential isUpdateAccountsStorageCredential_Credential + // Comment associated with the credential. + Comment *string + // Whether the credential is usable only for read operations. Only applicable + // when purpose is **STORAGE**. + ReadOnly *bool + // Username of current owner of credential. + Owner *string + // The unique identifier of the credential. + Id *string + // Unique identifier of the parent metastore. + MetastoreId *string + // Time at which this credential was created, in epoch milliseconds. + CreatedAt *int64 + // Username of credential creator. + CreatedBy *string + // Time at which this credential was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the credential. + UpdatedBy *string + // Whether this credential is the current metastore's root storage credential. + // Only applicable when purpose is **STORAGE**. + UsedForManagedStorage *bool + // The full name of the credential. + FullName *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode IsolationMode +} + +type isUpdateAccountsStorageCredential_Credential interface { + isUpdateAccountsStorageCredential_Credential() +} + +// UpdateAccountsStorageCredential_Credential_AwsIamRole selects AwsIamRole for UpdateAccountsStorageCredential.Credential. +// The AWS IAM role configuration. +type UpdateAccountsStorageCredential_Credential_AwsIamRole struct { + AwsIamRole AwsIamRole +} + +func (*UpdateAccountsStorageCredential_Credential_AwsIamRole) isUpdateAccountsStorageCredential_Credential() { +} + +// UpdateAccountsStorageCredential_Credential_AzureServicePrincipal selects AzureServicePrincipal for UpdateAccountsStorageCredential.Credential. +// The Azure service principal configuration. +type UpdateAccountsStorageCredential_Credential_AzureServicePrincipal struct { + AzureServicePrincipal AzureServicePrincipal +} + +func (*UpdateAccountsStorageCredential_Credential_AzureServicePrincipal) isUpdateAccountsStorageCredential_Credential() { +} + +// UpdateAccountsStorageCredential_Credential_GcpServiceAccountKey selects GcpServiceAccountKey for UpdateAccountsStorageCredential.Credential. +type UpdateAccountsStorageCredential_Credential_GcpServiceAccountKey struct { + GcpServiceAccountKey GcpServiceAccountKey +} + +func (*UpdateAccountsStorageCredential_Credential_GcpServiceAccountKey) isUpdateAccountsStorageCredential_Credential() { +} + +// UpdateAccountsStorageCredential_Credential_AzureManagedIdentity selects AzureManagedIdentity for UpdateAccountsStorageCredential.Credential. +// The Azure managed identity configuration. +type UpdateAccountsStorageCredential_Credential_AzureManagedIdentity struct { + AzureManagedIdentity AzureManagedIdentity +} + +func (*UpdateAccountsStorageCredential_Credential_AzureManagedIdentity) isUpdateAccountsStorageCredential_Credential() { +} + +// UpdateAccountsStorageCredential_Credential_DatabricksGcpServiceAccount selects DatabricksGcpServiceAccount for UpdateAccountsStorageCredential.Credential. +// The managed GCP service account configuration. +type UpdateAccountsStorageCredential_Credential_DatabricksGcpServiceAccount struct { + DatabricksGcpServiceAccount DatabricksGcpServiceAccount +} + +func (*UpdateAccountsStorageCredential_Credential_DatabricksGcpServiceAccount) isUpdateAccountsStorageCredential_Credential() { +} + +// UpdateAccountsStorageCredential_Credential_CloudflareApiToken selects CloudflareApiToken for UpdateAccountsStorageCredential.Credential. +// The Cloudflare API token configuration. +type UpdateAccountsStorageCredential_Credential_CloudflareApiToken struct { + CloudflareApiToken CloudflareApiToken +} + +func (*UpdateAccountsStorageCredential_Credential_CloudflareApiToken) isUpdateAccountsStorageCredential_Credential() { +} + +type UpdateCredentialRequest struct { + // Name of the credential. + NameArg *string + // New name of credential. + NewName *string + // Supply true to this argument to skip validation of the updated credential. + SkipValidation *bool + // Force an update even if there are dependent services (when purpose is + // **SERVICE**) or dependent external locations and external tables (when + // purpose is **STORAGE**). + Force *bool + // The credential name. The name must be unique among storage and service + // credentials within the metastore. + Name *string + // (--[Create:REQ, Update:OPT] The long-lived cloud credential.--) + Credential isUpdateCredentialRequest_Credential + // Comment associated with the credential. + Comment *string + // Whether the credential is usable only for read operations. Only applicable + // when purpose is **STORAGE**. + ReadOnly *bool + // Username of current owner of credential. + Owner *string + // The unique identifier of the credential. + Id *string + // Unique identifier of the parent metastore. + MetastoreId *string + // Time at which this credential was created, in epoch milliseconds. + CreatedAt *int64 + // Username of credential creator. + CreatedBy *string + // Time at which this credential was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the credential. + UpdatedBy *string + // Whether this credential is the current metastore's root storage credential. + // Only applicable when purpose is **STORAGE**. + UsedForManagedStorage *bool + // The full name of the credential. + FullName *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode IsolationMode +} + +type isUpdateCredentialRequest_Credential interface { + isUpdateCredentialRequest_Credential() +} + +// UpdateCredentialRequest_Credential_AwsIamRole selects AwsIamRole for UpdateCredentialRequest.Credential. +// The AWS IAM role configuration. +type UpdateCredentialRequest_Credential_AwsIamRole struct { + AwsIamRole AwsIamRole +} + +func (*UpdateCredentialRequest_Credential_AwsIamRole) isUpdateCredentialRequest_Credential() {} + +// UpdateCredentialRequest_Credential_AzureServicePrincipal selects AzureServicePrincipal for UpdateCredentialRequest.Credential. +// The Azure service principal configuration. +type UpdateCredentialRequest_Credential_AzureServicePrincipal struct { + AzureServicePrincipal AzureServicePrincipal +} + +func (*UpdateCredentialRequest_Credential_AzureServicePrincipal) isUpdateCredentialRequest_Credential() { +} + +// UpdateCredentialRequest_Credential_GcpServiceAccountKey selects GcpServiceAccountKey for UpdateCredentialRequest.Credential. +type UpdateCredentialRequest_Credential_GcpServiceAccountKey struct { + GcpServiceAccountKey GcpServiceAccountKey +} + +func (*UpdateCredentialRequest_Credential_GcpServiceAccountKey) isUpdateCredentialRequest_Credential() { +} + +// UpdateCredentialRequest_Credential_AzureManagedIdentity selects AzureManagedIdentity for UpdateCredentialRequest.Credential. +// The Azure managed identity configuration. +type UpdateCredentialRequest_Credential_AzureManagedIdentity struct { + AzureManagedIdentity AzureManagedIdentity +} + +func (*UpdateCredentialRequest_Credential_AzureManagedIdentity) isUpdateCredentialRequest_Credential() { +} + +// UpdateCredentialRequest_Credential_DatabricksGcpServiceAccount selects DatabricksGcpServiceAccount for UpdateCredentialRequest.Credential. +// The managed GCP service account configuration. +type UpdateCredentialRequest_Credential_DatabricksGcpServiceAccount struct { + DatabricksGcpServiceAccount DatabricksGcpServiceAccount +} + +func (*UpdateCredentialRequest_Credential_DatabricksGcpServiceAccount) isUpdateCredentialRequest_Credential() { +} + +// UpdateCredentialRequest_Credential_CloudflareApiToken selects CloudflareApiToken for UpdateCredentialRequest.Credential. +// The Cloudflare API token configuration. +type UpdateCredentialRequest_Credential_CloudflareApiToken struct { + CloudflareApiToken CloudflareApiToken +} + +func (*UpdateCredentialRequest_Credential_CloudflareApiToken) isUpdateCredentialRequest_Credential() { +} + +type UpdateStorageCredentialRequest struct { + // Name of the storage credential. + NameArg *string + // New name for the storage credential. + NewName *string + // Supplying true to this argument skips validation of the updated credential. + SkipValidation *bool + // Force update even if there are dependent external locations or external + // tables. + Force *bool + // The credential name. The name must be unique among storage and service + // credentials within the metastore. + Name *string + // (--[Create:REQ, Update:OPT] The long-lived cloud credential.--) + Credential isUpdateStorageCredentialRequest_Credential + // Comment associated with the credential. + Comment *string + // Whether the credential is usable only for read operations. Only applicable + // when purpose is **STORAGE**. + ReadOnly *bool + // Username of current owner of credential. + Owner *string + // The unique identifier of the credential. + Id *string + // Unique identifier of the parent metastore. + MetastoreId *string + // Time at which this credential was created, in epoch milliseconds. + CreatedAt *int64 + // Username of credential creator. + CreatedBy *string + // Time at which this credential was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the credential. + UpdatedBy *string + // Whether this credential is the current metastore's root storage credential. + // Only applicable when purpose is **STORAGE**. + UsedForManagedStorage *bool + // The full name of the credential. + FullName *string + // Whether the current securable is accessible from all workspaces or a specific + // set of workspaces. + IsolationMode IsolationMode +} + +type isUpdateStorageCredentialRequest_Credential interface { + isUpdateStorageCredentialRequest_Credential() +} + +// UpdateStorageCredentialRequest_Credential_AwsIamRole selects AwsIamRole for UpdateStorageCredentialRequest.Credential. +// The AWS IAM role configuration. +type UpdateStorageCredentialRequest_Credential_AwsIamRole struct { + AwsIamRole AwsIamRole +} + +func (*UpdateStorageCredentialRequest_Credential_AwsIamRole) isUpdateStorageCredentialRequest_Credential() { +} + +// UpdateStorageCredentialRequest_Credential_AzureServicePrincipal selects AzureServicePrincipal for UpdateStorageCredentialRequest.Credential. +// The Azure service principal configuration. +type UpdateStorageCredentialRequest_Credential_AzureServicePrincipal struct { + AzureServicePrincipal AzureServicePrincipal +} + +func (*UpdateStorageCredentialRequest_Credential_AzureServicePrincipal) isUpdateStorageCredentialRequest_Credential() { +} + +// UpdateStorageCredentialRequest_Credential_GcpServiceAccountKey selects GcpServiceAccountKey for UpdateStorageCredentialRequest.Credential. +type UpdateStorageCredentialRequest_Credential_GcpServiceAccountKey struct { + GcpServiceAccountKey GcpServiceAccountKey +} + +func (*UpdateStorageCredentialRequest_Credential_GcpServiceAccountKey) isUpdateStorageCredentialRequest_Credential() { +} + +// UpdateStorageCredentialRequest_Credential_AzureManagedIdentity selects AzureManagedIdentity for UpdateStorageCredentialRequest.Credential. +// The Azure managed identity configuration. +type UpdateStorageCredentialRequest_Credential_AzureManagedIdentity struct { + AzureManagedIdentity AzureManagedIdentity +} + +func (*UpdateStorageCredentialRequest_Credential_AzureManagedIdentity) isUpdateStorageCredentialRequest_Credential() { +} + +// UpdateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount selects DatabricksGcpServiceAccount for UpdateStorageCredentialRequest.Credential. +// The managed GCP service account configuration. +type UpdateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount struct { + DatabricksGcpServiceAccount DatabricksGcpServiceAccount +} + +func (*UpdateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount) isUpdateStorageCredentialRequest_Credential() { +} + +// UpdateStorageCredentialRequest_Credential_CloudflareApiToken selects CloudflareApiToken for UpdateStorageCredentialRequest.Credential. +// The Cloudflare API token configuration. +type UpdateStorageCredentialRequest_Credential_CloudflareApiToken struct { + CloudflareApiToken CloudflareApiToken +} + +func (*UpdateStorageCredentialRequest_Credential_CloudflareApiToken) isUpdateStorageCredentialRequest_Credential() { +} + +type ValidateCredentialRequest struct { + Credential isValidateCredentialRequest_Credential + // The name of an existing external location to validate. Only applicable for + // storage credentials (purpose is **STORAGE**.) + ExternalLocationName *string + // The external location url to validate. Only applicable when purpose is + // **STORAGE**. + Url *string + // Whether the credential is only usable for read operations. Only applicable + // for storage credentials (purpose is **STORAGE**.) + ReadOnly *bool +} + +type isValidateCredentialRequest_Credential interface { + isValidateCredentialRequest_Credential() +} + +// ValidateCredentialRequest_Credential_CredentialName selects CredentialName for ValidateCredentialRequest.Credential. +// Required. The name of an existing credential or long-lived cloud credential +// to validate. +type ValidateCredentialRequest_Credential_CredentialName struct { + CredentialName string +} + +func (*ValidateCredentialRequest_Credential_CredentialName) isValidateCredentialRequest_Credential() { +} + +// ValidateCredentialRequest_Credential_AwsIamRole selects AwsIamRole for ValidateCredentialRequest.Credential. +type ValidateCredentialRequest_Credential_AwsIamRole struct { + AwsIamRole AwsIamRole +} + +func (*ValidateCredentialRequest_Credential_AwsIamRole) isValidateCredentialRequest_Credential() {} + +// ValidateCredentialRequest_Credential_AzureManagedIdentity selects AzureManagedIdentity for ValidateCredentialRequest.Credential. +type ValidateCredentialRequest_Credential_AzureManagedIdentity struct { + AzureManagedIdentity AzureManagedIdentity +} + +func (*ValidateCredentialRequest_Credential_AzureManagedIdentity) isValidateCredentialRequest_Credential() { +} + +// ValidateCredentialRequest_Credential_DatabricksGcpServiceAccount selects DatabricksGcpServiceAccount for ValidateCredentialRequest.Credential. +type ValidateCredentialRequest_Credential_DatabricksGcpServiceAccount struct { + DatabricksGcpServiceAccount DatabricksGcpServiceAccount +} + +func (*ValidateCredentialRequest_Credential_DatabricksGcpServiceAccount) isValidateCredentialRequest_Credential() { +} + +type ValidateCredentialRequest_ValidationResult struct { + // The results of the tested operation. + Result ValidateCredentialRequest_Result + // Error message would exist when the result does not equal to **PASS**. + Message *string +} + +type ValidateCredentialResponse struct { + // The results of the validation check. + Results []ValidateCredentialRequest_ValidationResult + // Whether the tested location is a directory in cloud storage. Only applicable + // for when purpose is **STORAGE**. + IsDir *bool +} + +type ValidateStorageCredentialRequest struct { + Credential isValidateStorageCredentialRequest_Credential + // The name of an existing external location to validate. + ExternalLocationName *string + // The external location url to validate. + Url *string + // Whether the storage credential is only usable for read operations. + ReadOnly *bool +} + +type isValidateStorageCredentialRequest_Credential interface { + isValidateStorageCredentialRequest_Credential() +} + +// ValidateStorageCredentialRequest_Credential_StorageCredentialName selects StorageCredentialName for ValidateStorageCredentialRequest.Credential. +// Required. The name of an existing credential or long-lived cloud credential +// to validate. +type ValidateStorageCredentialRequest_Credential_StorageCredentialName struct { + StorageCredentialName string +} + +func (*ValidateStorageCredentialRequest_Credential_StorageCredentialName) isValidateStorageCredentialRequest_Credential() { +} + +// ValidateStorageCredentialRequest_Credential_AwsIamRole selects AwsIamRole for ValidateStorageCredentialRequest.Credential. +// The AWS IAM role configuration. +type ValidateStorageCredentialRequest_Credential_AwsIamRole struct { + AwsIamRole AwsIamRole +} + +func (*ValidateStorageCredentialRequest_Credential_AwsIamRole) isValidateStorageCredentialRequest_Credential() { +} + +// ValidateStorageCredentialRequest_Credential_AzureServicePrincipal selects AzureServicePrincipal for ValidateStorageCredentialRequest.Credential. +// The Azure service principal configuration. +type ValidateStorageCredentialRequest_Credential_AzureServicePrincipal struct { + AzureServicePrincipal AzureServicePrincipal +} + +func (*ValidateStorageCredentialRequest_Credential_AzureServicePrincipal) isValidateStorageCredentialRequest_Credential() { +} + +// ValidateStorageCredentialRequest_Credential_AzureManagedIdentity selects AzureManagedIdentity for ValidateStorageCredentialRequest.Credential. +// The Azure managed identity configuration. +type ValidateStorageCredentialRequest_Credential_AzureManagedIdentity struct { + AzureManagedIdentity AzureManagedIdentity +} + +func (*ValidateStorageCredentialRequest_Credential_AzureManagedIdentity) isValidateStorageCredentialRequest_Credential() { +} + +// ValidateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount selects DatabricksGcpServiceAccount for ValidateStorageCredentialRequest.Credential. +// The created GCP service account configuration. +type ValidateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount struct { + DatabricksGcpServiceAccount DatabricksGcpServiceAccount +} + +func (*ValidateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount) isValidateStorageCredentialRequest_Credential() { +} + +// ValidateStorageCredentialRequest_Credential_CloudflareApiToken selects CloudflareApiToken for ValidateStorageCredentialRequest.Credential. +// The Cloudflare API token configuration. +type ValidateStorageCredentialRequest_Credential_CloudflareApiToken struct { + CloudflareApiToken CloudflareApiToken +} + +func (*ValidateStorageCredentialRequest_Credential_CloudflareApiToken) isValidateStorageCredentialRequest_Credential() { +} + +type ValidateStorageCredentialRequest_ValidationResult struct { + // The operation tested. + Operation ValidateStorageCredentialRequest_FileOperation + // The results of the tested operation. + Result ValidateStorageCredentialRequest_Result + // Error message would exist when the result does not equal to **PASS**. + Message *string +} + +type ValidateStorageCredentialResponse struct { + // Whether the tested location is a directory in cloud storage. + IsDir *bool + // The results of the validation check. + Results []ValidateStorageCredentialRequest_ValidationResult +} diff --git a/uc/credentials/v1/wire.go b/uc/credentials/v1/wire.go new file mode 100755 index 0000000..3285290 --- /dev/null +++ b/uc/credentials/v1/wire.go @@ -0,0 +1,2147 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package credentials + +import ( + "fmt" +) + +type accountsCreateStorageCredentialRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CredentialInfo *createAccountsStorageCredentialWire `json:"credential_info,omitempty"` + SkipValidation *bool `json:"skip_validation,omitempty"` +} + +func accountsCreateStorageCredentialRequestToWire(v *AccountsCreateStorageCredentialRequest) (*accountsCreateStorageCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + credentialInfoWireValue, err := createAccountsStorageCredentialToWire(v.CredentialInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsCreateStorageCredentialRequest.CredentialInfo", err) + } + return &accountsCreateStorageCredentialRequestWire{ + AccountId: v.AccountId, + MetastoreId: v.MetastoreId, + CredentialInfo: credentialInfoWireValue, + SkipValidation: v.SkipValidation, + }, nil +} + +type accountsCreateStorageCredentialResponseWire struct { + CredentialInfo *storageCredentialInfoWire `json:"credential_info,omitempty"` +} + +func accountsCreateStorageCredentialResponseFromWire(w *accountsCreateStorageCredentialResponseWire) (*AccountsCreateStorageCredentialResponse, error) { + if w == nil { + return nil, nil + } + credentialInfoPublicValue, err := storageCredentialInfoFromWire(w.CredentialInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsCreateStorageCredentialResponse.CredentialInfo", err) + } + return &AccountsCreateStorageCredentialResponse{ + CredentialInfo: credentialInfoPublicValue, + }, nil +} + +type accountsDeleteStorageCredentialRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + NameArg *string `json:"name_arg,omitempty"` + Force *bool `json:"force,omitempty"` +} + +func accountsDeleteStorageCredentialRequestToWire(v *AccountsDeleteStorageCredentialRequest) (*accountsDeleteStorageCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + return &accountsDeleteStorageCredentialRequestWire{ + AccountId: v.AccountId, + MetastoreId: v.MetastoreId, + NameArg: v.NameArg, + Force: v.Force, + }, nil +} + +type accountsGetStorageCredentialResponseWire struct { + CredentialInfo *storageCredentialInfoWire `json:"credential_info,omitempty"` +} + +func accountsGetStorageCredentialResponseFromWire(w *accountsGetStorageCredentialResponseWire) (*AccountsGetStorageCredentialResponse, error) { + if w == nil { + return nil, nil + } + credentialInfoPublicValue, err := storageCredentialInfoFromWire(w.CredentialInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsGetStorageCredentialResponse.CredentialInfo", err) + } + return &AccountsGetStorageCredentialResponse{ + CredentialInfo: credentialInfoPublicValue, + }, nil +} + +type accountsListStorageCredentialsResponseWire struct { + StorageCredentials []storageCredentialInfoWire `json:"storage_credentials,omitempty"` +} + +func accountsListStorageCredentialsResponseFromWire(w *accountsListStorageCredentialsResponseWire) (*AccountsListStorageCredentialsResponse, error) { + if w == nil { + return nil, nil + } + storageCredentialsPublicValue, err := convertSlice(w.StorageCredentials, storageCredentialInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsListStorageCredentialsResponse.StorageCredentials", err) + } + return &AccountsListStorageCredentialsResponse{ + StorageCredentials: storageCredentialsPublicValue, + }, nil +} + +type accountsUpdateStorageCredentialRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + NameArg *string `json:"name_arg,omitempty"` + CredentialInfo *updateAccountsStorageCredentialWire `json:"credential_info,omitempty"` + SkipValidation *bool `json:"skip_validation,omitempty"` +} + +func accountsUpdateStorageCredentialRequestToWire(v *AccountsUpdateStorageCredentialRequest) (*accountsUpdateStorageCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + credentialInfoWireValue, err := updateAccountsStorageCredentialToWire(v.CredentialInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsUpdateStorageCredentialRequest.CredentialInfo", err) + } + return &accountsUpdateStorageCredentialRequestWire{ + AccountId: v.AccountId, + MetastoreId: v.MetastoreId, + NameArg: v.NameArg, + CredentialInfo: credentialInfoWireValue, + SkipValidation: v.SkipValidation, + }, nil +} + +type accountsUpdateStorageCredentialResponseWire struct { + CredentialInfo *storageCredentialInfoWire `json:"credential_info,omitempty"` +} + +func accountsUpdateStorageCredentialResponseFromWire(w *accountsUpdateStorageCredentialResponseWire) (*AccountsUpdateStorageCredentialResponse, error) { + if w == nil { + return nil, nil + } + credentialInfoPublicValue, err := storageCredentialInfoFromWire(w.CredentialInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsUpdateStorageCredentialResponse.CredentialInfo", err) + } + return &AccountsUpdateStorageCredentialResponse{ + CredentialInfo: credentialInfoPublicValue, + }, nil +} + +type awsCredentialsWire struct { + StsRole *awsCredentials_StsRoleWire `json:"sts_role,omitempty"` +} + +func awsCredentialsFromWire(w *awsCredentialsWire) (*AwsCredentials, error) { + if w == nil { + return nil, nil + } + credsMembers := 0 + if w.StsRole != nil { + credsMembers++ + } + if credsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "AwsCredentials.Creds") + } + var credsSelection isAwsCredentials_Creds + switch { + case w.StsRole != nil: + credsStsRoleConverted, err := awsCredentials_StsRoleFromWire(w.StsRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AwsCredentials.Creds.StsRole", err) + } + credsSelection = &AwsCredentials_Creds_StsRole{StsRole: *credsStsRoleConverted} + } + return &AwsCredentials{ + Creds: credsSelection, + }, nil +} + +type awsCredentials_StsRoleWire struct { + RoleArn *string `json:"role_arn,omitempty"` +} + +func awsCredentials_StsRoleToWire(v *AwsCredentials_StsRole) (*awsCredentials_StsRoleWire, error) { + if v == nil { + return nil, nil + } + return &awsCredentials_StsRoleWire{ + RoleArn: v.RoleArn, + }, nil +} + +func awsCredentials_StsRoleFromWire(w *awsCredentials_StsRoleWire) (*AwsCredentials_StsRole, error) { + if w == nil { + return nil, nil + } + return &AwsCredentials_StsRole{ + RoleArn: w.RoleArn, + }, nil +} + +type awsIamRoleWire struct { + RoleArn *string `json:"role_arn,omitempty"` + UnityCatalogIamArn *string `json:"unity_catalog_iam_arn,omitempty"` + ExternalId *string `json:"external_id,omitempty"` +} + +func awsIamRoleToWire(v *AwsIamRole) (*awsIamRoleWire, error) { + if v == nil { + return nil, nil + } + return &awsIamRoleWire{ + RoleArn: v.RoleArn, + UnityCatalogIamArn: v.UnityCatalogIamArn, + ExternalId: v.ExternalId, + }, nil +} + +func awsIamRoleFromWire(w *awsIamRoleWire) (*AwsIamRole, error) { + if w == nil { + return nil, nil + } + return &AwsIamRole{ + RoleArn: w.RoleArn, + UnityCatalogIamArn: w.UnityCatalogIamArn, + ExternalId: w.ExternalId, + }, nil +} + +type azureActiveDirectoryTokenWire struct { + AadToken *string `json:"aad_token,omitempty"` +} + +func azureActiveDirectoryTokenFromWire(w *azureActiveDirectoryTokenWire) (*AzureActiveDirectoryToken, error) { + if w == nil { + return nil, nil + } + return &AzureActiveDirectoryToken{ + AadToken: w.AadToken, + }, nil +} + +type azureManagedIdentityWire struct { + AccessConnectorId *string `json:"access_connector_id,omitempty"` + ManagedIdentityId *string `json:"managed_identity_id,omitempty"` + CredentialId *string `json:"credential_id,omitempty"` +} + +func azureManagedIdentityToWire(v *AzureManagedIdentity) (*azureManagedIdentityWire, error) { + if v == nil { + return nil, nil + } + return &azureManagedIdentityWire{ + AccessConnectorId: v.AccessConnectorId, + ManagedIdentityId: v.ManagedIdentityId, + CredentialId: v.CredentialId, + }, nil +} + +func azureManagedIdentityFromWire(w *azureManagedIdentityWire) (*AzureManagedIdentity, error) { + if w == nil { + return nil, nil + } + return &AzureManagedIdentity{ + AccessConnectorId: w.AccessConnectorId, + ManagedIdentityId: w.ManagedIdentityId, + CredentialId: w.CredentialId, + }, nil +} + +type azureServicePrincipalWire struct { + DirectoryId *string `json:"directory_id,omitempty"` + ApplicationId *string `json:"application_id,omitempty"` + ClientSecret *string `json:"client_secret,omitempty"` +} + +func azureServicePrincipalToWire(v *AzureServicePrincipal) (*azureServicePrincipalWire, error) { + if v == nil { + return nil, nil + } + return &azureServicePrincipalWire{ + DirectoryId: v.DirectoryId, + ApplicationId: v.ApplicationId, + ClientSecret: v.ClientSecret, + }, nil +} + +func azureServicePrincipalFromWire(w *azureServicePrincipalWire) (*AzureServicePrincipal, error) { + if w == nil { + return nil, nil + } + return &AzureServicePrincipal{ + DirectoryId: w.DirectoryId, + ApplicationId: w.ApplicationId, + ClientSecret: w.ClientSecret, + }, nil +} + +type azureUserDelegationSasWire struct { + SasToken *string `json:"sas_token,omitempty"` +} + +func azureUserDelegationSasFromWire(w *azureUserDelegationSasWire) (*AzureUserDelegationSas, error) { + if w == nil { + return nil, nil + } + return &AzureUserDelegationSas{ + SasToken: w.SasToken, + }, nil +} + +type cloudflareApiTokenWire struct { + AccessKeyId *string `json:"access_key_id,omitempty"` + SecretAccessKey *string `json:"secret_access_key,omitempty"` + AccountId *string `json:"account_id,omitempty"` +} + +func cloudflareApiTokenToWire(v *CloudflareApiToken) (*cloudflareApiTokenWire, error) { + if v == nil { + return nil, nil + } + return &cloudflareApiTokenWire{ + AccessKeyId: v.AccessKeyId, + SecretAccessKey: v.SecretAccessKey, + AccountId: v.AccountId, + }, nil +} + +func cloudflareApiTokenFromWire(w *cloudflareApiTokenWire) (*CloudflareApiToken, error) { + if w == nil { + return nil, nil + } + return &CloudflareApiToken{ + AccessKeyId: w.AccessKeyId, + SecretAccessKey: w.SecretAccessKey, + AccountId: w.AccountId, + }, nil +} + +type createAccountsStorageCredentialWire struct { + Name *string `json:"name,omitempty"` + AwsIamRole *awsIamRoleWire `json:"aws_iam_role,omitempty"` + AzureServicePrincipal *azureServicePrincipalWire `json:"azure_service_principal,omitempty"` + GcpServiceAccountKey *gcpServiceAccountKeyWire `json:"gcp_service_account_key,omitempty"` + AzureManagedIdentity *azureManagedIdentityWire `json:"azure_managed_identity,omitempty"` + DatabricksGcpServiceAccount *databricksGcpServiceAccountWire `json:"databricks_gcp_service_account,omitempty"` + CloudflareApiToken *cloudflareApiTokenWire `json:"cloudflare_api_token,omitempty"` + Comment *string `json:"comment,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Owner *string `json:"owner,omitempty"` + Id *string `json:"id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + UsedForManagedStorage *bool `json:"used_for_managed_storage,omitempty"` + FullName *string `json:"full_name,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` +} + +func createAccountsStorageCredentialToWire(v *CreateAccountsStorageCredential) (*createAccountsStorageCredentialWire, error) { + if v == nil { + return nil, nil + } + var credentialAwsIamRoleWire *awsIamRoleWire + var credentialAzureServicePrincipalWire *azureServicePrincipalWire + var credentialGcpServiceAccountKeyWire *gcpServiceAccountKeyWire + var credentialAzureManagedIdentityWire *azureManagedIdentityWire + var credentialDatabricksGcpServiceAccountWire *databricksGcpServiceAccountWire + var credentialCloudflareApiTokenWire *cloudflareApiTokenWire + switch value := v.Credential.(type) { + case nil: + case *CreateAccountsStorageCredential_Credential_AwsIamRole: + if value != nil { + credentialAwsIamRoleConverted, err := awsIamRoleToWire(&value.AwsIamRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountsStorageCredential.Credential.AwsIamRole", err) + } + credentialAwsIamRoleWire = credentialAwsIamRoleConverted + } + case *CreateAccountsStorageCredential_Credential_AzureServicePrincipal: + if value != nil { + credentialAzureServicePrincipalConverted, err := azureServicePrincipalToWire(&value.AzureServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountsStorageCredential.Credential.AzureServicePrincipal", err) + } + credentialAzureServicePrincipalWire = credentialAzureServicePrincipalConverted + } + case *CreateAccountsStorageCredential_Credential_GcpServiceAccountKey: + if value != nil { + credentialGcpServiceAccountKeyConverted, err := gcpServiceAccountKeyToWire(&value.GcpServiceAccountKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountsStorageCredential.Credential.GcpServiceAccountKey", err) + } + credentialGcpServiceAccountKeyWire = credentialGcpServiceAccountKeyConverted + } + case *CreateAccountsStorageCredential_Credential_AzureManagedIdentity: + if value != nil { + credentialAzureManagedIdentityConverted, err := azureManagedIdentityToWire(&value.AzureManagedIdentity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountsStorageCredential.Credential.AzureManagedIdentity", err) + } + credentialAzureManagedIdentityWire = credentialAzureManagedIdentityConverted + } + case *CreateAccountsStorageCredential_Credential_DatabricksGcpServiceAccount: + if value != nil { + credentialDatabricksGcpServiceAccountConverted, err := databricksGcpServiceAccountToWire(&value.DatabricksGcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountsStorageCredential.Credential.DatabricksGcpServiceAccount", err) + } + credentialDatabricksGcpServiceAccountWire = credentialDatabricksGcpServiceAccountConverted + } + case *CreateAccountsStorageCredential_Credential_CloudflareApiToken: + if value != nil { + credentialCloudflareApiTokenConverted, err := cloudflareApiTokenToWire(&value.CloudflareApiToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccountsStorageCredential.Credential.CloudflareApiToken", err) + } + credentialCloudflareApiTokenWire = credentialCloudflareApiTokenConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreateAccountsStorageCredential.Credential", value) + } + return &createAccountsStorageCredentialWire{ + Name: v.Name, + AwsIamRole: credentialAwsIamRoleWire, + AzureServicePrincipal: credentialAzureServicePrincipalWire, + GcpServiceAccountKey: credentialGcpServiceAccountKeyWire, + AzureManagedIdentity: credentialAzureManagedIdentityWire, + DatabricksGcpServiceAccount: credentialDatabricksGcpServiceAccountWire, + CloudflareApiToken: credentialCloudflareApiTokenWire, + Comment: v.Comment, + ReadOnly: v.ReadOnly, + Owner: v.Owner, + Id: v.Id, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + UsedForManagedStorage: v.UsedForManagedStorage, + FullName: v.FullName, + IsolationMode: v.IsolationMode, + }, nil +} + +type createCredentialAwsCredentialsWire struct { + StsRole *awsCredentials_StsRoleWire `json:"sts_role,omitempty"` +} + +func createCredentialAwsCredentialsToWire(v *CreateCredentialAwsCredentials) (*createCredentialAwsCredentialsWire, error) { + if v == nil { + return nil, nil + } + var credsStsRoleWire *awsCredentials_StsRoleWire + switch value := v.Creds.(type) { + case nil: + case *CreateCredentialAwsCredentials_Creds_StsRole: + if value != nil { + credsStsRoleConverted, err := awsCredentials_StsRoleToWire(&value.StsRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCredentialAwsCredentials.Creds.StsRole", err) + } + credsStsRoleWire = credsStsRoleConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreateCredentialAwsCredentials.Creds", value) + } + return &createCredentialAwsCredentialsWire{ + StsRole: credsStsRoleWire, + }, nil +} + +type createCredentialRequestWire struct { + SkipValidation *bool `json:"skip_validation,omitempty"` + Name *string `json:"name,omitempty"` + AwsIamRole *awsIamRoleWire `json:"aws_iam_role,omitempty"` + AzureServicePrincipal *azureServicePrincipalWire `json:"azure_service_principal,omitempty"` + GcpServiceAccountKey *gcpServiceAccountKeyWire `json:"gcp_service_account_key,omitempty"` + AzureManagedIdentity *azureManagedIdentityWire `json:"azure_managed_identity,omitempty"` + DatabricksGcpServiceAccount *databricksGcpServiceAccountWire `json:"databricks_gcp_service_account,omitempty"` + CloudflareApiToken *cloudflareApiTokenWire `json:"cloudflare_api_token,omitempty"` + Comment *string `json:"comment,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Owner *string `json:"owner,omitempty"` + Id *string `json:"id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + UsedForManagedStorage *bool `json:"used_for_managed_storage,omitempty"` + FullName *string `json:"full_name,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` +} + +func createCredentialRequestToWire(v *CreateCredentialRequest) (*createCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + var credentialAwsIamRoleWire *awsIamRoleWire + var credentialAzureServicePrincipalWire *azureServicePrincipalWire + var credentialGcpServiceAccountKeyWire *gcpServiceAccountKeyWire + var credentialAzureManagedIdentityWire *azureManagedIdentityWire + var credentialDatabricksGcpServiceAccountWire *databricksGcpServiceAccountWire + var credentialCloudflareApiTokenWire *cloudflareApiTokenWire + switch value := v.Credential.(type) { + case nil: + case *CreateCredentialRequest_Credential_AwsIamRole: + if value != nil { + credentialAwsIamRoleConverted, err := awsIamRoleToWire(&value.AwsIamRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCredentialRequest.Credential.AwsIamRole", err) + } + credentialAwsIamRoleWire = credentialAwsIamRoleConverted + } + case *CreateCredentialRequest_Credential_AzureServicePrincipal: + if value != nil { + credentialAzureServicePrincipalConverted, err := azureServicePrincipalToWire(&value.AzureServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCredentialRequest.Credential.AzureServicePrincipal", err) + } + credentialAzureServicePrincipalWire = credentialAzureServicePrincipalConverted + } + case *CreateCredentialRequest_Credential_GcpServiceAccountKey: + if value != nil { + credentialGcpServiceAccountKeyConverted, err := gcpServiceAccountKeyToWire(&value.GcpServiceAccountKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCredentialRequest.Credential.GcpServiceAccountKey", err) + } + credentialGcpServiceAccountKeyWire = credentialGcpServiceAccountKeyConverted + } + case *CreateCredentialRequest_Credential_AzureManagedIdentity: + if value != nil { + credentialAzureManagedIdentityConverted, err := azureManagedIdentityToWire(&value.AzureManagedIdentity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCredentialRequest.Credential.AzureManagedIdentity", err) + } + credentialAzureManagedIdentityWire = credentialAzureManagedIdentityConverted + } + case *CreateCredentialRequest_Credential_DatabricksGcpServiceAccount: + if value != nil { + credentialDatabricksGcpServiceAccountConverted, err := databricksGcpServiceAccountToWire(&value.DatabricksGcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCredentialRequest.Credential.DatabricksGcpServiceAccount", err) + } + credentialDatabricksGcpServiceAccountWire = credentialDatabricksGcpServiceAccountConverted + } + case *CreateCredentialRequest_Credential_CloudflareApiToken: + if value != nil { + credentialCloudflareApiTokenConverted, err := cloudflareApiTokenToWire(&value.CloudflareApiToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCredentialRequest.Credential.CloudflareApiToken", err) + } + credentialCloudflareApiTokenWire = credentialCloudflareApiTokenConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreateCredentialRequest.Credential", value) + } + return &createCredentialRequestWire{ + SkipValidation: v.SkipValidation, + Name: v.Name, + AwsIamRole: credentialAwsIamRoleWire, + AzureServicePrincipal: credentialAzureServicePrincipalWire, + GcpServiceAccountKey: credentialGcpServiceAccountKeyWire, + AzureManagedIdentity: credentialAzureManagedIdentityWire, + DatabricksGcpServiceAccount: credentialDatabricksGcpServiceAccountWire, + CloudflareApiToken: credentialCloudflareApiTokenWire, + Comment: v.Comment, + ReadOnly: v.ReadOnly, + Owner: v.Owner, + Id: v.Id, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + UsedForManagedStorage: v.UsedForManagedStorage, + FullName: v.FullName, + IsolationMode: v.IsolationMode, + }, nil +} + +type createCredentialsRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + CredentialsName *string `json:"credentials_name,omitempty"` + AwsCredentials *createCredentialAwsCredentialsWire `json:"aws_credentials,omitempty"` +} + +func createCredentialsRequestToWire(v *CreateCredentialsRequest) (*createCredentialsRequestWire, error) { + if v == nil { + return nil, nil + } + var cloudCredentialsAwsCredentialsWire *createCredentialAwsCredentialsWire + switch value := v.CloudCredentials.(type) { + case nil: + case *CreateCredentialsRequest_CloudCredentials_AwsCredentials: + if value != nil { + cloudCredentialsAwsCredentialsConverted, err := createCredentialAwsCredentialsToWire(&value.AwsCredentials) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateCredentialsRequest.CloudCredentials.AwsCredentials", err) + } + cloudCredentialsAwsCredentialsWire = cloudCredentialsAwsCredentialsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreateCredentialsRequest.CloudCredentials", value) + } + return &createCredentialsRequestWire{ + AccountId: v.AccountId, + CredentialsName: v.CredentialsName, + AwsCredentials: cloudCredentialsAwsCredentialsWire, + }, nil +} + +type createStorageCredentialRequestWire struct { + SkipValidation *bool `json:"skip_validation,omitempty"` + Name *string `json:"name,omitempty"` + AwsIamRole *awsIamRoleWire `json:"aws_iam_role,omitempty"` + AzureServicePrincipal *azureServicePrincipalWire `json:"azure_service_principal,omitempty"` + GcpServiceAccountKey *gcpServiceAccountKeyWire `json:"gcp_service_account_key,omitempty"` + AzureManagedIdentity *azureManagedIdentityWire `json:"azure_managed_identity,omitempty"` + DatabricksGcpServiceAccount *databricksGcpServiceAccountWire `json:"databricks_gcp_service_account,omitempty"` + CloudflareApiToken *cloudflareApiTokenWire `json:"cloudflare_api_token,omitempty"` + Comment *string `json:"comment,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Owner *string `json:"owner,omitempty"` + Id *string `json:"id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + UsedForManagedStorage *bool `json:"used_for_managed_storage,omitempty"` + FullName *string `json:"full_name,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` +} + +func createStorageCredentialRequestToWire(v *CreateStorageCredentialRequest) (*createStorageCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + var credentialAwsIamRoleWire *awsIamRoleWire + var credentialAzureServicePrincipalWire *azureServicePrincipalWire + var credentialGcpServiceAccountKeyWire *gcpServiceAccountKeyWire + var credentialAzureManagedIdentityWire *azureManagedIdentityWire + var credentialDatabricksGcpServiceAccountWire *databricksGcpServiceAccountWire + var credentialCloudflareApiTokenWire *cloudflareApiTokenWire + switch value := v.Credential.(type) { + case nil: + case *CreateStorageCredentialRequest_Credential_AwsIamRole: + if value != nil { + credentialAwsIamRoleConverted, err := awsIamRoleToWire(&value.AwsIamRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateStorageCredentialRequest.Credential.AwsIamRole", err) + } + credentialAwsIamRoleWire = credentialAwsIamRoleConverted + } + case *CreateStorageCredentialRequest_Credential_AzureServicePrincipal: + if value != nil { + credentialAzureServicePrincipalConverted, err := azureServicePrincipalToWire(&value.AzureServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateStorageCredentialRequest.Credential.AzureServicePrincipal", err) + } + credentialAzureServicePrincipalWire = credentialAzureServicePrincipalConverted + } + case *CreateStorageCredentialRequest_Credential_GcpServiceAccountKey: + if value != nil { + credentialGcpServiceAccountKeyConverted, err := gcpServiceAccountKeyToWire(&value.GcpServiceAccountKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateStorageCredentialRequest.Credential.GcpServiceAccountKey", err) + } + credentialGcpServiceAccountKeyWire = credentialGcpServiceAccountKeyConverted + } + case *CreateStorageCredentialRequest_Credential_AzureManagedIdentity: + if value != nil { + credentialAzureManagedIdentityConverted, err := azureManagedIdentityToWire(&value.AzureManagedIdentity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateStorageCredentialRequest.Credential.AzureManagedIdentity", err) + } + credentialAzureManagedIdentityWire = credentialAzureManagedIdentityConverted + } + case *CreateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount: + if value != nil { + credentialDatabricksGcpServiceAccountConverted, err := databricksGcpServiceAccountToWire(&value.DatabricksGcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateStorageCredentialRequest.Credential.DatabricksGcpServiceAccount", err) + } + credentialDatabricksGcpServiceAccountWire = credentialDatabricksGcpServiceAccountConverted + } + case *CreateStorageCredentialRequest_Credential_CloudflareApiToken: + if value != nil { + credentialCloudflareApiTokenConverted, err := cloudflareApiTokenToWire(&value.CloudflareApiToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateStorageCredentialRequest.Credential.CloudflareApiToken", err) + } + credentialCloudflareApiTokenWire = credentialCloudflareApiTokenConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreateStorageCredentialRequest.Credential", value) + } + return &createStorageCredentialRequestWire{ + SkipValidation: v.SkipValidation, + Name: v.Name, + AwsIamRole: credentialAwsIamRoleWire, + AzureServicePrincipal: credentialAzureServicePrincipalWire, + GcpServiceAccountKey: credentialGcpServiceAccountKeyWire, + AzureManagedIdentity: credentialAzureManagedIdentityWire, + DatabricksGcpServiceAccount: credentialDatabricksGcpServiceAccountWire, + CloudflareApiToken: credentialCloudflareApiTokenWire, + Comment: v.Comment, + ReadOnly: v.ReadOnly, + Owner: v.Owner, + Id: v.Id, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + UsedForManagedStorage: v.UsedForManagedStorage, + FullName: v.FullName, + IsolationMode: v.IsolationMode, + }, nil +} + +type credentialInfoWire struct { + Name *string `json:"name,omitempty"` + AwsIamRole *awsIamRoleWire `json:"aws_iam_role,omitempty"` + AzureServicePrincipal *azureServicePrincipalWire `json:"azure_service_principal,omitempty"` + GcpServiceAccountKey *gcpServiceAccountKeyWire `json:"gcp_service_account_key,omitempty"` + AzureManagedIdentity *azureManagedIdentityWire `json:"azure_managed_identity,omitempty"` + DatabricksGcpServiceAccount *databricksGcpServiceAccountWire `json:"databricks_gcp_service_account,omitempty"` + CloudflareApiToken *cloudflareApiTokenWire `json:"cloudflare_api_token,omitempty"` + Comment *string `json:"comment,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Owner *string `json:"owner,omitempty"` + Id *string `json:"id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + UsedForManagedStorage *bool `json:"used_for_managed_storage,omitempty"` + FullName *string `json:"full_name,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` +} + +func credentialInfoFromWire(w *credentialInfoWire) (*CredentialInfo, error) { + if w == nil { + return nil, nil + } + credentialMembers := 0 + if w.AwsIamRole != nil { + credentialMembers++ + } + if w.AzureServicePrincipal != nil { + credentialMembers++ + } + if w.GcpServiceAccountKey != nil { + credentialMembers++ + } + if w.AzureManagedIdentity != nil { + credentialMembers++ + } + if w.DatabricksGcpServiceAccount != nil { + credentialMembers++ + } + if w.CloudflareApiToken != nil { + credentialMembers++ + } + if credentialMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "CredentialInfo.Credential") + } + var credentialSelection isCredentialInfo_Credential + switch { + case w.AwsIamRole != nil: + credentialAwsIamRoleConverted, err := awsIamRoleFromWire(w.AwsIamRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CredentialInfo.Credential.AwsIamRole", err) + } + credentialSelection = &CredentialInfo_Credential_AwsIamRole{AwsIamRole: *credentialAwsIamRoleConverted} + case w.AzureServicePrincipal != nil: + credentialAzureServicePrincipalConverted, err := azureServicePrincipalFromWire(w.AzureServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CredentialInfo.Credential.AzureServicePrincipal", err) + } + credentialSelection = &CredentialInfo_Credential_AzureServicePrincipal{AzureServicePrincipal: *credentialAzureServicePrincipalConverted} + case w.GcpServiceAccountKey != nil: + credentialGcpServiceAccountKeyConverted, err := gcpServiceAccountKeyFromWire(w.GcpServiceAccountKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CredentialInfo.Credential.GcpServiceAccountKey", err) + } + credentialSelection = &CredentialInfo_Credential_GcpServiceAccountKey{GcpServiceAccountKey: *credentialGcpServiceAccountKeyConverted} + case w.AzureManagedIdentity != nil: + credentialAzureManagedIdentityConverted, err := azureManagedIdentityFromWire(w.AzureManagedIdentity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CredentialInfo.Credential.AzureManagedIdentity", err) + } + credentialSelection = &CredentialInfo_Credential_AzureManagedIdentity{AzureManagedIdentity: *credentialAzureManagedIdentityConverted} + case w.DatabricksGcpServiceAccount != nil: + credentialDatabricksGcpServiceAccountConverted, err := databricksGcpServiceAccountFromWire(w.DatabricksGcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CredentialInfo.Credential.DatabricksGcpServiceAccount", err) + } + credentialSelection = &CredentialInfo_Credential_DatabricksGcpServiceAccount{DatabricksGcpServiceAccount: *credentialDatabricksGcpServiceAccountConverted} + case w.CloudflareApiToken != nil: + credentialCloudflareApiTokenConverted, err := cloudflareApiTokenFromWire(w.CloudflareApiToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CredentialInfo.Credential.CloudflareApiToken", err) + } + credentialSelection = &CredentialInfo_Credential_CloudflareApiToken{CloudflareApiToken: *credentialCloudflareApiTokenConverted} + } + return &CredentialInfo{ + Name: w.Name, + Comment: w.Comment, + ReadOnly: w.ReadOnly, + Owner: w.Owner, + Id: w.Id, + MetastoreId: w.MetastoreId, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + UsedForManagedStorage: w.UsedForManagedStorage, + FullName: w.FullName, + IsolationMode: w.IsolationMode, + Credential: credentialSelection, + }, nil +} + +type credentialsWire struct { + CredentialsId *string `json:"credentials_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + AwsCredentials *awsCredentialsWire `json:"aws_credentials,omitempty"` + CredentialsName *string `json:"credentials_name,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` +} + +func credentialsFromWire(w *credentialsWire) (*Credentials, error) { + if w == nil { + return nil, nil + } + cloudCredentialsMembers := 0 + if w.AwsCredentials != nil { + cloudCredentialsMembers++ + } + if cloudCredentialsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Credentials.CloudCredentials") + } + var cloudCredentialsSelection isCredentials_CloudCredentials + switch { + case w.AwsCredentials != nil: + cloudCredentialsAwsCredentialsConverted, err := awsCredentialsFromWire(w.AwsCredentials) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Credentials.CloudCredentials.AwsCredentials", err) + } + cloudCredentialsSelection = &Credentials_CloudCredentials_AwsCredentials{AwsCredentials: *cloudCredentialsAwsCredentialsConverted} + } + return &Credentials{ + CredentialsId: w.CredentialsId, + AccountId: w.AccountId, + CredentialsName: w.CredentialsName, + CreationTime: w.CreationTime, + CloudCredentials: cloudCredentialsSelection, + }, nil +} + +type databricksGcpServiceAccountWire struct { + Email *string `json:"email,omitempty"` + PrivateKeyId *string `json:"private_key_id,omitempty"` + CredentialId *string `json:"credential_id,omitempty"` +} + +func databricksGcpServiceAccountToWire(v *DatabricksGcpServiceAccount) (*databricksGcpServiceAccountWire, error) { + if v == nil { + return nil, nil + } + return &databricksGcpServiceAccountWire{ + Email: v.Email, + PrivateKeyId: v.PrivateKeyId, + CredentialId: v.CredentialId, + }, nil +} + +func databricksGcpServiceAccountFromWire(w *databricksGcpServiceAccountWire) (*DatabricksGcpServiceAccount, error) { + if w == nil { + return nil, nil + } + return &DatabricksGcpServiceAccount{ + Email: w.Email, + PrivateKeyId: w.PrivateKeyId, + CredentialId: w.CredentialId, + }, nil +} + +type deleteCredentialRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + Force *bool `json:"force,omitempty"` +} + +func deleteCredentialRequestToWire(v *DeleteCredentialRequest) (*deleteCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteCredentialRequestWire{ + NameArg: v.NameArg, + Force: v.Force, + }, nil +} + +type deleteStorageCredentialRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + Force *bool `json:"force,omitempty"` +} + +func deleteStorageCredentialRequestToWire(v *DeleteStorageCredentialRequest) (*deleteStorageCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteStorageCredentialRequestWire{ + NameArg: v.NameArg, + Force: v.Force, + }, nil +} + +type gcpOauthTokenWire struct { + OauthToken *string `json:"oauth_token,omitempty"` +} + +func gcpOauthTokenFromWire(w *gcpOauthTokenWire) (*GcpOauthToken, error) { + if w == nil { + return nil, nil + } + return &GcpOauthToken{ + OauthToken: w.OauthToken, + }, nil +} + +type gcpServiceAccountKeyWire struct { + Email *string `json:"email,omitempty"` + PrivateKeyId *string `json:"private_key_id,omitempty"` + PrivateKey *string `json:"private_key,omitempty"` +} + +func gcpServiceAccountKeyToWire(v *GcpServiceAccountKey) (*gcpServiceAccountKeyWire, error) { + if v == nil { + return nil, nil + } + return &gcpServiceAccountKeyWire{ + Email: v.Email, + PrivateKeyId: v.PrivateKeyId, + PrivateKey: v.PrivateKey, + }, nil +} + +func gcpServiceAccountKeyFromWire(w *gcpServiceAccountKeyWire) (*GcpServiceAccountKey, error) { + if w == nil { + return nil, nil + } + return &GcpServiceAccountKey{ + Email: w.Email, + PrivateKeyId: w.PrivateKeyId, + PrivateKey: w.PrivateKey, + }, nil +} + +type generateTemporaryPathCredentialRequestWire struct { + Url *string `json:"url,omitempty"` + Operation PathOperation `json:"operation,omitempty"` + DryRun *bool `json:"dry_run,omitempty"` +} + +func generateTemporaryPathCredentialRequestToWire(v *GenerateTemporaryPathCredentialRequest) (*generateTemporaryPathCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + return &generateTemporaryPathCredentialRequestWire{ + Url: v.Url, + Operation: v.Operation, + DryRun: v.DryRun, + }, nil +} + +type generateTemporaryPathCredentialResponseWire struct { + AwsTempCredentials *temporaryAwsCredentialsWire `json:"aws_temp_credentials,omitempty"` + AzureUserDelegationSas *azureUserDelegationSasWire `json:"azure_user_delegation_sas,omitempty"` + GcpOauthToken *gcpOauthTokenWire `json:"gcp_oauth_token,omitempty"` + AzureAad *azureActiveDirectoryTokenWire `json:"azure_aad,omitempty"` + R2TempCredentials *r2CredentialsWire `json:"r2_temp_credentials,omitempty"` + ExpirationTime *int64 `json:"expiration_time,omitempty"` + Url *string `json:"url,omitempty"` +} + +func generateTemporaryPathCredentialResponseFromWire(w *generateTemporaryPathCredentialResponseWire) (*GenerateTemporaryPathCredentialResponse, error) { + if w == nil { + return nil, nil + } + credentialsMembers := 0 + if w.AwsTempCredentials != nil { + credentialsMembers++ + } + if w.AzureUserDelegationSas != nil { + credentialsMembers++ + } + if w.GcpOauthToken != nil { + credentialsMembers++ + } + if w.AzureAad != nil { + credentialsMembers++ + } + if w.R2TempCredentials != nil { + credentialsMembers++ + } + if credentialsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "GenerateTemporaryPathCredentialResponse.Credentials") + } + var credentialsSelection isGenerateTemporaryPathCredentialResponse_Credentials + switch { + case w.AwsTempCredentials != nil: + credentialsAwsTempCredentialsConverted, err := temporaryAwsCredentialsFromWire(w.AwsTempCredentials) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryPathCredentialResponse.Credentials.AwsTempCredentials", err) + } + credentialsSelection = &GenerateTemporaryPathCredentialResponse_Credentials_AwsTempCredentials{AwsTempCredentials: *credentialsAwsTempCredentialsConverted} + case w.AzureUserDelegationSas != nil: + credentialsAzureUserDelegationSasConverted, err := azureUserDelegationSasFromWire(w.AzureUserDelegationSas) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryPathCredentialResponse.Credentials.AzureUserDelegationSas", err) + } + credentialsSelection = &GenerateTemporaryPathCredentialResponse_Credentials_AzureUserDelegationSas{AzureUserDelegationSas: *credentialsAzureUserDelegationSasConverted} + case w.GcpOauthToken != nil: + credentialsGcpOauthTokenConverted, err := gcpOauthTokenFromWire(w.GcpOauthToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryPathCredentialResponse.Credentials.GcpOauthToken", err) + } + credentialsSelection = &GenerateTemporaryPathCredentialResponse_Credentials_GcpOauthToken{GcpOauthToken: *credentialsGcpOauthTokenConverted} + case w.AzureAad != nil: + credentialsAzureAadConverted, err := azureActiveDirectoryTokenFromWire(w.AzureAad) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryPathCredentialResponse.Credentials.AzureAad", err) + } + credentialsSelection = &GenerateTemporaryPathCredentialResponse_Credentials_AzureAad{AzureAad: *credentialsAzureAadConverted} + case w.R2TempCredentials != nil: + credentialsR2TempCredentialsConverted, err := r2CredentialsFromWire(w.R2TempCredentials) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryPathCredentialResponse.Credentials.R2TempCredentials", err) + } + credentialsSelection = &GenerateTemporaryPathCredentialResponse_Credentials_R2TempCredentials{R2TempCredentials: *credentialsR2TempCredentialsConverted} + } + return &GenerateTemporaryPathCredentialResponse{ + ExpirationTime: w.ExpirationTime, + Url: w.Url, + Credentials: credentialsSelection, + }, nil +} + +type generateTemporaryServiceCredentialRequestWire struct { + CredentialName *string `json:"credential_name,omitempty"` + AzureOptions *generateTemporaryServiceCredentialRequest_AzureOptionsWire `json:"azure_options,omitempty"` + GcpOptions *generateTemporaryServiceCredentialRequest_GcpOptionsWire `json:"gcp_options,omitempty"` +} + +func generateTemporaryServiceCredentialRequestToWire(v *GenerateTemporaryServiceCredentialRequest) (*generateTemporaryServiceCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + var optionsAzureOptionsWire *generateTemporaryServiceCredentialRequest_AzureOptionsWire + var optionsGcpOptionsWire *generateTemporaryServiceCredentialRequest_GcpOptionsWire + switch value := v.Options.(type) { + case nil: + case *GenerateTemporaryServiceCredentialRequest_Options_AzureOptions: + if value != nil { + optionsAzureOptionsConverted, err := generateTemporaryServiceCredentialRequest_AzureOptionsToWire(&value.AzureOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryServiceCredentialRequest.Options.AzureOptions", err) + } + optionsAzureOptionsWire = optionsAzureOptionsConverted + } + case *GenerateTemporaryServiceCredentialRequest_Options_GcpOptions: + if value != nil { + optionsGcpOptionsConverted, err := generateTemporaryServiceCredentialRequest_GcpOptionsToWire(&value.GcpOptions) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryServiceCredentialRequest.Options.GcpOptions", err) + } + optionsGcpOptionsWire = optionsGcpOptionsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "GenerateTemporaryServiceCredentialRequest.Options", value) + } + return &generateTemporaryServiceCredentialRequestWire{ + CredentialName: v.CredentialName, + AzureOptions: optionsAzureOptionsWire, + GcpOptions: optionsGcpOptionsWire, + }, nil +} + +type generateTemporaryServiceCredentialRequest_AzureOptionsWire struct { + Resources []string `json:"resources,omitempty"` +} + +func generateTemporaryServiceCredentialRequest_AzureOptionsToWire(v *GenerateTemporaryServiceCredentialRequest_AzureOptions) (*generateTemporaryServiceCredentialRequest_AzureOptionsWire, error) { + if v == nil { + return nil, nil + } + return &generateTemporaryServiceCredentialRequest_AzureOptionsWire{ + Resources: v.Resources, + }, nil +} + +type generateTemporaryServiceCredentialRequest_GcpOptionsWire struct { + Scopes []string `json:"scopes,omitempty"` +} + +func generateTemporaryServiceCredentialRequest_GcpOptionsToWire(v *GenerateTemporaryServiceCredentialRequest_GcpOptions) (*generateTemporaryServiceCredentialRequest_GcpOptionsWire, error) { + if v == nil { + return nil, nil + } + return &generateTemporaryServiceCredentialRequest_GcpOptionsWire{ + Scopes: v.Scopes, + }, nil +} + +type generateTemporaryTableCredentialRequestWire struct { + TableId *string `json:"table_id,omitempty"` + Operation TableOperation `json:"operation,omitempty"` +} + +func generateTemporaryTableCredentialRequestToWire(v *GenerateTemporaryTableCredentialRequest) (*generateTemporaryTableCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + return &generateTemporaryTableCredentialRequestWire{ + TableId: v.TableId, + Operation: v.Operation, + }, nil +} + +type generateTemporaryTableCredentialResponseWire struct { + AwsTempCredentials *temporaryAwsCredentialsWire `json:"aws_temp_credentials,omitempty"` + AzureUserDelegationSas *azureUserDelegationSasWire `json:"azure_user_delegation_sas,omitempty"` + GcpOauthToken *gcpOauthTokenWire `json:"gcp_oauth_token,omitempty"` + AzureAad *azureActiveDirectoryTokenWire `json:"azure_aad,omitempty"` + R2TempCredentials *r2CredentialsWire `json:"r2_temp_credentials,omitempty"` + ExpirationTime *int64 `json:"expiration_time,omitempty"` + Url *string `json:"url,omitempty"` +} + +func generateTemporaryTableCredentialResponseFromWire(w *generateTemporaryTableCredentialResponseWire) (*GenerateTemporaryTableCredentialResponse, error) { + if w == nil { + return nil, nil + } + credentialsMembers := 0 + if w.AwsTempCredentials != nil { + credentialsMembers++ + } + if w.AzureUserDelegationSas != nil { + credentialsMembers++ + } + if w.GcpOauthToken != nil { + credentialsMembers++ + } + if w.AzureAad != nil { + credentialsMembers++ + } + if w.R2TempCredentials != nil { + credentialsMembers++ + } + if credentialsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "GenerateTemporaryTableCredentialResponse.Credentials") + } + var credentialsSelection isGenerateTemporaryTableCredentialResponse_Credentials + switch { + case w.AwsTempCredentials != nil: + credentialsAwsTempCredentialsConverted, err := temporaryAwsCredentialsFromWire(w.AwsTempCredentials) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryTableCredentialResponse.Credentials.AwsTempCredentials", err) + } + credentialsSelection = &GenerateTemporaryTableCredentialResponse_Credentials_AwsTempCredentials{AwsTempCredentials: *credentialsAwsTempCredentialsConverted} + case w.AzureUserDelegationSas != nil: + credentialsAzureUserDelegationSasConverted, err := azureUserDelegationSasFromWire(w.AzureUserDelegationSas) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryTableCredentialResponse.Credentials.AzureUserDelegationSas", err) + } + credentialsSelection = &GenerateTemporaryTableCredentialResponse_Credentials_AzureUserDelegationSas{AzureUserDelegationSas: *credentialsAzureUserDelegationSasConverted} + case w.GcpOauthToken != nil: + credentialsGcpOauthTokenConverted, err := gcpOauthTokenFromWire(w.GcpOauthToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryTableCredentialResponse.Credentials.GcpOauthToken", err) + } + credentialsSelection = &GenerateTemporaryTableCredentialResponse_Credentials_GcpOauthToken{GcpOauthToken: *credentialsGcpOauthTokenConverted} + case w.AzureAad != nil: + credentialsAzureAadConverted, err := azureActiveDirectoryTokenFromWire(w.AzureAad) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryTableCredentialResponse.Credentials.AzureAad", err) + } + credentialsSelection = &GenerateTemporaryTableCredentialResponse_Credentials_AzureAad{AzureAad: *credentialsAzureAadConverted} + case w.R2TempCredentials != nil: + credentialsR2TempCredentialsConverted, err := r2CredentialsFromWire(w.R2TempCredentials) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryTableCredentialResponse.Credentials.R2TempCredentials", err) + } + credentialsSelection = &GenerateTemporaryTableCredentialResponse_Credentials_R2TempCredentials{R2TempCredentials: *credentialsR2TempCredentialsConverted} + } + return &GenerateTemporaryTableCredentialResponse{ + ExpirationTime: w.ExpirationTime, + Url: w.Url, + Credentials: credentialsSelection, + }, nil +} + +type generateTemporaryVolumeCredentialRequestWire struct { + VolumeId *string `json:"volume_id,omitempty"` + Operation VolumeOperation `json:"operation,omitempty"` +} + +func generateTemporaryVolumeCredentialRequestToWire(v *GenerateTemporaryVolumeCredentialRequest) (*generateTemporaryVolumeCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + return &generateTemporaryVolumeCredentialRequestWire{ + VolumeId: v.VolumeId, + Operation: v.Operation, + }, nil +} + +type generateTemporaryVolumeCredentialResponseWire struct { + AwsTempCredentials *temporaryAwsCredentialsWire `json:"aws_temp_credentials,omitempty"` + AzureUserDelegationSas *azureUserDelegationSasWire `json:"azure_user_delegation_sas,omitempty"` + GcpOauthToken *gcpOauthTokenWire `json:"gcp_oauth_token,omitempty"` + AzureAad *azureActiveDirectoryTokenWire `json:"azure_aad,omitempty"` + R2TempCredentials *r2CredentialsWire `json:"r2_temp_credentials,omitempty"` + ExpirationTime *int64 `json:"expiration_time,omitempty"` + Url *string `json:"url,omitempty"` +} + +func generateTemporaryVolumeCredentialResponseFromWire(w *generateTemporaryVolumeCredentialResponseWire) (*GenerateTemporaryVolumeCredentialResponse, error) { + if w == nil { + return nil, nil + } + credentialsMembers := 0 + if w.AwsTempCredentials != nil { + credentialsMembers++ + } + if w.AzureUserDelegationSas != nil { + credentialsMembers++ + } + if w.GcpOauthToken != nil { + credentialsMembers++ + } + if w.AzureAad != nil { + credentialsMembers++ + } + if w.R2TempCredentials != nil { + credentialsMembers++ + } + if credentialsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "GenerateTemporaryVolumeCredentialResponse.Credentials") + } + var credentialsSelection isGenerateTemporaryVolumeCredentialResponse_Credentials + switch { + case w.AwsTempCredentials != nil: + credentialsAwsTempCredentialsConverted, err := temporaryAwsCredentialsFromWire(w.AwsTempCredentials) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryVolumeCredentialResponse.Credentials.AwsTempCredentials", err) + } + credentialsSelection = &GenerateTemporaryVolumeCredentialResponse_Credentials_AwsTempCredentials{AwsTempCredentials: *credentialsAwsTempCredentialsConverted} + case w.AzureUserDelegationSas != nil: + credentialsAzureUserDelegationSasConverted, err := azureUserDelegationSasFromWire(w.AzureUserDelegationSas) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryVolumeCredentialResponse.Credentials.AzureUserDelegationSas", err) + } + credentialsSelection = &GenerateTemporaryVolumeCredentialResponse_Credentials_AzureUserDelegationSas{AzureUserDelegationSas: *credentialsAzureUserDelegationSasConverted} + case w.GcpOauthToken != nil: + credentialsGcpOauthTokenConverted, err := gcpOauthTokenFromWire(w.GcpOauthToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryVolumeCredentialResponse.Credentials.GcpOauthToken", err) + } + credentialsSelection = &GenerateTemporaryVolumeCredentialResponse_Credentials_GcpOauthToken{GcpOauthToken: *credentialsGcpOauthTokenConverted} + case w.AzureAad != nil: + credentialsAzureAadConverted, err := azureActiveDirectoryTokenFromWire(w.AzureAad) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryVolumeCredentialResponse.Credentials.AzureAad", err) + } + credentialsSelection = &GenerateTemporaryVolumeCredentialResponse_Credentials_AzureAad{AzureAad: *credentialsAzureAadConverted} + case w.R2TempCredentials != nil: + credentialsR2TempCredentialsConverted, err := r2CredentialsFromWire(w.R2TempCredentials) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GenerateTemporaryVolumeCredentialResponse.Credentials.R2TempCredentials", err) + } + credentialsSelection = &GenerateTemporaryVolumeCredentialResponse_Credentials_R2TempCredentials{R2TempCredentials: *credentialsR2TempCredentialsConverted} + } + return &GenerateTemporaryVolumeCredentialResponse{ + ExpirationTime: w.ExpirationTime, + Url: w.Url, + Credentials: credentialsSelection, + }, nil +} + +type listCredentialsRequestWire struct { + IncludeUnbound *bool `json:"include_unbound,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listCredentialsRequestToWire(v *ListCredentialsRequest) (*listCredentialsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listCredentialsRequestWire{ + IncludeUnbound: v.IncludeUnbound, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listCredentialsRequest_ResponseWire struct { + Credentials []credentialInfoWire `json:"credentials,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listCredentialsRequest_ResponseFromWire(w *listCredentialsRequest_ResponseWire) (*ListCredentialsRequest_Response, error) { + if w == nil { + return nil, nil + } + credentialsPublicValue, err := convertSlice(w.Credentials, credentialInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListCredentialsRequest_Response.Credentials", err) + } + return &ListCredentialsRequest_Response{ + Credentials: credentialsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listStorageCredentialsRequestWire struct { + IncludeUnbound *bool `json:"include_unbound,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listStorageCredentialsRequestToWire(v *ListStorageCredentialsRequest) (*listStorageCredentialsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listStorageCredentialsRequestWire{ + IncludeUnbound: v.IncludeUnbound, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listStorageCredentialsResponseWire struct { + StorageCredentials []storageCredentialInfoWire `json:"storage_credentials,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listStorageCredentialsResponseFromWire(w *listStorageCredentialsResponseWire) (*ListStorageCredentialsResponse, error) { + if w == nil { + return nil, nil + } + storageCredentialsPublicValue, err := convertSlice(w.StorageCredentials, storageCredentialInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListStorageCredentialsResponse.StorageCredentials", err) + } + return &ListStorageCredentialsResponse{ + StorageCredentials: storageCredentialsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type r2CredentialsWire struct { + AccessKeyId *string `json:"access_key_id,omitempty"` + SecretAccessKey *string `json:"secret_access_key,omitempty"` + SessionToken *string `json:"session_token,omitempty"` +} + +func r2CredentialsFromWire(w *r2CredentialsWire) (*R2Credentials, error) { + if w == nil { + return nil, nil + } + return &R2Credentials{ + AccessKeyId: w.AccessKeyId, + SecretAccessKey: w.SecretAccessKey, + SessionToken: w.SessionToken, + }, nil +} + +type storageCredentialInfoWire struct { + Name *string `json:"name,omitempty"` + AwsIamRole *awsIamRoleWire `json:"aws_iam_role,omitempty"` + AzureServicePrincipal *azureServicePrincipalWire `json:"azure_service_principal,omitempty"` + GcpServiceAccountKey *gcpServiceAccountKeyWire `json:"gcp_service_account_key,omitempty"` + AzureManagedIdentity *azureManagedIdentityWire `json:"azure_managed_identity,omitempty"` + DatabricksGcpServiceAccount *databricksGcpServiceAccountWire `json:"databricks_gcp_service_account,omitempty"` + CloudflareApiToken *cloudflareApiTokenWire `json:"cloudflare_api_token,omitempty"` + Comment *string `json:"comment,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Owner *string `json:"owner,omitempty"` + Id *string `json:"id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + UsedForManagedStorage *bool `json:"used_for_managed_storage,omitempty"` + FullName *string `json:"full_name,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` +} + +func storageCredentialInfoFromWire(w *storageCredentialInfoWire) (*StorageCredentialInfo, error) { + if w == nil { + return nil, nil + } + credentialMembers := 0 + if w.AwsIamRole != nil { + credentialMembers++ + } + if w.AzureServicePrincipal != nil { + credentialMembers++ + } + if w.GcpServiceAccountKey != nil { + credentialMembers++ + } + if w.AzureManagedIdentity != nil { + credentialMembers++ + } + if w.DatabricksGcpServiceAccount != nil { + credentialMembers++ + } + if w.CloudflareApiToken != nil { + credentialMembers++ + } + if credentialMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "StorageCredentialInfo.Credential") + } + var credentialSelection isStorageCredentialInfo_Credential + switch { + case w.AwsIamRole != nil: + credentialAwsIamRoleConverted, err := awsIamRoleFromWire(w.AwsIamRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StorageCredentialInfo.Credential.AwsIamRole", err) + } + credentialSelection = &StorageCredentialInfo_Credential_AwsIamRole{AwsIamRole: *credentialAwsIamRoleConverted} + case w.AzureServicePrincipal != nil: + credentialAzureServicePrincipalConverted, err := azureServicePrincipalFromWire(w.AzureServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StorageCredentialInfo.Credential.AzureServicePrincipal", err) + } + credentialSelection = &StorageCredentialInfo_Credential_AzureServicePrincipal{AzureServicePrincipal: *credentialAzureServicePrincipalConverted} + case w.GcpServiceAccountKey != nil: + credentialGcpServiceAccountKeyConverted, err := gcpServiceAccountKeyFromWire(w.GcpServiceAccountKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StorageCredentialInfo.Credential.GcpServiceAccountKey", err) + } + credentialSelection = &StorageCredentialInfo_Credential_GcpServiceAccountKey{GcpServiceAccountKey: *credentialGcpServiceAccountKeyConverted} + case w.AzureManagedIdentity != nil: + credentialAzureManagedIdentityConverted, err := azureManagedIdentityFromWire(w.AzureManagedIdentity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StorageCredentialInfo.Credential.AzureManagedIdentity", err) + } + credentialSelection = &StorageCredentialInfo_Credential_AzureManagedIdentity{AzureManagedIdentity: *credentialAzureManagedIdentityConverted} + case w.DatabricksGcpServiceAccount != nil: + credentialDatabricksGcpServiceAccountConverted, err := databricksGcpServiceAccountFromWire(w.DatabricksGcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StorageCredentialInfo.Credential.DatabricksGcpServiceAccount", err) + } + credentialSelection = &StorageCredentialInfo_Credential_DatabricksGcpServiceAccount{DatabricksGcpServiceAccount: *credentialDatabricksGcpServiceAccountConverted} + case w.CloudflareApiToken != nil: + credentialCloudflareApiTokenConverted, err := cloudflareApiTokenFromWire(w.CloudflareApiToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "StorageCredentialInfo.Credential.CloudflareApiToken", err) + } + credentialSelection = &StorageCredentialInfo_Credential_CloudflareApiToken{CloudflareApiToken: *credentialCloudflareApiTokenConverted} + } + return &StorageCredentialInfo{ + Name: w.Name, + Comment: w.Comment, + ReadOnly: w.ReadOnly, + Owner: w.Owner, + Id: w.Id, + MetastoreId: w.MetastoreId, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + UsedForManagedStorage: w.UsedForManagedStorage, + FullName: w.FullName, + IsolationMode: w.IsolationMode, + Credential: credentialSelection, + }, nil +} + +type temporaryAwsCredentialsWire struct { + AccessKeyId *string `json:"access_key_id,omitempty"` + SecretAccessKey *string `json:"secret_access_key,omitempty"` + SessionToken *string `json:"session_token,omitempty"` + AccessPoint *string `json:"access_point,omitempty"` +} + +func temporaryAwsCredentialsFromWire(w *temporaryAwsCredentialsWire) (*TemporaryAwsCredentials, error) { + if w == nil { + return nil, nil + } + return &TemporaryAwsCredentials{ + AccessKeyId: w.AccessKeyId, + SecretAccessKey: w.SecretAccessKey, + SessionToken: w.SessionToken, + AccessPoint: w.AccessPoint, + }, nil +} + +type temporaryCredentialsWire struct { + AwsTempCredentials *temporaryAwsCredentialsWire `json:"aws_temp_credentials,omitempty"` + AzureUserDelegationSas *azureUserDelegationSasWire `json:"azure_user_delegation_sas,omitempty"` + GcpOauthToken *gcpOauthTokenWire `json:"gcp_oauth_token,omitempty"` + AzureAad *azureActiveDirectoryTokenWire `json:"azure_aad,omitempty"` + R2TempCredentials *r2CredentialsWire `json:"r2_temp_credentials,omitempty"` + ExpirationTime *int64 `json:"expiration_time,omitempty"` + Url *string `json:"url,omitempty"` +} + +func temporaryCredentialsFromWire(w *temporaryCredentialsWire) (*TemporaryCredentials, error) { + if w == nil { + return nil, nil + } + credentialsMembers := 0 + if w.AwsTempCredentials != nil { + credentialsMembers++ + } + if w.AzureUserDelegationSas != nil { + credentialsMembers++ + } + if w.GcpOauthToken != nil { + credentialsMembers++ + } + if w.AzureAad != nil { + credentialsMembers++ + } + if w.R2TempCredentials != nil { + credentialsMembers++ + } + if credentialsMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "TemporaryCredentials.Credentials") + } + var credentialsSelection isTemporaryCredentials_Credentials + switch { + case w.AwsTempCredentials != nil: + credentialsAwsTempCredentialsConverted, err := temporaryAwsCredentialsFromWire(w.AwsTempCredentials) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TemporaryCredentials.Credentials.AwsTempCredentials", err) + } + credentialsSelection = &TemporaryCredentials_Credentials_AwsTempCredentials{AwsTempCredentials: *credentialsAwsTempCredentialsConverted} + case w.AzureUserDelegationSas != nil: + credentialsAzureUserDelegationSasConverted, err := azureUserDelegationSasFromWire(w.AzureUserDelegationSas) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TemporaryCredentials.Credentials.AzureUserDelegationSas", err) + } + credentialsSelection = &TemporaryCredentials_Credentials_AzureUserDelegationSas{AzureUserDelegationSas: *credentialsAzureUserDelegationSasConverted} + case w.GcpOauthToken != nil: + credentialsGcpOauthTokenConverted, err := gcpOauthTokenFromWire(w.GcpOauthToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TemporaryCredentials.Credentials.GcpOauthToken", err) + } + credentialsSelection = &TemporaryCredentials_Credentials_GcpOauthToken{GcpOauthToken: *credentialsGcpOauthTokenConverted} + case w.AzureAad != nil: + credentialsAzureAadConverted, err := azureActiveDirectoryTokenFromWire(w.AzureAad) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TemporaryCredentials.Credentials.AzureAad", err) + } + credentialsSelection = &TemporaryCredentials_Credentials_AzureAad{AzureAad: *credentialsAzureAadConverted} + case w.R2TempCredentials != nil: + credentialsR2TempCredentialsConverted, err := r2CredentialsFromWire(w.R2TempCredentials) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TemporaryCredentials.Credentials.R2TempCredentials", err) + } + credentialsSelection = &TemporaryCredentials_Credentials_R2TempCredentials{R2TempCredentials: *credentialsR2TempCredentialsConverted} + } + return &TemporaryCredentials{ + ExpirationTime: w.ExpirationTime, + Url: w.Url, + Credentials: credentialsSelection, + }, nil +} + +type updateAccountsStorageCredentialWire struct { + Name *string `json:"name,omitempty"` + AwsIamRole *awsIamRoleWire `json:"aws_iam_role,omitempty"` + AzureServicePrincipal *azureServicePrincipalWire `json:"azure_service_principal,omitempty"` + GcpServiceAccountKey *gcpServiceAccountKeyWire `json:"gcp_service_account_key,omitempty"` + AzureManagedIdentity *azureManagedIdentityWire `json:"azure_managed_identity,omitempty"` + DatabricksGcpServiceAccount *databricksGcpServiceAccountWire `json:"databricks_gcp_service_account,omitempty"` + CloudflareApiToken *cloudflareApiTokenWire `json:"cloudflare_api_token,omitempty"` + Comment *string `json:"comment,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Owner *string `json:"owner,omitempty"` + Id *string `json:"id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + UsedForManagedStorage *bool `json:"used_for_managed_storage,omitempty"` + FullName *string `json:"full_name,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` +} + +func updateAccountsStorageCredentialToWire(v *UpdateAccountsStorageCredential) (*updateAccountsStorageCredentialWire, error) { + if v == nil { + return nil, nil + } + var credentialAwsIamRoleWire *awsIamRoleWire + var credentialAzureServicePrincipalWire *azureServicePrincipalWire + var credentialGcpServiceAccountKeyWire *gcpServiceAccountKeyWire + var credentialAzureManagedIdentityWire *azureManagedIdentityWire + var credentialDatabricksGcpServiceAccountWire *databricksGcpServiceAccountWire + var credentialCloudflareApiTokenWire *cloudflareApiTokenWire + switch value := v.Credential.(type) { + case nil: + case *UpdateAccountsStorageCredential_Credential_AwsIamRole: + if value != nil { + credentialAwsIamRoleConverted, err := awsIamRoleToWire(&value.AwsIamRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountsStorageCredential.Credential.AwsIamRole", err) + } + credentialAwsIamRoleWire = credentialAwsIamRoleConverted + } + case *UpdateAccountsStorageCredential_Credential_AzureServicePrincipal: + if value != nil { + credentialAzureServicePrincipalConverted, err := azureServicePrincipalToWire(&value.AzureServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountsStorageCredential.Credential.AzureServicePrincipal", err) + } + credentialAzureServicePrincipalWire = credentialAzureServicePrincipalConverted + } + case *UpdateAccountsStorageCredential_Credential_GcpServiceAccountKey: + if value != nil { + credentialGcpServiceAccountKeyConverted, err := gcpServiceAccountKeyToWire(&value.GcpServiceAccountKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountsStorageCredential.Credential.GcpServiceAccountKey", err) + } + credentialGcpServiceAccountKeyWire = credentialGcpServiceAccountKeyConverted + } + case *UpdateAccountsStorageCredential_Credential_AzureManagedIdentity: + if value != nil { + credentialAzureManagedIdentityConverted, err := azureManagedIdentityToWire(&value.AzureManagedIdentity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountsStorageCredential.Credential.AzureManagedIdentity", err) + } + credentialAzureManagedIdentityWire = credentialAzureManagedIdentityConverted + } + case *UpdateAccountsStorageCredential_Credential_DatabricksGcpServiceAccount: + if value != nil { + credentialDatabricksGcpServiceAccountConverted, err := databricksGcpServiceAccountToWire(&value.DatabricksGcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountsStorageCredential.Credential.DatabricksGcpServiceAccount", err) + } + credentialDatabricksGcpServiceAccountWire = credentialDatabricksGcpServiceAccountConverted + } + case *UpdateAccountsStorageCredential_Credential_CloudflareApiToken: + if value != nil { + credentialCloudflareApiTokenConverted, err := cloudflareApiTokenToWire(&value.CloudflareApiToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccountsStorageCredential.Credential.CloudflareApiToken", err) + } + credentialCloudflareApiTokenWire = credentialCloudflareApiTokenConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "UpdateAccountsStorageCredential.Credential", value) + } + return &updateAccountsStorageCredentialWire{ + Name: v.Name, + AwsIamRole: credentialAwsIamRoleWire, + AzureServicePrincipal: credentialAzureServicePrincipalWire, + GcpServiceAccountKey: credentialGcpServiceAccountKeyWire, + AzureManagedIdentity: credentialAzureManagedIdentityWire, + DatabricksGcpServiceAccount: credentialDatabricksGcpServiceAccountWire, + CloudflareApiToken: credentialCloudflareApiTokenWire, + Comment: v.Comment, + ReadOnly: v.ReadOnly, + Owner: v.Owner, + Id: v.Id, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + UsedForManagedStorage: v.UsedForManagedStorage, + FullName: v.FullName, + IsolationMode: v.IsolationMode, + }, nil +} + +type updateCredentialRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + SkipValidation *bool `json:"skip_validation,omitempty"` + Force *bool `json:"force,omitempty"` + Name *string `json:"name,omitempty"` + AwsIamRole *awsIamRoleWire `json:"aws_iam_role,omitempty"` + AzureServicePrincipal *azureServicePrincipalWire `json:"azure_service_principal,omitempty"` + GcpServiceAccountKey *gcpServiceAccountKeyWire `json:"gcp_service_account_key,omitempty"` + AzureManagedIdentity *azureManagedIdentityWire `json:"azure_managed_identity,omitempty"` + DatabricksGcpServiceAccount *databricksGcpServiceAccountWire `json:"databricks_gcp_service_account,omitempty"` + CloudflareApiToken *cloudflareApiTokenWire `json:"cloudflare_api_token,omitempty"` + Comment *string `json:"comment,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Owner *string `json:"owner,omitempty"` + Id *string `json:"id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + UsedForManagedStorage *bool `json:"used_for_managed_storage,omitempty"` + FullName *string `json:"full_name,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` +} + +func updateCredentialRequestToWire(v *UpdateCredentialRequest) (*updateCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + var credentialAwsIamRoleWire *awsIamRoleWire + var credentialAzureServicePrincipalWire *azureServicePrincipalWire + var credentialGcpServiceAccountKeyWire *gcpServiceAccountKeyWire + var credentialAzureManagedIdentityWire *azureManagedIdentityWire + var credentialDatabricksGcpServiceAccountWire *databricksGcpServiceAccountWire + var credentialCloudflareApiTokenWire *cloudflareApiTokenWire + switch value := v.Credential.(type) { + case nil: + case *UpdateCredentialRequest_Credential_AwsIamRole: + if value != nil { + credentialAwsIamRoleConverted, err := awsIamRoleToWire(&value.AwsIamRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCredentialRequest.Credential.AwsIamRole", err) + } + credentialAwsIamRoleWire = credentialAwsIamRoleConverted + } + case *UpdateCredentialRequest_Credential_AzureServicePrincipal: + if value != nil { + credentialAzureServicePrincipalConverted, err := azureServicePrincipalToWire(&value.AzureServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCredentialRequest.Credential.AzureServicePrincipal", err) + } + credentialAzureServicePrincipalWire = credentialAzureServicePrincipalConverted + } + case *UpdateCredentialRequest_Credential_GcpServiceAccountKey: + if value != nil { + credentialGcpServiceAccountKeyConverted, err := gcpServiceAccountKeyToWire(&value.GcpServiceAccountKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCredentialRequest.Credential.GcpServiceAccountKey", err) + } + credentialGcpServiceAccountKeyWire = credentialGcpServiceAccountKeyConverted + } + case *UpdateCredentialRequest_Credential_AzureManagedIdentity: + if value != nil { + credentialAzureManagedIdentityConverted, err := azureManagedIdentityToWire(&value.AzureManagedIdentity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCredentialRequest.Credential.AzureManagedIdentity", err) + } + credentialAzureManagedIdentityWire = credentialAzureManagedIdentityConverted + } + case *UpdateCredentialRequest_Credential_DatabricksGcpServiceAccount: + if value != nil { + credentialDatabricksGcpServiceAccountConverted, err := databricksGcpServiceAccountToWire(&value.DatabricksGcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCredentialRequest.Credential.DatabricksGcpServiceAccount", err) + } + credentialDatabricksGcpServiceAccountWire = credentialDatabricksGcpServiceAccountConverted + } + case *UpdateCredentialRequest_Credential_CloudflareApiToken: + if value != nil { + credentialCloudflareApiTokenConverted, err := cloudflareApiTokenToWire(&value.CloudflareApiToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateCredentialRequest.Credential.CloudflareApiToken", err) + } + credentialCloudflareApiTokenWire = credentialCloudflareApiTokenConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "UpdateCredentialRequest.Credential", value) + } + return &updateCredentialRequestWire{ + NameArg: v.NameArg, + NewName: v.NewName, + SkipValidation: v.SkipValidation, + Force: v.Force, + Name: v.Name, + AwsIamRole: credentialAwsIamRoleWire, + AzureServicePrincipal: credentialAzureServicePrincipalWire, + GcpServiceAccountKey: credentialGcpServiceAccountKeyWire, + AzureManagedIdentity: credentialAzureManagedIdentityWire, + DatabricksGcpServiceAccount: credentialDatabricksGcpServiceAccountWire, + CloudflareApiToken: credentialCloudflareApiTokenWire, + Comment: v.Comment, + ReadOnly: v.ReadOnly, + Owner: v.Owner, + Id: v.Id, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + UsedForManagedStorage: v.UsedForManagedStorage, + FullName: v.FullName, + IsolationMode: v.IsolationMode, + }, nil +} + +type updateStorageCredentialRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + SkipValidation *bool `json:"skip_validation,omitempty"` + Force *bool `json:"force,omitempty"` + Name *string `json:"name,omitempty"` + AwsIamRole *awsIamRoleWire `json:"aws_iam_role,omitempty"` + AzureServicePrincipal *azureServicePrincipalWire `json:"azure_service_principal,omitempty"` + GcpServiceAccountKey *gcpServiceAccountKeyWire `json:"gcp_service_account_key,omitempty"` + AzureManagedIdentity *azureManagedIdentityWire `json:"azure_managed_identity,omitempty"` + DatabricksGcpServiceAccount *databricksGcpServiceAccountWire `json:"databricks_gcp_service_account,omitempty"` + CloudflareApiToken *cloudflareApiTokenWire `json:"cloudflare_api_token,omitempty"` + Comment *string `json:"comment,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Owner *string `json:"owner,omitempty"` + Id *string `json:"id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + UsedForManagedStorage *bool `json:"used_for_managed_storage,omitempty"` + FullName *string `json:"full_name,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` +} + +func updateStorageCredentialRequestToWire(v *UpdateStorageCredentialRequest) (*updateStorageCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + var credentialAwsIamRoleWire *awsIamRoleWire + var credentialAzureServicePrincipalWire *azureServicePrincipalWire + var credentialGcpServiceAccountKeyWire *gcpServiceAccountKeyWire + var credentialAzureManagedIdentityWire *azureManagedIdentityWire + var credentialDatabricksGcpServiceAccountWire *databricksGcpServiceAccountWire + var credentialCloudflareApiTokenWire *cloudflareApiTokenWire + switch value := v.Credential.(type) { + case nil: + case *UpdateStorageCredentialRequest_Credential_AwsIamRole: + if value != nil { + credentialAwsIamRoleConverted, err := awsIamRoleToWire(&value.AwsIamRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateStorageCredentialRequest.Credential.AwsIamRole", err) + } + credentialAwsIamRoleWire = credentialAwsIamRoleConverted + } + case *UpdateStorageCredentialRequest_Credential_AzureServicePrincipal: + if value != nil { + credentialAzureServicePrincipalConverted, err := azureServicePrincipalToWire(&value.AzureServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateStorageCredentialRequest.Credential.AzureServicePrincipal", err) + } + credentialAzureServicePrincipalWire = credentialAzureServicePrincipalConverted + } + case *UpdateStorageCredentialRequest_Credential_GcpServiceAccountKey: + if value != nil { + credentialGcpServiceAccountKeyConverted, err := gcpServiceAccountKeyToWire(&value.GcpServiceAccountKey) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateStorageCredentialRequest.Credential.GcpServiceAccountKey", err) + } + credentialGcpServiceAccountKeyWire = credentialGcpServiceAccountKeyConverted + } + case *UpdateStorageCredentialRequest_Credential_AzureManagedIdentity: + if value != nil { + credentialAzureManagedIdentityConverted, err := azureManagedIdentityToWire(&value.AzureManagedIdentity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateStorageCredentialRequest.Credential.AzureManagedIdentity", err) + } + credentialAzureManagedIdentityWire = credentialAzureManagedIdentityConverted + } + case *UpdateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount: + if value != nil { + credentialDatabricksGcpServiceAccountConverted, err := databricksGcpServiceAccountToWire(&value.DatabricksGcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateStorageCredentialRequest.Credential.DatabricksGcpServiceAccount", err) + } + credentialDatabricksGcpServiceAccountWire = credentialDatabricksGcpServiceAccountConverted + } + case *UpdateStorageCredentialRequest_Credential_CloudflareApiToken: + if value != nil { + credentialCloudflareApiTokenConverted, err := cloudflareApiTokenToWire(&value.CloudflareApiToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateStorageCredentialRequest.Credential.CloudflareApiToken", err) + } + credentialCloudflareApiTokenWire = credentialCloudflareApiTokenConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "UpdateStorageCredentialRequest.Credential", value) + } + return &updateStorageCredentialRequestWire{ + NameArg: v.NameArg, + NewName: v.NewName, + SkipValidation: v.SkipValidation, + Force: v.Force, + Name: v.Name, + AwsIamRole: credentialAwsIamRoleWire, + AzureServicePrincipal: credentialAzureServicePrincipalWire, + GcpServiceAccountKey: credentialGcpServiceAccountKeyWire, + AzureManagedIdentity: credentialAzureManagedIdentityWire, + DatabricksGcpServiceAccount: credentialDatabricksGcpServiceAccountWire, + CloudflareApiToken: credentialCloudflareApiTokenWire, + Comment: v.Comment, + ReadOnly: v.ReadOnly, + Owner: v.Owner, + Id: v.Id, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + UsedForManagedStorage: v.UsedForManagedStorage, + FullName: v.FullName, + IsolationMode: v.IsolationMode, + }, nil +} + +type validateCredentialRequestWire struct { + CredentialName *string `json:"credential_name,omitempty"` + AwsIamRole *awsIamRoleWire `json:"aws_iam_role,omitempty"` + AzureManagedIdentity *azureManagedIdentityWire `json:"azure_managed_identity,omitempty"` + DatabricksGcpServiceAccount *databricksGcpServiceAccountWire `json:"databricks_gcp_service_account,omitempty"` + ExternalLocationName *string `json:"external_location_name,omitempty"` + Url *string `json:"url,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` +} + +func validateCredentialRequestToWire(v *ValidateCredentialRequest) (*validateCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + var credentialCredentialNameWire *string + var credentialAwsIamRoleWire *awsIamRoleWire + var credentialAzureManagedIdentityWire *azureManagedIdentityWire + var credentialDatabricksGcpServiceAccountWire *databricksGcpServiceAccountWire + switch value := v.Credential.(type) { + case nil: + case *ValidateCredentialRequest_Credential_CredentialName: + if value != nil { + credentialCredentialNameWire = new(value.CredentialName) + } + case *ValidateCredentialRequest_Credential_AwsIamRole: + if value != nil { + credentialAwsIamRoleConverted, err := awsIamRoleToWire(&value.AwsIamRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ValidateCredentialRequest.Credential.AwsIamRole", err) + } + credentialAwsIamRoleWire = credentialAwsIamRoleConverted + } + case *ValidateCredentialRequest_Credential_AzureManagedIdentity: + if value != nil { + credentialAzureManagedIdentityConverted, err := azureManagedIdentityToWire(&value.AzureManagedIdentity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ValidateCredentialRequest.Credential.AzureManagedIdentity", err) + } + credentialAzureManagedIdentityWire = credentialAzureManagedIdentityConverted + } + case *ValidateCredentialRequest_Credential_DatabricksGcpServiceAccount: + if value != nil { + credentialDatabricksGcpServiceAccountConverted, err := databricksGcpServiceAccountToWire(&value.DatabricksGcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ValidateCredentialRequest.Credential.DatabricksGcpServiceAccount", err) + } + credentialDatabricksGcpServiceAccountWire = credentialDatabricksGcpServiceAccountConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ValidateCredentialRequest.Credential", value) + } + return &validateCredentialRequestWire{ + CredentialName: credentialCredentialNameWire, + AwsIamRole: credentialAwsIamRoleWire, + AzureManagedIdentity: credentialAzureManagedIdentityWire, + DatabricksGcpServiceAccount: credentialDatabricksGcpServiceAccountWire, + ExternalLocationName: v.ExternalLocationName, + Url: v.Url, + ReadOnly: v.ReadOnly, + }, nil +} + +type validateCredentialRequest_ValidationResultWire struct { + Result ValidateCredentialRequest_Result `json:"result,omitempty"` + Message *string `json:"message,omitempty"` +} + +func validateCredentialRequest_ValidationResultFromWire(w *validateCredentialRequest_ValidationResultWire) (*ValidateCredentialRequest_ValidationResult, error) { + if w == nil { + return nil, nil + } + return &ValidateCredentialRequest_ValidationResult{ + Result: w.Result, + Message: w.Message, + }, nil +} + +type validateCredentialResponseWire struct { + Results []validateCredentialRequest_ValidationResultWire `json:"results,omitempty"` + IsDir *bool `json:"isDir,omitempty"` +} + +func validateCredentialResponseFromWire(w *validateCredentialResponseWire) (*ValidateCredentialResponse, error) { + if w == nil { + return nil, nil + } + resultsPublicValue, err := convertSlice(w.Results, validateCredentialRequest_ValidationResultFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ValidateCredentialResponse.Results", err) + } + return &ValidateCredentialResponse{ + Results: resultsPublicValue, + IsDir: w.IsDir, + }, nil +} + +type validateStorageCredentialRequestWire struct { + StorageCredentialName *string `json:"storage_credential_name,omitempty"` + AwsIamRole *awsIamRoleWire `json:"aws_iam_role,omitempty"` + AzureServicePrincipal *azureServicePrincipalWire `json:"azure_service_principal,omitempty"` + AzureManagedIdentity *azureManagedIdentityWire `json:"azure_managed_identity,omitempty"` + DatabricksGcpServiceAccount *databricksGcpServiceAccountWire `json:"databricks_gcp_service_account,omitempty"` + CloudflareApiToken *cloudflareApiTokenWire `json:"cloudflare_api_token,omitempty"` + ExternalLocationName *string `json:"external_location_name,omitempty"` + Url *string `json:"url,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` +} + +func validateStorageCredentialRequestToWire(v *ValidateStorageCredentialRequest) (*validateStorageCredentialRequestWire, error) { + if v == nil { + return nil, nil + } + var credentialStorageCredentialNameWire *string + var credentialAwsIamRoleWire *awsIamRoleWire + var credentialAzureServicePrincipalWire *azureServicePrincipalWire + var credentialAzureManagedIdentityWire *azureManagedIdentityWire + var credentialDatabricksGcpServiceAccountWire *databricksGcpServiceAccountWire + var credentialCloudflareApiTokenWire *cloudflareApiTokenWire + switch value := v.Credential.(type) { + case nil: + case *ValidateStorageCredentialRequest_Credential_StorageCredentialName: + if value != nil { + credentialStorageCredentialNameWire = new(value.StorageCredentialName) + } + case *ValidateStorageCredentialRequest_Credential_AwsIamRole: + if value != nil { + credentialAwsIamRoleConverted, err := awsIamRoleToWire(&value.AwsIamRole) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ValidateStorageCredentialRequest.Credential.AwsIamRole", err) + } + credentialAwsIamRoleWire = credentialAwsIamRoleConverted + } + case *ValidateStorageCredentialRequest_Credential_AzureServicePrincipal: + if value != nil { + credentialAzureServicePrincipalConverted, err := azureServicePrincipalToWire(&value.AzureServicePrincipal) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ValidateStorageCredentialRequest.Credential.AzureServicePrincipal", err) + } + credentialAzureServicePrincipalWire = credentialAzureServicePrincipalConverted + } + case *ValidateStorageCredentialRequest_Credential_AzureManagedIdentity: + if value != nil { + credentialAzureManagedIdentityConverted, err := azureManagedIdentityToWire(&value.AzureManagedIdentity) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ValidateStorageCredentialRequest.Credential.AzureManagedIdentity", err) + } + credentialAzureManagedIdentityWire = credentialAzureManagedIdentityConverted + } + case *ValidateStorageCredentialRequest_Credential_DatabricksGcpServiceAccount: + if value != nil { + credentialDatabricksGcpServiceAccountConverted, err := databricksGcpServiceAccountToWire(&value.DatabricksGcpServiceAccount) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ValidateStorageCredentialRequest.Credential.DatabricksGcpServiceAccount", err) + } + credentialDatabricksGcpServiceAccountWire = credentialDatabricksGcpServiceAccountConverted + } + case *ValidateStorageCredentialRequest_Credential_CloudflareApiToken: + if value != nil { + credentialCloudflareApiTokenConverted, err := cloudflareApiTokenToWire(&value.CloudflareApiToken) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ValidateStorageCredentialRequest.Credential.CloudflareApiToken", err) + } + credentialCloudflareApiTokenWire = credentialCloudflareApiTokenConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ValidateStorageCredentialRequest.Credential", value) + } + return &validateStorageCredentialRequestWire{ + StorageCredentialName: credentialStorageCredentialNameWire, + AwsIamRole: credentialAwsIamRoleWire, + AzureServicePrincipal: credentialAzureServicePrincipalWire, + AzureManagedIdentity: credentialAzureManagedIdentityWire, + DatabricksGcpServiceAccount: credentialDatabricksGcpServiceAccountWire, + CloudflareApiToken: credentialCloudflareApiTokenWire, + ExternalLocationName: v.ExternalLocationName, + Url: v.Url, + ReadOnly: v.ReadOnly, + }, nil +} + +type validateStorageCredentialRequest_ValidationResultWire struct { + Operation ValidateStorageCredentialRequest_FileOperation `json:"operation,omitempty"` + Result ValidateStorageCredentialRequest_Result `json:"result,omitempty"` + Message *string `json:"message,omitempty"` +} + +func validateStorageCredentialRequest_ValidationResultFromWire(w *validateStorageCredentialRequest_ValidationResultWire) (*ValidateStorageCredentialRequest_ValidationResult, error) { + if w == nil { + return nil, nil + } + return &ValidateStorageCredentialRequest_ValidationResult{ + Operation: w.Operation, + Result: w.Result, + Message: w.Message, + }, nil +} + +type validateStorageCredentialResponseWire struct { + IsDir *bool `json:"isDir,omitempty"` + Results []validateStorageCredentialRequest_ValidationResultWire `json:"results,omitempty"` +} + +func validateStorageCredentialResponseFromWire(w *validateStorageCredentialResponseWire) (*ValidateStorageCredentialResponse, error) { + if w == nil { + return nil, nil + } + resultsPublicValue, err := convertSlice(w.Results, validateStorageCredentialRequest_ValidationResultFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ValidateStorageCredentialResponse.Results", err) + } + return &ValidateStorageCredentialResponse{ + IsDir: w.IsDir, + Results: resultsPublicValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/entitytagassignments/.package.json b/uc/entitytagassignments/.package.json new file mode 100644 index 0000000..bd7e46b --- /dev/null +++ b/uc/entitytagassignments/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/entitytagassignments" +} diff --git a/uc/entitytagassignments/CHANGELOG.md b/uc/entitytagassignments/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/entitytagassignments/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/entitytagassignments/README.md b/uc/entitytagassignments/README.md new file mode 100644 index 0000000..99f0259 --- /dev/null +++ b/uc/entitytagassignments/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/entitytagassignments + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/entitytagassignments@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/entitytagassignments/v1" + +client, err := entitytagassignments.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/entitytagassignments/go.mod b/uc/entitytagassignments/go.mod new file mode 100644 index 0000000..784ceb5 --- /dev/null +++ b/uc/entitytagassignments/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/entitytagassignments + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/entitytagassignments/internal/version.go b/uc/entitytagassignments/internal/version.go new file mode 100644 index 0000000..0197cdc --- /dev/null +++ b/uc/entitytagassignments/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-entitytagassignments" + +const Version = "0.0.1-dev.1" diff --git a/uc/entitytagassignments/v1/client.go b/uc/entitytagassignments/v1/client.go new file mode 100755 index 0000000..6a7c465 --- /dev/null +++ b/uc/entitytagassignments/v1/client.go @@ -0,0 +1,488 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package entitytagassignments + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/entitytagassignments/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a tag assignment for an Unity Catalog entity. +// +// To add tags to Unity Catalog entities, you must own the entity or have the +// following privileges: - **APPLY TAG** on the entity - **USE SCHEMA** on the +// entity's parent schema - **USE CATALOG** on the entity's parent catalog +// +// To add a governed tag to Unity Catalog entities, you must also have the +// **ASSIGN** or **MANAGE** permission on the tag policy. See [Manage tag policy +// permissions]. +// +// [Manage tag policy permissions]: https://docs.databricks.com/aws/en/admin/tag-policies/manage-permissions +func (c *internalClient) CreateEntityTagAssignment(ctx context.Context, req *CreateEntityTagAssignmentRequest, opts ...call.Option) (*EntityTagAssignment, error) { + wireReq, err := createEntityTagAssignmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.TagAssignment) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/entity-tag-assignments" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EntityTagAssignment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp entityTagAssignmentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = entityTagAssignmentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a tag assignment for an Unity Catalog entity by its key. +// +// To delete tags from Unity Catalog entities, you must own the entity or have +// the following privileges: - **APPLY TAG** on the entity - **USE_SCHEMA** on +// the entity's parent schema - **USE_CATALOG** on the entity's parent catalog +// +// To delete a governed tag from Unity Catalog entities, you must also have the +// **ASSIGN** or **MANAGE** permission on the tag policy. See [Manage tag policy +// permissions]. +// +// [Manage tag policy permissions]: https://docs.databricks.com/aws/en/admin/tag-policies/manage-permissions +func (c *internalClient) DeleteEntityTagAssignment(ctx context.Context, req *DeleteEntityTagAssignmentRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/entity-tag-assignments/") + pb.singleSegment(*req.EntityType) + pb.literal("/") + pb.singleSegment(*req.EntityName) + pb.literal("/tags/") + pb.singleSegment(*req.TagKey) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets a tag assignment for an Unity Catalog entity by tag key. +func (c *internalClient) GetEntityTagAssignment(ctx context.Context, req *GetEntityTagAssignmentRequest, opts ...call.Option) (*EntityTagAssignment, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/entity-tag-assignments/") + pb.singleSegment(*req.EntityType) + pb.literal("/") + pb.singleSegment(*req.EntityName) + pb.literal("/tags/") + pb.singleSegment(*req.TagKey) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EntityTagAssignment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp entityTagAssignmentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = entityTagAssignmentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List tag assignments for an Unity Catalog entity +// +// PAGINATION BEHAVIOR: The API is by default paginated, a page may contain zero +// results while still providing a next_page_token. Clients must continue +// reading pages until next_page_token is absent, which is the only indication +// that the end of results has been reached. +func (c *internalClient) ListEntityTagAssignments(ctx context.Context, req *ListEntityTagAssignmentsRequest, opts ...call.Option) (*ListEntityTagAssignmentsResponse, error) { + wireReq, err := listEntityTagAssignmentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/entity-tag-assignments/") + pb.singleSegment(*req.EntityType) + pb.literal("/") + pb.singleSegment(*req.EntityName) + pb.literal("/tags") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListEntityTagAssignmentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listEntityTagAssignmentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listEntityTagAssignmentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListEntityTagAssignmentsIter returns an iterator that iterates +// over the results of ListEntityTagAssignments. +// +// For example: +// +// for item, err := range c.ListEntityTagAssignmentsIter(ctx, &ListEntityTagAssignmentsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListEntityTagAssignments call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListEntityTagAssignments directly. +func (c *internalClient) ListEntityTagAssignmentsIter(ctx context.Context, req *ListEntityTagAssignmentsRequest, opts ...call.Option) iter.Seq2[*EntityTagAssignment, error] { + return func(yield func(*EntityTagAssignment, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListEntityTagAssignmentsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListEntityTagAssignments(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.TagAssignments { + if !yield(&resp.TagAssignments[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates an existing tag assignment for an Unity Catalog entity. +// +// To update tags to Unity Catalog entities, you must own the entity or have the +// following privileges: - **APPLY TAG** on the entity - **USE SCHEMA** on the +// entity's parent schema - **USE CATALOG** on the entity's parent catalog +// +// To update a governed tag to Unity Catalog entities, you must also have the +// **ASSIGN** or **MANAGE** permission on the tag policy. See [Manage tag policy +// permissions]. +// +// [Manage tag policy permissions]: https://docs.databricks.com/aws/en/admin/tag-policies/manage-permissions +func (c *internalClient) UpdateEntityTagAssignment(ctx context.Context, req *UpdateEntityTagAssignmentRequest, opts ...call.Option) (*EntityTagAssignment, error) { + wireReq, err := updateEntityTagAssignmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.TagAssignment) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/entity-tag-assignments/") + pb.singleSegment(*req.TagAssignment.EntityType) + pb.literal("/") + pb.singleSegment(*req.TagAssignment.EntityName) + pb.literal("/tags/") + pb.singleSegment(*req.TagAssignment.TagKey) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EntityTagAssignment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp entityTagAssignmentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = entityTagAssignmentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/entitytagassignments/v1/genhelper.go b/uc/entitytagassignments/v1/genhelper.go new file mode 100755 index 0000000..4cf1f13 --- /dev/null +++ b/uc/entitytagassignments/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package entitytagassignments + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/entitytagassignments/v1/model.go b/uc/entitytagassignments/v1/model.go new file mode 100755 index 0000000..438c2c4 --- /dev/null +++ b/uc/entitytagassignments/v1/model.go @@ -0,0 +1,84 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package entitytagassignments + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// Enum representing the source type of a tag assignment +type TagAssignmentSourceType string + +const ( + TagAssignmentSourceType_Unspecified TagAssignmentSourceType = "" + // Automatically assigned by Data Classification + TagAssignmentSourceType_TagAssignmentSourceTypeSystemDataClassification TagAssignmentSourceType = "TAG_ASSIGNMENT_SOURCE_TYPE_SYSTEM_DATA_CLASSIFICATION" +) + +// Request to create a new entity tag assignment. +type CreateEntityTagAssignmentRequest struct { + TagAssignment *EntityTagAssignment +} + +// Request to delete an entity tag assignment. +type DeleteEntityTagAssignmentRequest struct { + // The fully qualified name of the entity to which the tag is assigned + EntityName *string + // Required. The key of the tag to delete + TagKey *string + // The type of the entity to which the tag is assigned. + EntityType *string +} + +// Represents a tag assignment to an entity. +type EntityTagAssignment struct { + // The fully qualified name of the entity to which the tag is assigned + EntityName *string `fieldmask:"entity_name"` + // The key of the tag + TagKey *string `fieldmask:"tag_key"` + // The value of the tag + TagValue *string `fieldmask:"tag_value"` + // The type of the entity to which the tag is assigned. + EntityType *string `fieldmask:"entity_type"` + // The timestamp when the tag assignment was last updated + UpdateTime *types.Time `fieldmask:"update_time"` + // The user or principal who updated the tag assignment + UpdatedBy *string `fieldmask:"updated_by"` + // The source type of the tag assignment, e.g., user-assigned or system-assigned + SourceType TagAssignmentSourceType `fieldmask:"source_type"` +} + +// Request to get an entity tag assignment. +type GetEntityTagAssignmentRequest struct { + // The fully qualified name of the entity to which the tag is assigned + EntityName *string + // Required. The key of the tag + TagKey *string + // The type of the entity to which the tag is assigned. + EntityType *string +} + +// Request to list entity tag assignments. +type ListEntityTagAssignmentsRequest struct { + // The fully qualified name of the entity to which the tag is assigned + EntityName *string + // Optional. Maximum number of tag assignments to return in a single page + MaxResults *int + // Optional. Pagination token to retrieve the next page of results + PageToken *string + // The type of the entity to which the tag is assigned. + EntityType *string +} + +type ListEntityTagAssignmentsResponse struct { + // The list of tag assignments + TagAssignments []EntityTagAssignment + // Optional. Pagination token for retrieving the next page of results + NextPageToken *string +} + +// Request to update an entity tag assignment. +type UpdateEntityTagAssignmentRequest struct { + TagAssignment *EntityTagAssignment + UpdateMask *types.FieldMask[EntityTagAssignment] +} diff --git a/uc/entitytagassignments/v1/wire.go b/uc/entitytagassignments/v1/wire.go new file mode 100755 index 0000000..5883ebd --- /dev/null +++ b/uc/entitytagassignments/v1/wire.go @@ -0,0 +1,146 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package entitytagassignments + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createEntityTagAssignmentRequestWire struct { + TagAssignment *entityTagAssignmentWire `json:"tag_assignment,omitempty"` +} + +func createEntityTagAssignmentRequestToWire(v *CreateEntityTagAssignmentRequest) (*createEntityTagAssignmentRequestWire, error) { + if v == nil { + return nil, nil + } + tagAssignmentWireValue, err := entityTagAssignmentToWire(v.TagAssignment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateEntityTagAssignmentRequest.TagAssignment", err) + } + return &createEntityTagAssignmentRequestWire{ + TagAssignment: tagAssignmentWireValue, + }, nil +} + +type entityTagAssignmentWire struct { + EntityName *string `json:"entity_name,omitempty"` + TagKey *string `json:"tag_key,omitempty"` + TagValue *string `json:"tag_value,omitempty"` + EntityType *string `json:"entity_type,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + SourceType TagAssignmentSourceType `json:"source_type,omitempty"` +} + +func entityTagAssignmentToWire(v *EntityTagAssignment) (*entityTagAssignmentWire, error) { + if v == nil { + return nil, nil + } + return &entityTagAssignmentWire{ + EntityName: v.EntityName, + TagKey: v.TagKey, + TagValue: v.TagValue, + EntityType: v.EntityType, + UpdateTime: v.UpdateTime, + UpdatedBy: v.UpdatedBy, + SourceType: v.SourceType, + }, nil +} + +func entityTagAssignmentFromWire(w *entityTagAssignmentWire) (*EntityTagAssignment, error) { + if w == nil { + return nil, nil + } + return &EntityTagAssignment{ + EntityName: w.EntityName, + TagKey: w.TagKey, + TagValue: w.TagValue, + EntityType: w.EntityType, + UpdateTime: w.UpdateTime, + UpdatedBy: w.UpdatedBy, + SourceType: w.SourceType, + }, nil +} + +type listEntityTagAssignmentsRequestWire struct { + EntityName *string `json:"entity_name,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` + EntityType *string `json:"entity_type,omitempty"` +} + +func listEntityTagAssignmentsRequestToWire(v *ListEntityTagAssignmentsRequest) (*listEntityTagAssignmentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listEntityTagAssignmentsRequestWire{ + EntityName: v.EntityName, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + EntityType: v.EntityType, + }, nil +} + +type listEntityTagAssignmentsResponseWire struct { + TagAssignments []entityTagAssignmentWire `json:"tag_assignments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listEntityTagAssignmentsResponseFromWire(w *listEntityTagAssignmentsResponseWire) (*ListEntityTagAssignmentsResponse, error) { + if w == nil { + return nil, nil + } + tagAssignmentsPublicValue, err := convertSlice(w.TagAssignments, entityTagAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListEntityTagAssignmentsResponse.TagAssignments", err) + } + return &ListEntityTagAssignmentsResponse{ + TagAssignments: tagAssignmentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type updateEntityTagAssignmentRequestWire struct { + TagAssignment *entityTagAssignmentWire `json:"tag_assignment,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateEntityTagAssignmentRequestToWire(v *UpdateEntityTagAssignmentRequest) (*updateEntityTagAssignmentRequestWire, error) { + if v == nil { + return nil, nil + } + tagAssignmentWireValue, err := entityTagAssignmentToWire(v.TagAssignment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateEntityTagAssignmentRequest.TagAssignment", err) + } + return &updateEntityTagAssignmentRequestWire{ + TagAssignment: tagAssignmentWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/externallineage/.package.json b/uc/externallineage/.package.json new file mode 100644 index 0000000..e461665 --- /dev/null +++ b/uc/externallineage/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/externallineage" +} diff --git a/uc/externallineage/CHANGELOG.md b/uc/externallineage/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/externallineage/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/externallineage/README.md b/uc/externallineage/README.md new file mode 100644 index 0000000..3a29157 --- /dev/null +++ b/uc/externallineage/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/externallineage + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/externallineage@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/externallineage/v1" + +client, err := externallineage.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/externallineage/go.mod b/uc/externallineage/go.mod new file mode 100644 index 0000000..1a1828d --- /dev/null +++ b/uc/externallineage/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/externallineage + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/externallineage/internal/version.go b/uc/externallineage/internal/version.go new file mode 100644 index 0000000..b18d27f --- /dev/null +++ b/uc/externallineage/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-externallineage" + +const Version = "0.0.1-dev.1" diff --git a/uc/externallineage/v1/client.go b/uc/externallineage/v1/client.go new file mode 100755 index 0000000..9bf2353 --- /dev/null +++ b/uc/externallineage/v1/client.go @@ -0,0 +1,388 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externallineage + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/externallineage/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates an external lineage relationship between a or external +// metadata object and another external metadata object. +func (c *internalClient) CreateExternalLineageRelationship(ctx context.Context, req *CreateExternalLineageRelationshipRequest, opts ...call.Option) (*ExternalLineageRelationship, error) { + wireReq, err := createExternalLineageRelationshipRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.ExternalLineageRelationship) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/lineage-tracking/external-lineage" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExternalLineageRelationship + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp externalLineageRelationshipWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = externalLineageRelationshipFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes an external lineage relationship between a or external +// metadata object and another external metadata object. +func (c *internalClient) DeleteExternalLineageRelationship(ctx context.Context, req *DeleteExternalLineageRelationshipRequest, opts ...call.Option) error { + wireReq, err := deleteExternalLineageRelationshipRequestToWire(req) + if err != nil { + return err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + baseURL.Path = "/api/2.0/lineage-tracking/external-lineage" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "external_lineage_relationship", wireReq.ExternalLineageRelationship); err != nil { + return err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Lists external lineage relationships of a object or external +// metadata given a supplied direction. +func (c *internalClient) ListExternalLineageRelationships(ctx context.Context, req *ListExternalLineageRelationshipsRequest, opts ...call.Option) (*ListExternalLineageRelationshipsResponse, error) { + wireReq, err := listExternalLineageRelationshipsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/lineage-tracking/external-lineage" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "object_info", wireReq.ObjectInfo); err != nil { + return nil, err + } + if wireReq.LineageDirection != "" { + if err := addQueryValue(queryParams, "lineage_direction", wireReq.LineageDirection); err != nil { + return nil, err + } + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListExternalLineageRelationshipsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listExternalLineageRelationshipsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listExternalLineageRelationshipsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListExternalLineageRelationshipsIter returns an iterator that iterates +// over the results of ListExternalLineageRelationships. +// +// For example: +// +// for item, err := range c.ListExternalLineageRelationshipsIter(ctx, &ListExternalLineageRelationshipsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListExternalLineageRelationships call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListExternalLineageRelationships directly. +func (c *internalClient) ListExternalLineageRelationshipsIter(ctx context.Context, req *ListExternalLineageRelationshipsRequest, opts ...call.Option) iter.Seq2[*ExternalLineageInfo, error] { + return func(yield func(*ExternalLineageInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListExternalLineageRelationshipsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListExternalLineageRelationships(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ExternalLineageRelationships { + if !yield(&resp.ExternalLineageRelationships[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates an external lineage relationship between a or external +// metadata object and another external metadata object. +func (c *internalClient) UpdateExternalLineageRelationship(ctx context.Context, req *UpdateExternalLineageRelationshipRequest, opts ...call.Option) (*ExternalLineageRelationship, error) { + wireReq, err := updateExternalLineageRelationshipRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.ExternalLineageRelationship) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/lineage-tracking/external-lineage" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExternalLineageRelationship + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp externalLineageRelationshipWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = externalLineageRelationshipFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/externallineage/v1/genhelper.go b/uc/externallineage/v1/genhelper.go new file mode 100755 index 0000000..d364c2c --- /dev/null +++ b/uc/externallineage/v1/genhelper.go @@ -0,0 +1,178 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externallineage + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} diff --git a/uc/externallineage/v1/model.go b/uc/externallineage/v1/model.go new file mode 100755 index 0000000..dde5f16 --- /dev/null +++ b/uc/externallineage/v1/model.go @@ -0,0 +1,263 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externallineage + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type SystemType string + +const ( + SystemType_Unspecified SystemType = "" + SystemType_Other SystemType = "OTHER" + SystemType_Tableau SystemType = "TABLEAU" + SystemType_PowerBi SystemType = "POWER_BI" + SystemType_Looker SystemType = "LOOKER" + SystemType_Kafka SystemType = "KAFKA" + SystemType_Sap SystemType = "SAP" + SystemType_Oracle SystemType = "ORACLE" + SystemType_Salesforce SystemType = "SALESFORCE" + SystemType_Workday SystemType = "WORKDAY" + SystemType_Mysql SystemType = "MYSQL" + SystemType_Postgresql SystemType = "POSTGRESQL" + SystemType_MicrosoftSqlServer SystemType = "MICROSOFT_SQL_SERVER" + SystemType_Servicenow SystemType = "SERVICENOW" + SystemType_AmazonRedshift SystemType = "AMAZON_REDSHIFT" + SystemType_AzureSynapse SystemType = "AZURE_SYNAPSE" + SystemType_Snowflake SystemType = "SNOWFLAKE" + SystemType_GoogleBigquery SystemType = "GOOGLE_BIGQUERY" + SystemType_MicrosoftFabric SystemType = "MICROSOFT_FABRIC" + SystemType_Mongodb SystemType = "MONGODB" + SystemType_Teradata SystemType = "TERADATA" + SystemType_Confluent SystemType = "CONFLUENT" + SystemType_Databricks SystemType = "DATABRICKS" + SystemType_StreamNative SystemType = "STREAM_NATIVE" +) + +type Direction_LineageDirection string + +const ( + Direction_LineageDirection_Unspecified Direction_LineageDirection = "" + Direction_LineageDirection_Upstream Direction_LineageDirection = "UPSTREAM" + Direction_LineageDirection_Downstream Direction_LineageDirection = "DOWNSTREAM" +) + +type ColumnRelationship struct { + Source *string + Target *string +} + +type CreateExternalLineageRelationshipRequest struct { + ExternalLineageRelationship *CreateRequestExternalLineage +} + +type CreateRequestExternalLineage struct { + // Unique identifier of the external lineage relationship. + Id *string + // Source object of the external lineage relationship. + Source *ExternalLineageRelationshipObject + // Target object of the external lineage relationship. + Target *ExternalLineageRelationshipObject + // List of column relationships between source and target objects. + Columns []ColumnRelationship + // Key-value properties associated with the external lineage relationship. + Properties map[string]string +} + +type DeleteExternalLineageRelationshipRequest struct { + ExternalLineageRelationship *DeleteRequestExternalLineage +} + +type DeleteRequestExternalLineage struct { + // Unique identifier of the external lineage relationship. + Id *string + // Source object of the external lineage relationship. + Source *ExternalLineageRelationshipObject + // Target object of the external lineage relationship. + Target *ExternalLineageRelationshipObject + // List of column relationships between source and target objects. + Columns []ColumnRelationship + // Key-value properties associated with the external lineage relationship. + Properties map[string]string +} + +// Represents the direction of lineage in a lineage event.. +type Direction struct { +} + +// Lineage response containing lineage information of a data asset.. +type ExternalLineageInfo struct { + // Information about the table involved in the lineage relationship. + TableInfo *LineageTableInfo + // Information about the file involved in the lineage relationship. + FileInfo *LineageFileInfo + // Information about the model version involved in the lineage relationship. + ModelInfo *LineageModelVersionInfo + // Information about external metadata involved in the lineage relationship. + ExternalMetadataInfo *LineageExternalMetadataInfo + // Information about the edge metadata of the external lineage relationship. + ExternalLineageInfo *ExternalLineageRelationship +} + +type ExternalLineageRelationship struct { + // Unique identifier of the external lineage relationship. + Id *string + // Source object of the external lineage relationship. + Source *ExternalLineageRelationshipObject + // Target object of the external lineage relationship. + Target *ExternalLineageRelationshipObject + // List of column relationships between source and target objects. + Columns []ColumnRelationship + // Key-value properties associated with the external lineage relationship. + Properties map[string]string +} + +type ExternalLineageRelationshipExternalMetadata struct { + Name *string `fieldmask:"name"` +} + +type ExternalLineageRelationshipModelVersion struct { + Name *string `fieldmask:"name"` + Version *string `fieldmask:"version"` +} + +type ExternalLineageRelationshipObject struct { + Tpe isExternalLineageRelationshipObject_Tpe + _ [0]externalLineageRelationshipObjectTpeFieldMaskMetadata `fieldmask_oneof:"Tpe"` +} + +type isExternalLineageRelationshipObject_Tpe interface { + isExternalLineageRelationshipObject_Tpe() +} + +// ExternalLineageRelationshipObject_Tpe_Table selects Table for ExternalLineageRelationshipObject.Tpe. +type ExternalLineageRelationshipObject_Tpe_Table struct { + Table ExternalLineageRelationshipTable `fieldmask:"table"` +} + +func (*ExternalLineageRelationshipObject_Tpe_Table) isExternalLineageRelationshipObject_Tpe() {} + +// ExternalLineageRelationshipObject_Tpe_Path selects Path for ExternalLineageRelationshipObject.Tpe. +type ExternalLineageRelationshipObject_Tpe_Path struct { + Path ExternalLineageRelationshipPath `fieldmask:"path"` +} + +func (*ExternalLineageRelationshipObject_Tpe_Path) isExternalLineageRelationshipObject_Tpe() {} + +// ExternalLineageRelationshipObject_Tpe_ModelVersion selects ModelVersion for ExternalLineageRelationshipObject.Tpe. +type ExternalLineageRelationshipObject_Tpe_ModelVersion struct { + ModelVersion ExternalLineageRelationshipModelVersion `fieldmask:"model_version"` +} + +func (*ExternalLineageRelationshipObject_Tpe_ModelVersion) isExternalLineageRelationshipObject_Tpe() { +} + +// ExternalLineageRelationshipObject_Tpe_ExternalMetadata selects ExternalMetadata for ExternalLineageRelationshipObject.Tpe. +type ExternalLineageRelationshipObject_Tpe_ExternalMetadata struct { + ExternalMetadata ExternalLineageRelationshipExternalMetadata `fieldmask:"external_metadata"` +} + +func (*ExternalLineageRelationshipObject_Tpe_ExternalMetadata) isExternalLineageRelationshipObject_Tpe() { +} + +type externalLineageRelationshipObjectTpeFieldMaskMetadata struct { + *ExternalLineageRelationshipObject_Tpe_Table + *ExternalLineageRelationshipObject_Tpe_Path + *ExternalLineageRelationshipObject_Tpe_ModelVersion + *ExternalLineageRelationshipObject_Tpe_ExternalMetadata +} + +type ExternalLineageRelationshipPath struct { + Url *string `fieldmask:"url"` +} + +type ExternalLineageRelationshipTable struct { + Name *string `fieldmask:"name"` +} + +// Represents the external metadata object in the lineage event.. +type LineageExternalMetadataInfo struct { + // Name of the external metadata object. + Name *string + // Type of external system. + SystemType SystemType + // Type of entity represented by the external metadata object. + EntityType *string + // Timestamp of the lineage event. + EventTime *types.Time +} + +// Represents the path information in the lineage event.. +type LineageFileInfo struct { + // URL of the path. + Path *string + // The full name of the securable on the path. + SecurableName *string + // The storage location associated with securable on the path. + StorageLocation *string + // The securable type of the securable on the path. + SecurableType *string + // Timestamp of the lineage event. + EventTime *types.Time +} + +// Represents the model version information in the lineage event.. +type LineageModelVersionInfo struct { + // Name of the model. + ModelName *string + // Version number of the model. + Version *int64 + // Timestamp of the lineage event. + EventTime *types.Time +} + +// Represents the table information in the lineage event.. +type LineageTableInfo struct { + // Name of Table. + Name *string + // Name of Catalog. + CatalogName *string + // Name of Schema. + SchemaName *string + // Timestamp of the lineage event. + EventTime *types.Time +} + +type ListExternalLineageRelationshipsRequest struct { + // The object to query external lineage relationships for. Since this field is a + // query parameter, please flatten the nested fields. For example, if the object + // is a table, the query parameter should look like: + // `object_info.table.name=main.sales.customers` + ObjectInfo *ExternalLineageRelationshipObject + // The lineage direction to filter on. + LineageDirection Direction_LineageDirection + // Specifies the maximum number of external lineage relationships to return in a + // single response. The value must be less than or equal to 1000. + PageSize *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListExternalLineageRelationshipsResponse struct { + ExternalLineageRelationships []ExternalLineageInfo + NextPageToken *string +} + +type UpdateExternalLineageRelationshipRequest struct { + ExternalLineageRelationship *UpdateRequestExternalLineage + UpdateMask *types.FieldMask[UpdateRequestExternalLineage] +} + +type UpdateRequestExternalLineage struct { + // Unique identifier of the external lineage relationship. + Id *string `fieldmask:"id"` + // Source object of the external lineage relationship. + Source *ExternalLineageRelationshipObject `fieldmask:"source"` + // Target object of the external lineage relationship. + Target *ExternalLineageRelationshipObject `fieldmask:"target"` + // List of column relationships between source and target objects. + Columns []ColumnRelationship `fieldmask:"columns"` + // Key-value properties associated with the external lineage relationship. + Properties map[string]string `fieldmask:"properties"` +} diff --git a/uc/externallineage/v1/wire.go b/uc/externallineage/v1/wire.go new file mode 100755 index 0000000..dd42a37 --- /dev/null +++ b/uc/externallineage/v1/wire.go @@ -0,0 +1,604 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externallineage + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type columnRelationshipWire struct { + Source *string `json:"source,omitempty"` + Target *string `json:"target,omitempty"` +} + +func columnRelationshipToWire(v *ColumnRelationship) (*columnRelationshipWire, error) { + if v == nil { + return nil, nil + } + return &columnRelationshipWire{ + Source: v.Source, + Target: v.Target, + }, nil +} + +func columnRelationshipFromWire(w *columnRelationshipWire) (*ColumnRelationship, error) { + if w == nil { + return nil, nil + } + return &ColumnRelationship{ + Source: w.Source, + Target: w.Target, + }, nil +} + +type createExternalLineageRelationshipRequestWire struct { + ExternalLineageRelationship *createRequestExternalLineageWire `json:"external_lineage_relationship,omitempty"` +} + +func createExternalLineageRelationshipRequestToWire(v *CreateExternalLineageRelationshipRequest) (*createExternalLineageRelationshipRequestWire, error) { + if v == nil { + return nil, nil + } + externalLineageRelationshipWireValue, err := createRequestExternalLineageToWire(v.ExternalLineageRelationship) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExternalLineageRelationshipRequest.ExternalLineageRelationship", err) + } + return &createExternalLineageRelationshipRequestWire{ + ExternalLineageRelationship: externalLineageRelationshipWireValue, + }, nil +} + +type createRequestExternalLineageWire struct { + Id *string `json:"id,omitempty"` + Source *externalLineageRelationshipObjectWire `json:"source,omitempty"` + Target *externalLineageRelationshipObjectWire `json:"target,omitempty"` + Columns []columnRelationshipWire `json:"columns,omitempty"` + Properties map[string]string `json:"properties,omitempty"` +} + +func createRequestExternalLineageToWire(v *CreateRequestExternalLineage) (*createRequestExternalLineageWire, error) { + if v == nil { + return nil, nil + } + sourceWireValue, err := externalLineageRelationshipObjectToWire(v.Source) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRequestExternalLineage.Source", err) + } + targetWireValue, err := externalLineageRelationshipObjectToWire(v.Target) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRequestExternalLineage.Target", err) + } + columnsWireValue, err := convertSlice(v.Columns, columnRelationshipToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRequestExternalLineage.Columns", err) + } + return &createRequestExternalLineageWire{ + Id: v.Id, + Source: sourceWireValue, + Target: targetWireValue, + Columns: columnsWireValue, + Properties: v.Properties, + }, nil +} + +type deleteExternalLineageRelationshipRequestWire struct { + ExternalLineageRelationship *deleteRequestExternalLineageWire `json:"external_lineage_relationship,omitempty"` +} + +func deleteExternalLineageRelationshipRequestToWire(v *DeleteExternalLineageRelationshipRequest) (*deleteExternalLineageRelationshipRequestWire, error) { + if v == nil { + return nil, nil + } + externalLineageRelationshipWireValue, err := deleteRequestExternalLineageToWire(v.ExternalLineageRelationship) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeleteExternalLineageRelationshipRequest.ExternalLineageRelationship", err) + } + return &deleteExternalLineageRelationshipRequestWire{ + ExternalLineageRelationship: externalLineageRelationshipWireValue, + }, nil +} + +type deleteRequestExternalLineageWire struct { + Id *string `json:"id,omitempty"` + Source *externalLineageRelationshipObjectWire `json:"source,omitempty"` + Target *externalLineageRelationshipObjectWire `json:"target,omitempty"` + Columns []columnRelationshipWire `json:"columns,omitempty"` + Properties map[string]string `json:"properties,omitempty"` +} + +func deleteRequestExternalLineageToWire(v *DeleteRequestExternalLineage) (*deleteRequestExternalLineageWire, error) { + if v == nil { + return nil, nil + } + sourceWireValue, err := externalLineageRelationshipObjectToWire(v.Source) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeleteRequestExternalLineage.Source", err) + } + targetWireValue, err := externalLineageRelationshipObjectToWire(v.Target) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeleteRequestExternalLineage.Target", err) + } + columnsWireValue, err := convertSlice(v.Columns, columnRelationshipToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeleteRequestExternalLineage.Columns", err) + } + return &deleteRequestExternalLineageWire{ + Id: v.Id, + Source: sourceWireValue, + Target: targetWireValue, + Columns: columnsWireValue, + Properties: v.Properties, + }, nil +} + +type externalLineageInfoWire struct { + TableInfo *lineageTableInfoWire `json:"table_info,omitempty"` + FileInfo *lineageFileInfoWire `json:"file_info,omitempty"` + ModelInfo *lineageModelVersionInfoWire `json:"model_info,omitempty"` + ExternalMetadataInfo *lineageExternalMetadataInfoWire `json:"external_metadata_info,omitempty"` + ExternalLineageInfo *externalLineageRelationshipWire `json:"external_lineage_info,omitempty"` +} + +func externalLineageInfoFromWire(w *externalLineageInfoWire) (*ExternalLineageInfo, error) { + if w == nil { + return nil, nil + } + tableInfoPublicValue, err := lineageTableInfoFromWire(w.TableInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageInfo.TableInfo", err) + } + fileInfoPublicValue, err := lineageFileInfoFromWire(w.FileInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageInfo.FileInfo", err) + } + modelInfoPublicValue, err := lineageModelVersionInfoFromWire(w.ModelInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageInfo.ModelInfo", err) + } + externalMetadataInfoPublicValue, err := lineageExternalMetadataInfoFromWire(w.ExternalMetadataInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageInfo.ExternalMetadataInfo", err) + } + externalLineageInfoPublicValue, err := externalLineageRelationshipFromWire(w.ExternalLineageInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageInfo.ExternalLineageInfo", err) + } + return &ExternalLineageInfo{ + TableInfo: tableInfoPublicValue, + FileInfo: fileInfoPublicValue, + ModelInfo: modelInfoPublicValue, + ExternalMetadataInfo: externalMetadataInfoPublicValue, + ExternalLineageInfo: externalLineageInfoPublicValue, + }, nil +} + +type externalLineageRelationshipWire struct { + Id *string `json:"id,omitempty"` + Source *externalLineageRelationshipObjectWire `json:"source,omitempty"` + Target *externalLineageRelationshipObjectWire `json:"target,omitempty"` + Columns []columnRelationshipWire `json:"columns,omitempty"` + Properties map[string]string `json:"properties,omitempty"` +} + +func externalLineageRelationshipFromWire(w *externalLineageRelationshipWire) (*ExternalLineageRelationship, error) { + if w == nil { + return nil, nil + } + sourcePublicValue, err := externalLineageRelationshipObjectFromWire(w.Source) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationship.Source", err) + } + targetPublicValue, err := externalLineageRelationshipObjectFromWire(w.Target) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationship.Target", err) + } + columnsPublicValue, err := convertSlice(w.Columns, columnRelationshipFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationship.Columns", err) + } + return &ExternalLineageRelationship{ + Id: w.Id, + Source: sourcePublicValue, + Target: targetPublicValue, + Columns: columnsPublicValue, + Properties: w.Properties, + }, nil +} + +type externalLineageRelationshipExternalMetadataWire struct { + Name *string `json:"name,omitempty"` +} + +func externalLineageRelationshipExternalMetadataToWire(v *ExternalLineageRelationshipExternalMetadata) (*externalLineageRelationshipExternalMetadataWire, error) { + if v == nil { + return nil, nil + } + return &externalLineageRelationshipExternalMetadataWire{ + Name: v.Name, + }, nil +} + +func externalLineageRelationshipExternalMetadataFromWire(w *externalLineageRelationshipExternalMetadataWire) (*ExternalLineageRelationshipExternalMetadata, error) { + if w == nil { + return nil, nil + } + return &ExternalLineageRelationshipExternalMetadata{ + Name: w.Name, + }, nil +} + +type externalLineageRelationshipModelVersionWire struct { + Name *string `json:"name,omitempty"` + Version *string `json:"version,omitempty"` +} + +func externalLineageRelationshipModelVersionToWire(v *ExternalLineageRelationshipModelVersion) (*externalLineageRelationshipModelVersionWire, error) { + if v == nil { + return nil, nil + } + return &externalLineageRelationshipModelVersionWire{ + Name: v.Name, + Version: v.Version, + }, nil +} + +func externalLineageRelationshipModelVersionFromWire(w *externalLineageRelationshipModelVersionWire) (*ExternalLineageRelationshipModelVersion, error) { + if w == nil { + return nil, nil + } + return &ExternalLineageRelationshipModelVersion{ + Name: w.Name, + Version: w.Version, + }, nil +} + +type externalLineageRelationshipObjectWire struct { + Table *externalLineageRelationshipTableWire `json:"table,omitempty"` + Path *externalLineageRelationshipPathWire `json:"path,omitempty"` + ModelVersion *externalLineageRelationshipModelVersionWire `json:"model_version,omitempty"` + ExternalMetadata *externalLineageRelationshipExternalMetadataWire `json:"external_metadata,omitempty"` +} + +func externalLineageRelationshipObjectToWire(v *ExternalLineageRelationshipObject) (*externalLineageRelationshipObjectWire, error) { + if v == nil { + return nil, nil + } + var tpeTableWire *externalLineageRelationshipTableWire + var tpePathWire *externalLineageRelationshipPathWire + var tpeModelVersionWire *externalLineageRelationshipModelVersionWire + var tpeExternalMetadataWire *externalLineageRelationshipExternalMetadataWire + switch value := v.Tpe.(type) { + case nil: + case *ExternalLineageRelationshipObject_Tpe_Table: + if value != nil { + tpeTableConverted, err := externalLineageRelationshipTableToWire(&value.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationshipObject.Tpe.Table", err) + } + tpeTableWire = tpeTableConverted + } + case *ExternalLineageRelationshipObject_Tpe_Path: + if value != nil { + tpePathConverted, err := externalLineageRelationshipPathToWire(&value.Path) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationshipObject.Tpe.Path", err) + } + tpePathWire = tpePathConverted + } + case *ExternalLineageRelationshipObject_Tpe_ModelVersion: + if value != nil { + tpeModelVersionConverted, err := externalLineageRelationshipModelVersionToWire(&value.ModelVersion) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationshipObject.Tpe.ModelVersion", err) + } + tpeModelVersionWire = tpeModelVersionConverted + } + case *ExternalLineageRelationshipObject_Tpe_ExternalMetadata: + if value != nil { + tpeExternalMetadataConverted, err := externalLineageRelationshipExternalMetadataToWire(&value.ExternalMetadata) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationshipObject.Tpe.ExternalMetadata", err) + } + tpeExternalMetadataWire = tpeExternalMetadataConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "ExternalLineageRelationshipObject.Tpe", value) + } + return &externalLineageRelationshipObjectWire{ + Table: tpeTableWire, + Path: tpePathWire, + ModelVersion: tpeModelVersionWire, + ExternalMetadata: tpeExternalMetadataWire, + }, nil +} + +func externalLineageRelationshipObjectFromWire(w *externalLineageRelationshipObjectWire) (*ExternalLineageRelationshipObject, error) { + if w == nil { + return nil, nil + } + tpeMembers := 0 + if w.Table != nil { + tpeMembers++ + } + if w.Path != nil { + tpeMembers++ + } + if w.ModelVersion != nil { + tpeMembers++ + } + if w.ExternalMetadata != nil { + tpeMembers++ + } + if tpeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "ExternalLineageRelationshipObject.Tpe") + } + var tpeSelection isExternalLineageRelationshipObject_Tpe + switch { + case w.Table != nil: + tpeTableConverted, err := externalLineageRelationshipTableFromWire(w.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationshipObject.Tpe.Table", err) + } + tpeSelection = &ExternalLineageRelationshipObject_Tpe_Table{Table: *tpeTableConverted} + case w.Path != nil: + tpePathConverted, err := externalLineageRelationshipPathFromWire(w.Path) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationshipObject.Tpe.Path", err) + } + tpeSelection = &ExternalLineageRelationshipObject_Tpe_Path{Path: *tpePathConverted} + case w.ModelVersion != nil: + tpeModelVersionConverted, err := externalLineageRelationshipModelVersionFromWire(w.ModelVersion) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationshipObject.Tpe.ModelVersion", err) + } + tpeSelection = &ExternalLineageRelationshipObject_Tpe_ModelVersion{ModelVersion: *tpeModelVersionConverted} + case w.ExternalMetadata != nil: + tpeExternalMetadataConverted, err := externalLineageRelationshipExternalMetadataFromWire(w.ExternalMetadata) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLineageRelationshipObject.Tpe.ExternalMetadata", err) + } + tpeSelection = &ExternalLineageRelationshipObject_Tpe_ExternalMetadata{ExternalMetadata: *tpeExternalMetadataConverted} + } + return &ExternalLineageRelationshipObject{ + Tpe: tpeSelection, + }, nil +} + +type externalLineageRelationshipPathWire struct { + Url *string `json:"url,omitempty"` +} + +func externalLineageRelationshipPathToWire(v *ExternalLineageRelationshipPath) (*externalLineageRelationshipPathWire, error) { + if v == nil { + return nil, nil + } + return &externalLineageRelationshipPathWire{ + Url: v.Url, + }, nil +} + +func externalLineageRelationshipPathFromWire(w *externalLineageRelationshipPathWire) (*ExternalLineageRelationshipPath, error) { + if w == nil { + return nil, nil + } + return &ExternalLineageRelationshipPath{ + Url: w.Url, + }, nil +} + +type externalLineageRelationshipTableWire struct { + Name *string `json:"name,omitempty"` +} + +func externalLineageRelationshipTableToWire(v *ExternalLineageRelationshipTable) (*externalLineageRelationshipTableWire, error) { + if v == nil { + return nil, nil + } + return &externalLineageRelationshipTableWire{ + Name: v.Name, + }, nil +} + +func externalLineageRelationshipTableFromWire(w *externalLineageRelationshipTableWire) (*ExternalLineageRelationshipTable, error) { + if w == nil { + return nil, nil + } + return &ExternalLineageRelationshipTable{ + Name: w.Name, + }, nil +} + +type lineageExternalMetadataInfoWire struct { + Name *string `json:"name,omitempty"` + SystemType SystemType `json:"system_type,omitempty"` + EntityType *string `json:"entity_type,omitempty"` + EventTime *types.Time `json:"event_time,omitempty"` +} + +func lineageExternalMetadataInfoFromWire(w *lineageExternalMetadataInfoWire) (*LineageExternalMetadataInfo, error) { + if w == nil { + return nil, nil + } + return &LineageExternalMetadataInfo{ + Name: w.Name, + SystemType: w.SystemType, + EntityType: w.EntityType, + EventTime: w.EventTime, + }, nil +} + +type lineageFileInfoWire struct { + Path *string `json:"path,omitempty"` + SecurableName *string `json:"securable_name,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + SecurableType *string `json:"securable_type,omitempty"` + EventTime *types.Time `json:"event_time,omitempty"` +} + +func lineageFileInfoFromWire(w *lineageFileInfoWire) (*LineageFileInfo, error) { + if w == nil { + return nil, nil + } + return &LineageFileInfo{ + Path: w.Path, + SecurableName: w.SecurableName, + StorageLocation: w.StorageLocation, + SecurableType: w.SecurableType, + EventTime: w.EventTime, + }, nil +} + +type lineageModelVersionInfoWire struct { + ModelName *string `json:"model_name,omitempty"` + Version *int64 `json:"version,omitempty"` + EventTime *types.Time `json:"event_time,omitempty"` +} + +func lineageModelVersionInfoFromWire(w *lineageModelVersionInfoWire) (*LineageModelVersionInfo, error) { + if w == nil { + return nil, nil + } + return &LineageModelVersionInfo{ + ModelName: w.ModelName, + Version: w.Version, + EventTime: w.EventTime, + }, nil +} + +type lineageTableInfoWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + EventTime *types.Time `json:"event_time,omitempty"` +} + +func lineageTableInfoFromWire(w *lineageTableInfoWire) (*LineageTableInfo, error) { + if w == nil { + return nil, nil + } + return &LineageTableInfo{ + Name: w.Name, + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + EventTime: w.EventTime, + }, nil +} + +type listExternalLineageRelationshipsRequestWire struct { + ObjectInfo *externalLineageRelationshipObjectWire `json:"object_info,omitempty"` + LineageDirection Direction_LineageDirection `json:"lineage_direction,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listExternalLineageRelationshipsRequestToWire(v *ListExternalLineageRelationshipsRequest) (*listExternalLineageRelationshipsRequestWire, error) { + if v == nil { + return nil, nil + } + objectInfoWireValue, err := externalLineageRelationshipObjectToWire(v.ObjectInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListExternalLineageRelationshipsRequest.ObjectInfo", err) + } + return &listExternalLineageRelationshipsRequestWire{ + ObjectInfo: objectInfoWireValue, + LineageDirection: v.LineageDirection, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listExternalLineageRelationshipsResponseWire struct { + ExternalLineageRelationships []externalLineageInfoWire `json:"external_lineage_relationships,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listExternalLineageRelationshipsResponseFromWire(w *listExternalLineageRelationshipsResponseWire) (*ListExternalLineageRelationshipsResponse, error) { + if w == nil { + return nil, nil + } + externalLineageRelationshipsPublicValue, err := convertSlice(w.ExternalLineageRelationships, externalLineageInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListExternalLineageRelationshipsResponse.ExternalLineageRelationships", err) + } + return &ListExternalLineageRelationshipsResponse{ + ExternalLineageRelationships: externalLineageRelationshipsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type updateExternalLineageRelationshipRequestWire struct { + ExternalLineageRelationship *updateRequestExternalLineageWire `json:"external_lineage_relationship,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateExternalLineageRelationshipRequestToWire(v *UpdateExternalLineageRelationshipRequest) (*updateExternalLineageRelationshipRequestWire, error) { + if v == nil { + return nil, nil + } + externalLineageRelationshipWireValue, err := updateRequestExternalLineageToWire(v.ExternalLineageRelationship) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExternalLineageRelationshipRequest.ExternalLineageRelationship", err) + } + return &updateExternalLineageRelationshipRequestWire{ + ExternalLineageRelationship: externalLineageRelationshipWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type updateRequestExternalLineageWire struct { + Id *string `json:"id,omitempty"` + Source *externalLineageRelationshipObjectWire `json:"source,omitempty"` + Target *externalLineageRelationshipObjectWire `json:"target,omitempty"` + Columns []columnRelationshipWire `json:"columns,omitempty"` + Properties map[string]string `json:"properties,omitempty"` +} + +func updateRequestExternalLineageToWire(v *UpdateRequestExternalLineage) (*updateRequestExternalLineageWire, error) { + if v == nil { + return nil, nil + } + sourceWireValue, err := externalLineageRelationshipObjectToWire(v.Source) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRequestExternalLineage.Source", err) + } + targetWireValue, err := externalLineageRelationshipObjectToWire(v.Target) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRequestExternalLineage.Target", err) + } + columnsWireValue, err := convertSlice(v.Columns, columnRelationshipToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRequestExternalLineage.Columns", err) + } + return &updateRequestExternalLineageWire{ + Id: v.Id, + Source: sourceWireValue, + Target: targetWireValue, + Columns: columnsWireValue, + Properties: v.Properties, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/externallocations/.package.json b/uc/externallocations/.package.json new file mode 100644 index 0000000..69231ab --- /dev/null +++ b/uc/externallocations/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/externallocations" +} diff --git a/uc/externallocations/CHANGELOG.md b/uc/externallocations/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/externallocations/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/externallocations/README.md b/uc/externallocations/README.md new file mode 100644 index 0000000..489b841 --- /dev/null +++ b/uc/externallocations/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/externallocations + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/externallocations@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/externallocations/v1" + +client, err := externallocations.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/externallocations/go.mod b/uc/externallocations/go.mod new file mode 100644 index 0000000..fa3494d --- /dev/null +++ b/uc/externallocations/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/externallocations + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/externallocations/internal/version.go b/uc/externallocations/internal/version.go new file mode 100644 index 0000000..6baf02b --- /dev/null +++ b/uc/externallocations/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-externallocations" + +const Version = "0.0.1-dev.1" diff --git a/uc/externallocations/v1/client.go b/uc/externallocations/v1/client.go new file mode 100755 index 0000000..4a1dcdd --- /dev/null +++ b/uc/externallocations/v1/client.go @@ -0,0 +1,474 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externallocations + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/externallocations/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new external location entry in the metastore. The caller must be a +// metastore admin or have the **CREATE_EXTERNAL_LOCATION** privilege on both +// the metastore and the associated storage credential. +func (c *internalClient) CreateExternalLocation(ctx context.Context, req *CreateExternalLocationRequest, opts ...call.Option) (*ExternalLocationInfo, error) { + wireReq, err := createExternalLocationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/external-locations" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExternalLocationInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp externalLocationInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = externalLocationInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the specified external location from the metastore. The caller must +// be the owner of the external location. +func (c *internalClient) DeleteExternalLocation(ctx context.Context, req *DeleteExternalLocationRequest, opts ...call.Option) (*DeleteExternalLocationResponse, error) { + wireReq, err := deleteExternalLocationRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/external-locations/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteExternalLocationResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteExternalLocationResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an external location from the metastore. The caller must be either a +// metastore admin, the owner of the external location, or a user that has some +// privilege on the external location. +func (c *internalClient) GetExternalLocation(ctx context.Context, req *GetExternalLocationRequest, opts ...call.Option) (*ExternalLocationInfo, error) { + wireReq, err := getExternalLocationRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/external-locations/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExternalLocationInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp externalLocationInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = externalLocationInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of external locations (__ExternalLocationInfo__ objects) from +// the metastore. The caller must be a metastore admin, the owner of the +// external location, or a user that has some privilege on the external +// location. There is no guarantee of a specific ordering of the elements in the +// array. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) ListExternalLocations(ctx context.Context, req *ListExternalLocationsRequest, opts ...call.Option) (*ListExternalLocationsResponse, error) { + wireReq, err := listExternalLocationsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/external-locations" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_unbound", wireReq.IncludeUnbound); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListExternalLocationsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listExternalLocationsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listExternalLocationsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListExternalLocationsIter returns an iterator that iterates +// over the results of ListExternalLocations. +// +// For example: +// +// for item, err := range c.ListExternalLocationsIter(ctx, &ListExternalLocationsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListExternalLocations call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListExternalLocations directly. +func (c *internalClient) ListExternalLocationsIter(ctx context.Context, req *ListExternalLocationsRequest, opts ...call.Option) iter.Seq2[*ExternalLocationInfo, error] { + return func(yield func(*ExternalLocationInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListExternalLocationsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListExternalLocations(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ExternalLocations { + if !yield(&resp.ExternalLocations[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates an external location in the metastore. The caller must be the owner +// of the external location, or be a metastore admin. In the second case, the +// admin can only update the name of the external location. +func (c *internalClient) UpdateExternalLocation(ctx context.Context, req *UpdateExternalLocationRequest, opts ...call.Option) (*ExternalLocationInfo, error) { + wireReq, err := updateExternalLocationRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/external-locations/") + pb.singleSegment(*req.NameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExternalLocationInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp externalLocationInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = externalLocationInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/externallocations/v1/genhelper.go b/uc/externallocations/v1/genhelper.go new file mode 100755 index 0000000..c3b1afb --- /dev/null +++ b/uc/externallocations/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externallocations + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/externallocations/v1/model.go b/uc/externallocations/v1/model.go new file mode 100755 index 0000000..dedf579 --- /dev/null +++ b/uc/externallocations/v1/model.go @@ -0,0 +1,358 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externallocations + +type IsolationMode string + +const ( + IsolationMode_Unspecified IsolationMode = "" + IsolationMode_IsolationModeOpen IsolationMode = "ISOLATION_MODE_OPEN" + IsolationMode_IsolationModeIsolated IsolationMode = "ISOLATION_MODE_ISOLATED" +) + +type SseEncryptionAlgorithm string + +const ( + SseEncryptionAlgorithm_Unspecified SseEncryptionAlgorithm = "" + SseEncryptionAlgorithm_AwsSseS3 SseEncryptionAlgorithm = "AWS_SSE_S3" + SseEncryptionAlgorithm_AwsSseKms SseEncryptionAlgorithm = "AWS_SSE_KMS" +) + +type AwsSqsQueue struct { + // The AQS queue url in the format https://sqs.{region}.amazonaws.com/{account + // id}/{queue name}. Only required for provided_sqs. + QueueUrl *string + // Unique identifier included in the name of file events managed cloud + // resources. + ManagedResourceId *string +} + +type AzureQueueStorage struct { + // The AQS queue url in the format https://{storage + // account}.queue.core.windows.net/{queue name} Only required for provided_aqs. + QueueUrl *string + // Optional subscription id for the queue, event grid subscription, and external + // location storage account. Required for locations with a service principal + // storage credential + SubscriptionId *string + // Optional resource group for the queue, event grid subscription, and external + // location storage account. Only required for locations with a service + // principal storage credential + ResourceGroup *string + // Unique identifier included in the name of file events managed cloud + // resources. + ManagedResourceId *string +} + +type CreateExternalLocationRequest struct { + // Skips validation of the storage credential associated with the external + // location. + SkipValidation *bool + // Name of the external location. + Name *string + // Path URL of the external location. + Url *string + // Name of the storage credential used with this location. + CredentialName *string + // Indicates whether the external location is read-only. + ReadOnly *bool + // User-provided free-form text description. + Comment *string + // Whether to enable file events on this external location. Default to `true`. + // Set to `false` to disable file events. The actual applied value may differ + // due to server-side defaults; check `effective_enable_file_events` for the + // effective state. + EnableFileEvents *bool + // File event queue settings. If `enable_file_events` is not `false`, must be + // defined and have exactly one of the documented properties. + FileEventQueue *FileEventQueue + // The owner of the external location. + Owner *string + EncryptionDetails *EncryptionDetails + // Unique identifier of metastore hosting the external location. + MetastoreId *string + // Unique ID of the location's storage credential. + CredentialId *string + // Time at which this external location was created, in epoch milliseconds. + CreatedAt *int64 + // Username of external location creator. + CreatedBy *string + // Time at which external location this was last modified, in epoch + // milliseconds. + UpdatedAt *int64 + // Username of user who last modified the external location. + UpdatedBy *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + IsolationMode IsolationMode + // Indicates whether fallback mode is enabled for this external location. When + // fallback mode is enabled, the access to the location falls back to cluster + // credentials if UC credentials are not sufficient. + Fallback *bool + // The effective value of `enable_file_events` after applying server-side + // defaults. + EffectiveEnableFileEvents *bool + // The effective file event queue configuration after applying server-side + // defaults. Always populated when a queue is provisioned, regardless of whether + // the user explicitly set `enable_file_events`. Use this field instead of + // `file_event_queue` for reading the actual queue state. + EffectiveFileEventQueue *FileEventQueue +} + +type DeleteExternalLocationRequest struct { + // Name of the external location. + NameArg *string + // Force deletion even if there are dependent external tables or mounts. + Force *bool +} + +type DeleteExternalLocationResponse struct { +} + +// Encryption options that apply to clients connecting to cloud storage.. +type EncryptionDetails struct { + EncryptionDetailsType isEncryptionDetails_EncryptionDetailsType +} + +type isEncryptionDetails_EncryptionDetailsType interface { + isEncryptionDetails_EncryptionDetailsType() +} + +// EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails selects SseEncryptionDetails for EncryptionDetails.EncryptionDetailsType. +// Server-Side Encryption properties for clients communicating with AWS s3. +type EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails struct { + SseEncryptionDetails SseEncryptionDetails +} + +func (*EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails) isEncryptionDetails_EncryptionDetailsType() { +} + +type ExternalLocationInfo struct { + // Name of the external location. + Name *string + // Path URL of the external location. + Url *string + // Name of the storage credential used with this location. + CredentialName *string + // Indicates whether the external location is read-only. + ReadOnly *bool + // User-provided free-form text description. + Comment *string + // Whether to enable file events on this external location. Default to `true`. + // Set to `false` to disable file events. The actual applied value may differ + // due to server-side defaults; check `effective_enable_file_events` for the + // effective state. + EnableFileEvents *bool + // File event queue settings. If `enable_file_events` is not `false`, must be + // defined and have exactly one of the documented properties. + FileEventQueue *FileEventQueue + // The owner of the external location. + Owner *string + EncryptionDetails *EncryptionDetails + // Unique identifier of metastore hosting the external location. + MetastoreId *string + // Unique ID of the location's storage credential. + CredentialId *string + // Time at which this external location was created, in epoch milliseconds. + CreatedAt *int64 + // Username of external location creator. + CreatedBy *string + // Time at which external location this was last modified, in epoch + // milliseconds. + UpdatedAt *int64 + // Username of user who last modified the external location. + UpdatedBy *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + IsolationMode IsolationMode + // Indicates whether fallback mode is enabled for this external location. When + // fallback mode is enabled, the access to the location falls back to cluster + // credentials if UC credentials are not sufficient. + Fallback *bool + // The effective value of `enable_file_events` after applying server-side + // defaults. + EffectiveEnableFileEvents *bool + // The effective file event queue configuration after applying server-side + // defaults. Always populated when a queue is provisioned, regardless of whether + // the user explicitly set `enable_file_events`. Use this field instead of + // `file_event_queue` for reading the actual queue state. + EffectiveFileEventQueue *FileEventQueue +} + +type FileEventQueue struct { + Provided isFileEventQueue_Provided + Managed isFileEventQueue_Managed +} + +type isFileEventQueue_Provided interface { + isFileEventQueue_Provided() +} + +// FileEventQueue_Provided_ProvidedAqs selects ProvidedAqs for FileEventQueue.Provided. +type FileEventQueue_Provided_ProvidedAqs struct { + ProvidedAqs AzureQueueStorage +} + +func (*FileEventQueue_Provided_ProvidedAqs) isFileEventQueue_Provided() {} + +// FileEventQueue_Provided_ProvidedSqs selects ProvidedSqs for FileEventQueue.Provided. +type FileEventQueue_Provided_ProvidedSqs struct { + ProvidedSqs AwsSqsQueue +} + +func (*FileEventQueue_Provided_ProvidedSqs) isFileEventQueue_Provided() {} + +// FileEventQueue_Provided_ProvidedPubsub selects ProvidedPubsub for FileEventQueue.Provided. +type FileEventQueue_Provided_ProvidedPubsub struct { + ProvidedPubsub GcpPubsub +} + +func (*FileEventQueue_Provided_ProvidedPubsub) isFileEventQueue_Provided() {} + +type isFileEventQueue_Managed interface { + isFileEventQueue_Managed() +} + +// FileEventQueue_Managed_ManagedAqs selects ManagedAqs for FileEventQueue.Managed. +type FileEventQueue_Managed_ManagedAqs struct { + ManagedAqs AzureQueueStorage +} + +func (*FileEventQueue_Managed_ManagedAqs) isFileEventQueue_Managed() {} + +// FileEventQueue_Managed_ManagedSqs selects ManagedSqs for FileEventQueue.Managed. +type FileEventQueue_Managed_ManagedSqs struct { + ManagedSqs AwsSqsQueue +} + +func (*FileEventQueue_Managed_ManagedSqs) isFileEventQueue_Managed() {} + +// FileEventQueue_Managed_ManagedPubsub selects ManagedPubsub for FileEventQueue.Managed. +type FileEventQueue_Managed_ManagedPubsub struct { + ManagedPubsub GcpPubsub +} + +func (*FileEventQueue_Managed_ManagedPubsub) isFileEventQueue_Managed() {} + +type GcpPubsub struct { + // The Pub/Sub subscription name in the format + // projects/{project}/subscriptions/{subscription name}. Only required for + // provided_pubsub. + SubscriptionName *string + // Unique identifier included in the name of file events managed cloud + // resources. + ManagedResourceId *string +} + +type GetExternalLocationRequest struct { + // Name of the external location. + NameArg *string + // Whether to include external locations in the response for which the principal + // can only access selective metadata for + IncludeBrowse *bool +} + +type ListExternalLocationsRequest struct { + // Whether to include external locations in the response for which the principal + // can only access selective metadata for + IncludeBrowse *bool + // Maximum number of external locations to return. If not set, all the external + // locations are returned (not recommended). - when set to a value greater than + // 0, the page length is the minimum of this value and a server configured + // value; - when set to 0, the page length is set to a server configured value + // (recommended); - when set to a value less than 0, an invalid parameter error + // is returned; + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string + // Whether to include external locations not bound to the workspace. Effective + // only if the user has permission to update the location–workspace binding. + IncludeUnbound *bool +} + +type ListExternalLocationsResponse struct { + // An array of external locations. + ExternalLocations []ExternalLocationInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +// Server-Side Encryption properties for clients communicating with AWS s3.. +type SseEncryptionDetails struct { + // Sets the value of the 'x-amz-server-side-encryption' header in S3 request. + Algorithm SseEncryptionAlgorithm + // Optional. The ARN of the SSE-KMS key used with the S3 location, when + // algorithm = "SSE-KMS". Sets the value of the + // 'x-amz-server-side-encryption-aws-kms-key-id' header. + AwsKmsKeyArn *string +} + +type UpdateExternalLocationRequest struct { + // Name of the external location. + NameArg *string + // New name for the external location. + NewName *string + // Force update even if changing url invalidates dependent external tables or + // mounts. + Force *bool + // Skips validation of the storage credential associated with the external + // location. + SkipValidation *bool + // Name of the external location. + Name *string + // Path URL of the external location. + Url *string + // Name of the storage credential used with this location. + CredentialName *string + // Indicates whether the external location is read-only. + ReadOnly *bool + // User-provided free-form text description. + Comment *string + // Whether to enable file events on this external location. Default to `true`. + // Set to `false` to disable file events. The actual applied value may differ + // due to server-side defaults; check `effective_enable_file_events` for the + // effective state. + EnableFileEvents *bool + // File event queue settings. If `enable_file_events` is not `false`, must be + // defined and have exactly one of the documented properties. + FileEventQueue *FileEventQueue + // The owner of the external location. + Owner *string + EncryptionDetails *EncryptionDetails + // Unique identifier of metastore hosting the external location. + MetastoreId *string + // Unique ID of the location's storage credential. + CredentialId *string + // Time at which this external location was created, in epoch milliseconds. + CreatedAt *int64 + // Username of external location creator. + CreatedBy *string + // Time at which external location this was last modified, in epoch + // milliseconds. + UpdatedAt *int64 + // Username of user who last modified the external location. + UpdatedBy *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + IsolationMode IsolationMode + // Indicates whether fallback mode is enabled for this external location. When + // fallback mode is enabled, the access to the location falls back to cluster + // credentials if UC credentials are not sufficient. + Fallback *bool + // The effective value of `enable_file_events` after applying server-side + // defaults. + EffectiveEnableFileEvents *bool + // The effective file event queue configuration after applying server-side + // defaults. Always populated when a queue is provisioned, regardless of whether + // the user explicitly set `enable_file_events`. Use this field instead of + // `file_event_queue` for reading the actual queue state. + EffectiveFileEventQueue *FileEventQueue +} diff --git a/uc/externallocations/v1/wire.go b/uc/externallocations/v1/wire.go new file mode 100755 index 0000000..29b229d --- /dev/null +++ b/uc/externallocations/v1/wire.go @@ -0,0 +1,612 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externallocations + +import ( + "fmt" +) + +type awsSqsQueueWire struct { + QueueUrl *string `json:"queue_url,omitempty"` + ManagedResourceId *string `json:"managed_resource_id,omitempty"` +} + +func awsSqsQueueToWire(v *AwsSqsQueue) (*awsSqsQueueWire, error) { + if v == nil { + return nil, nil + } + return &awsSqsQueueWire{ + QueueUrl: v.QueueUrl, + ManagedResourceId: v.ManagedResourceId, + }, nil +} + +func awsSqsQueueFromWire(w *awsSqsQueueWire) (*AwsSqsQueue, error) { + if w == nil { + return nil, nil + } + return &AwsSqsQueue{ + QueueUrl: w.QueueUrl, + ManagedResourceId: w.ManagedResourceId, + }, nil +} + +type azureQueueStorageWire struct { + QueueUrl *string `json:"queue_url,omitempty"` + SubscriptionId *string `json:"subscription_id,omitempty"` + ResourceGroup *string `json:"resource_group,omitempty"` + ManagedResourceId *string `json:"managed_resource_id,omitempty"` +} + +func azureQueueStorageToWire(v *AzureQueueStorage) (*azureQueueStorageWire, error) { + if v == nil { + return nil, nil + } + return &azureQueueStorageWire{ + QueueUrl: v.QueueUrl, + SubscriptionId: v.SubscriptionId, + ResourceGroup: v.ResourceGroup, + ManagedResourceId: v.ManagedResourceId, + }, nil +} + +func azureQueueStorageFromWire(w *azureQueueStorageWire) (*AzureQueueStorage, error) { + if w == nil { + return nil, nil + } + return &AzureQueueStorage{ + QueueUrl: w.QueueUrl, + SubscriptionId: w.SubscriptionId, + ResourceGroup: w.ResourceGroup, + ManagedResourceId: w.ManagedResourceId, + }, nil +} + +type createExternalLocationRequestWire struct { + SkipValidation *bool `json:"skip_validation,omitempty"` + Name *string `json:"name,omitempty"` + Url *string `json:"url,omitempty"` + CredentialName *string `json:"credential_name,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Comment *string `json:"comment,omitempty"` + EnableFileEvents *bool `json:"enable_file_events,omitempty"` + FileEventQueue *fileEventQueueWire `json:"file_event_queue,omitempty"` + Owner *string `json:"owner,omitempty"` + EncryptionDetails *encryptionDetailsWire `json:"encryption_details,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CredentialId *string `json:"credential_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` + Fallback *bool `json:"fallback,omitempty"` + EffectiveEnableFileEvents *bool `json:"effective_enable_file_events,omitempty"` + EffectiveFileEventQueue *fileEventQueueWire `json:"effective_file_event_queue,omitempty"` +} + +func createExternalLocationRequestToWire(v *CreateExternalLocationRequest) (*createExternalLocationRequestWire, error) { + if v == nil { + return nil, nil + } + fileEventQueueWireValue, err := fileEventQueueToWire(v.FileEventQueue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExternalLocationRequest.FileEventQueue", err) + } + encryptionDetailsWireValue, err := encryptionDetailsToWire(v.EncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExternalLocationRequest.EncryptionDetails", err) + } + effectiveFileEventQueueWireValue, err := fileEventQueueToWire(v.EffectiveFileEventQueue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExternalLocationRequest.EffectiveFileEventQueue", err) + } + return &createExternalLocationRequestWire{ + SkipValidation: v.SkipValidation, + Name: v.Name, + Url: v.Url, + CredentialName: v.CredentialName, + ReadOnly: v.ReadOnly, + Comment: v.Comment, + EnableFileEvents: v.EnableFileEvents, + FileEventQueue: fileEventQueueWireValue, + Owner: v.Owner, + EncryptionDetails: encryptionDetailsWireValue, + MetastoreId: v.MetastoreId, + CredentialId: v.CredentialId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + BrowseOnly: v.BrowseOnly, + IsolationMode: v.IsolationMode, + Fallback: v.Fallback, + EffectiveEnableFileEvents: v.EffectiveEnableFileEvents, + EffectiveFileEventQueue: effectiveFileEventQueueWireValue, + }, nil +} + +type deleteExternalLocationRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + Force *bool `json:"force,omitempty"` +} + +func deleteExternalLocationRequestToWire(v *DeleteExternalLocationRequest) (*deleteExternalLocationRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteExternalLocationRequestWire{ + NameArg: v.NameArg, + Force: v.Force, + }, nil +} + +type encryptionDetailsWire struct { + SseEncryptionDetails *sseEncryptionDetailsWire `json:"sse_encryption_details,omitempty"` +} + +func encryptionDetailsToWire(v *EncryptionDetails) (*encryptionDetailsWire, error) { + if v == nil { + return nil, nil + } + var encryptionDetailsTypeSseEncryptionDetailsWire *sseEncryptionDetailsWire + switch value := v.EncryptionDetailsType.(type) { + case nil: + case *EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails: + if value != nil { + encryptionDetailsTypeSseEncryptionDetailsConverted, err := sseEncryptionDetailsToWire(&value.SseEncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EncryptionDetails.EncryptionDetailsType.SseEncryptionDetails", err) + } + encryptionDetailsTypeSseEncryptionDetailsWire = encryptionDetailsTypeSseEncryptionDetailsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "EncryptionDetails.EncryptionDetailsType", value) + } + return &encryptionDetailsWire{ + SseEncryptionDetails: encryptionDetailsTypeSseEncryptionDetailsWire, + }, nil +} + +func encryptionDetailsFromWire(w *encryptionDetailsWire) (*EncryptionDetails, error) { + if w == nil { + return nil, nil + } + encryptionDetailsTypeMembers := 0 + if w.SseEncryptionDetails != nil { + encryptionDetailsTypeMembers++ + } + if encryptionDetailsTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "EncryptionDetails.EncryptionDetailsType") + } + var encryptionDetailsTypeSelection isEncryptionDetails_EncryptionDetailsType + switch { + case w.SseEncryptionDetails != nil: + encryptionDetailsTypeSseEncryptionDetailsConverted, err := sseEncryptionDetailsFromWire(w.SseEncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EncryptionDetails.EncryptionDetailsType.SseEncryptionDetails", err) + } + encryptionDetailsTypeSelection = &EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails{SseEncryptionDetails: *encryptionDetailsTypeSseEncryptionDetailsConverted} + } + return &EncryptionDetails{ + EncryptionDetailsType: encryptionDetailsTypeSelection, + }, nil +} + +type externalLocationInfoWire struct { + Name *string `json:"name,omitempty"` + Url *string `json:"url,omitempty"` + CredentialName *string `json:"credential_name,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Comment *string `json:"comment,omitempty"` + EnableFileEvents *bool `json:"enable_file_events,omitempty"` + FileEventQueue *fileEventQueueWire `json:"file_event_queue,omitempty"` + Owner *string `json:"owner,omitempty"` + EncryptionDetails *encryptionDetailsWire `json:"encryption_details,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CredentialId *string `json:"credential_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` + Fallback *bool `json:"fallback,omitempty"` + EffectiveEnableFileEvents *bool `json:"effective_enable_file_events,omitempty"` + EffectiveFileEventQueue *fileEventQueueWire `json:"effective_file_event_queue,omitempty"` +} + +func externalLocationInfoFromWire(w *externalLocationInfoWire) (*ExternalLocationInfo, error) { + if w == nil { + return nil, nil + } + fileEventQueuePublicValue, err := fileEventQueueFromWire(w.FileEventQueue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLocationInfo.FileEventQueue", err) + } + encryptionDetailsPublicValue, err := encryptionDetailsFromWire(w.EncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLocationInfo.EncryptionDetails", err) + } + effectiveFileEventQueuePublicValue, err := fileEventQueueFromWire(w.EffectiveFileEventQueue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ExternalLocationInfo.EffectiveFileEventQueue", err) + } + return &ExternalLocationInfo{ + Name: w.Name, + Url: w.Url, + CredentialName: w.CredentialName, + ReadOnly: w.ReadOnly, + Comment: w.Comment, + EnableFileEvents: w.EnableFileEvents, + FileEventQueue: fileEventQueuePublicValue, + Owner: w.Owner, + EncryptionDetails: encryptionDetailsPublicValue, + MetastoreId: w.MetastoreId, + CredentialId: w.CredentialId, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + BrowseOnly: w.BrowseOnly, + IsolationMode: w.IsolationMode, + Fallback: w.Fallback, + EffectiveEnableFileEvents: w.EffectiveEnableFileEvents, + EffectiveFileEventQueue: effectiveFileEventQueuePublicValue, + }, nil +} + +type fileEventQueueWire struct { + ProvidedAqs *azureQueueStorageWire `json:"provided_aqs,omitempty"` + ProvidedSqs *awsSqsQueueWire `json:"provided_sqs,omitempty"` + ProvidedPubsub *gcpPubsubWire `json:"provided_pubsub,omitempty"` + ManagedAqs *azureQueueStorageWire `json:"managed_aqs,omitempty"` + ManagedSqs *awsSqsQueueWire `json:"managed_sqs,omitempty"` + ManagedPubsub *gcpPubsubWire `json:"managed_pubsub,omitempty"` +} + +func fileEventQueueToWire(v *FileEventQueue) (*fileEventQueueWire, error) { + if v == nil { + return nil, nil + } + var providedProvidedAqsWire *azureQueueStorageWire + var providedProvidedSqsWire *awsSqsQueueWire + var providedProvidedPubsubWire *gcpPubsubWire + switch value := v.Provided.(type) { + case nil: + case *FileEventQueue_Provided_ProvidedAqs: + if value != nil { + providedProvidedAqsConverted, err := azureQueueStorageToWire(&value.ProvidedAqs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Provided.ProvidedAqs", err) + } + providedProvidedAqsWire = providedProvidedAqsConverted + } + case *FileEventQueue_Provided_ProvidedSqs: + if value != nil { + providedProvidedSqsConverted, err := awsSqsQueueToWire(&value.ProvidedSqs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Provided.ProvidedSqs", err) + } + providedProvidedSqsWire = providedProvidedSqsConverted + } + case *FileEventQueue_Provided_ProvidedPubsub: + if value != nil { + providedProvidedPubsubConverted, err := gcpPubsubToWire(&value.ProvidedPubsub) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Provided.ProvidedPubsub", err) + } + providedProvidedPubsubWire = providedProvidedPubsubConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "FileEventQueue.Provided", value) + } + var managedManagedAqsWire *azureQueueStorageWire + var managedManagedSqsWire *awsSqsQueueWire + var managedManagedPubsubWire *gcpPubsubWire + switch value := v.Managed.(type) { + case nil: + case *FileEventQueue_Managed_ManagedAqs: + if value != nil { + managedManagedAqsConverted, err := azureQueueStorageToWire(&value.ManagedAqs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Managed.ManagedAqs", err) + } + managedManagedAqsWire = managedManagedAqsConverted + } + case *FileEventQueue_Managed_ManagedSqs: + if value != nil { + managedManagedSqsConverted, err := awsSqsQueueToWire(&value.ManagedSqs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Managed.ManagedSqs", err) + } + managedManagedSqsWire = managedManagedSqsConverted + } + case *FileEventQueue_Managed_ManagedPubsub: + if value != nil { + managedManagedPubsubConverted, err := gcpPubsubToWire(&value.ManagedPubsub) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Managed.ManagedPubsub", err) + } + managedManagedPubsubWire = managedManagedPubsubConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "FileEventQueue.Managed", value) + } + return &fileEventQueueWire{ + ProvidedAqs: providedProvidedAqsWire, + ProvidedSqs: providedProvidedSqsWire, + ProvidedPubsub: providedProvidedPubsubWire, + ManagedAqs: managedManagedAqsWire, + ManagedSqs: managedManagedSqsWire, + ManagedPubsub: managedManagedPubsubWire, + }, nil +} + +func fileEventQueueFromWire(w *fileEventQueueWire) (*FileEventQueue, error) { + if w == nil { + return nil, nil + } + providedMembers := 0 + if w.ProvidedAqs != nil { + providedMembers++ + } + if w.ProvidedSqs != nil { + providedMembers++ + } + if w.ProvidedPubsub != nil { + providedMembers++ + } + if providedMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "FileEventQueue.Provided") + } + managedMembers := 0 + if w.ManagedAqs != nil { + managedMembers++ + } + if w.ManagedSqs != nil { + managedMembers++ + } + if w.ManagedPubsub != nil { + managedMembers++ + } + if managedMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "FileEventQueue.Managed") + } + var providedSelection isFileEventQueue_Provided + switch { + case w.ProvidedAqs != nil: + providedProvidedAqsConverted, err := azureQueueStorageFromWire(w.ProvidedAqs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Provided.ProvidedAqs", err) + } + providedSelection = &FileEventQueue_Provided_ProvidedAqs{ProvidedAqs: *providedProvidedAqsConverted} + case w.ProvidedSqs != nil: + providedProvidedSqsConverted, err := awsSqsQueueFromWire(w.ProvidedSqs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Provided.ProvidedSqs", err) + } + providedSelection = &FileEventQueue_Provided_ProvidedSqs{ProvidedSqs: *providedProvidedSqsConverted} + case w.ProvidedPubsub != nil: + providedProvidedPubsubConverted, err := gcpPubsubFromWire(w.ProvidedPubsub) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Provided.ProvidedPubsub", err) + } + providedSelection = &FileEventQueue_Provided_ProvidedPubsub{ProvidedPubsub: *providedProvidedPubsubConverted} + } + var managedSelection isFileEventQueue_Managed + switch { + case w.ManagedAqs != nil: + managedManagedAqsConverted, err := azureQueueStorageFromWire(w.ManagedAqs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Managed.ManagedAqs", err) + } + managedSelection = &FileEventQueue_Managed_ManagedAqs{ManagedAqs: *managedManagedAqsConverted} + case w.ManagedSqs != nil: + managedManagedSqsConverted, err := awsSqsQueueFromWire(w.ManagedSqs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Managed.ManagedSqs", err) + } + managedSelection = &FileEventQueue_Managed_ManagedSqs{ManagedSqs: *managedManagedSqsConverted} + case w.ManagedPubsub != nil: + managedManagedPubsubConverted, err := gcpPubsubFromWire(w.ManagedPubsub) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FileEventQueue.Managed.ManagedPubsub", err) + } + managedSelection = &FileEventQueue_Managed_ManagedPubsub{ManagedPubsub: *managedManagedPubsubConverted} + } + return &FileEventQueue{ + Provided: providedSelection, + Managed: managedSelection, + }, nil +} + +type gcpPubsubWire struct { + SubscriptionName *string `json:"subscription_name,omitempty"` + ManagedResourceId *string `json:"managed_resource_id,omitempty"` +} + +func gcpPubsubToWire(v *GcpPubsub) (*gcpPubsubWire, error) { + if v == nil { + return nil, nil + } + return &gcpPubsubWire{ + SubscriptionName: v.SubscriptionName, + ManagedResourceId: v.ManagedResourceId, + }, nil +} + +func gcpPubsubFromWire(w *gcpPubsubWire) (*GcpPubsub, error) { + if w == nil { + return nil, nil + } + return &GcpPubsub{ + SubscriptionName: w.SubscriptionName, + ManagedResourceId: w.ManagedResourceId, + }, nil +} + +type getExternalLocationRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` +} + +func getExternalLocationRequestToWire(v *GetExternalLocationRequest) (*getExternalLocationRequestWire, error) { + if v == nil { + return nil, nil + } + return &getExternalLocationRequestWire{ + NameArg: v.NameArg, + IncludeBrowse: v.IncludeBrowse, + }, nil +} + +type listExternalLocationsRequestWire struct { + IncludeBrowse *bool `json:"include_browse,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` + IncludeUnbound *bool `json:"include_unbound,omitempty"` +} + +func listExternalLocationsRequestToWire(v *ListExternalLocationsRequest) (*listExternalLocationsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listExternalLocationsRequestWire{ + IncludeBrowse: v.IncludeBrowse, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + IncludeUnbound: v.IncludeUnbound, + }, nil +} + +type listExternalLocationsResponseWire struct { + ExternalLocations []externalLocationInfoWire `json:"external_locations,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listExternalLocationsResponseFromWire(w *listExternalLocationsResponseWire) (*ListExternalLocationsResponse, error) { + if w == nil { + return nil, nil + } + externalLocationsPublicValue, err := convertSlice(w.ExternalLocations, externalLocationInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListExternalLocationsResponse.ExternalLocations", err) + } + return &ListExternalLocationsResponse{ + ExternalLocations: externalLocationsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type sseEncryptionDetailsWire struct { + Algorithm SseEncryptionAlgorithm `json:"algorithm,omitempty"` + AwsKmsKeyArn *string `json:"aws_kms_key_arn,omitempty"` +} + +func sseEncryptionDetailsToWire(v *SseEncryptionDetails) (*sseEncryptionDetailsWire, error) { + if v == nil { + return nil, nil + } + return &sseEncryptionDetailsWire{ + Algorithm: v.Algorithm, + AwsKmsKeyArn: v.AwsKmsKeyArn, + }, nil +} + +func sseEncryptionDetailsFromWire(w *sseEncryptionDetailsWire) (*SseEncryptionDetails, error) { + if w == nil { + return nil, nil + } + return &SseEncryptionDetails{ + Algorithm: w.Algorithm, + AwsKmsKeyArn: w.AwsKmsKeyArn, + }, nil +} + +type updateExternalLocationRequestWire struct { + NameArg *string `json:"name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + Force *bool `json:"force,omitempty"` + SkipValidation *bool `json:"skip_validation,omitempty"` + Name *string `json:"name,omitempty"` + Url *string `json:"url,omitempty"` + CredentialName *string `json:"credential_name,omitempty"` + ReadOnly *bool `json:"read_only,omitempty"` + Comment *string `json:"comment,omitempty"` + EnableFileEvents *bool `json:"enable_file_events,omitempty"` + FileEventQueue *fileEventQueueWire `json:"file_event_queue,omitempty"` + Owner *string `json:"owner,omitempty"` + EncryptionDetails *encryptionDetailsWire `json:"encryption_details,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CredentialId *string `json:"credential_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + IsolationMode IsolationMode `json:"isolation_mode,omitempty"` + Fallback *bool `json:"fallback,omitempty"` + EffectiveEnableFileEvents *bool `json:"effective_enable_file_events,omitempty"` + EffectiveFileEventQueue *fileEventQueueWire `json:"effective_file_event_queue,omitempty"` +} + +func updateExternalLocationRequestToWire(v *UpdateExternalLocationRequest) (*updateExternalLocationRequestWire, error) { + if v == nil { + return nil, nil + } + fileEventQueueWireValue, err := fileEventQueueToWire(v.FileEventQueue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExternalLocationRequest.FileEventQueue", err) + } + encryptionDetailsWireValue, err := encryptionDetailsToWire(v.EncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExternalLocationRequest.EncryptionDetails", err) + } + effectiveFileEventQueueWireValue, err := fileEventQueueToWire(v.EffectiveFileEventQueue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExternalLocationRequest.EffectiveFileEventQueue", err) + } + return &updateExternalLocationRequestWire{ + NameArg: v.NameArg, + NewName: v.NewName, + Force: v.Force, + SkipValidation: v.SkipValidation, + Name: v.Name, + Url: v.Url, + CredentialName: v.CredentialName, + ReadOnly: v.ReadOnly, + Comment: v.Comment, + EnableFileEvents: v.EnableFileEvents, + FileEventQueue: fileEventQueueWireValue, + Owner: v.Owner, + EncryptionDetails: encryptionDetailsWireValue, + MetastoreId: v.MetastoreId, + CredentialId: v.CredentialId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + BrowseOnly: v.BrowseOnly, + IsolationMode: v.IsolationMode, + Fallback: v.Fallback, + EffectiveEnableFileEvents: v.EffectiveEnableFileEvents, + EffectiveFileEventQueue: effectiveFileEventQueueWireValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/externalmetadata/.package.json b/uc/externalmetadata/.package.json new file mode 100644 index 0000000..10a4a74 --- /dev/null +++ b/uc/externalmetadata/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/externalmetadata" +} diff --git a/uc/externalmetadata/CHANGELOG.md b/uc/externalmetadata/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/externalmetadata/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/externalmetadata/README.md b/uc/externalmetadata/README.md new file mode 100644 index 0000000..00abca8 --- /dev/null +++ b/uc/externalmetadata/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/externalmetadata + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/externalmetadata@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/externalmetadata/v1" + +client, err := externalmetadata.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/externalmetadata/go.mod b/uc/externalmetadata/go.mod new file mode 100644 index 0000000..a7fddd7 --- /dev/null +++ b/uc/externalmetadata/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/externalmetadata + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/externalmetadata/internal/version.go b/uc/externalmetadata/internal/version.go new file mode 100644 index 0000000..6ee4919 --- /dev/null +++ b/uc/externalmetadata/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-externalmetadata" + +const Version = "0.0.1-dev.1" diff --git a/uc/externalmetadata/v1/client.go b/uc/externalmetadata/v1/client.go new file mode 100755 index 0000000..eae38b1 --- /dev/null +++ b/uc/externalmetadata/v1/client.go @@ -0,0 +1,449 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externalmetadata + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/externalmetadata/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new external metadata object in the parent metastore if the caller +// is a metastore admin or has the **CREATE_EXTERNAL_METADATA** privilege. +// Grants **BROWSE** to all account users upon creation by default. +func (c *internalClient) CreateExternalMetadataV2(ctx context.Context, req *CreateExternalMetadataRequest, opts ...call.Option) (*ExternalMetadata, error) { + wireReq, err := createExternalMetadataRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.ExternalMetadata) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/lineage-tracking/external-metadata" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExternalMetadata + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp externalMetadataWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = externalMetadataFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the external metadata object that matches the supplied name. The +// caller must be a metastore admin, the owner of the external metadata object, +// or a user that has the **MANAGE** privilege. +func (c *internalClient) DeleteExternalMetadataV2(ctx context.Context, req *DeleteExternalMetadataRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lineage-tracking/external-metadata/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets the specified external metadata object in a metastore. The caller must +// be a metastore admin, the owner of the external metadata object, or a user +// that has the **BROWSE** privilege. +func (c *internalClient) GetExternalMetadataV2(ctx context.Context, req *GetExternalMetadataRequest, opts ...call.Option) (*ExternalMetadata, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lineage-tracking/external-metadata/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExternalMetadata + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp externalMetadataWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = externalMetadataFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of external metadata objects in the metastore. If the caller is +// the metastore admin, all external metadata objects will be retrieved. +// Otherwise, only external metadata objects that the caller has **BROWSE** on +// will be retrieved. There is no guarantee of a specific ordering of the +// elements in the array. +func (c *internalClient) ListExternalMetadataV2(ctx context.Context, req *ListExternalMetadataRequest, opts ...call.Option) (*ListExternalMetadataResponseV2, error) { + wireReq, err := listExternalMetadataRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/lineage-tracking/external-metadata" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListExternalMetadataResponseV2 + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listExternalMetadataResponseV2Wire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listExternalMetadataResponseV2FromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListExternalMetadataV2Iter returns an iterator that iterates +// over the results of ListExternalMetadataV2. +// +// For example: +// +// for item, err := range c.ListExternalMetadataV2Iter(ctx, &ListExternalMetadataRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListExternalMetadataV2 call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListExternalMetadataV2 directly. +func (c *internalClient) ListExternalMetadataV2Iter(ctx context.Context, req *ListExternalMetadataRequest, opts ...call.Option) iter.Seq2[*ExternalMetadata, error] { + return func(yield func(*ExternalMetadata, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListExternalMetadataRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListExternalMetadataV2(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ExternalMetadata { + if !yield(&resp.ExternalMetadata[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates the external metadata object that matches the supplied name. The +// caller can only update either the owner or other metadata fields in one +// request. The caller must be a metastore admin, the owner of the external +// metadata object, or a user that has the **MODIFY** privilege. If the caller +// is updating the owner, they must also have the **MANAGE** privilege. +func (c *internalClient) UpdateExternalMetadataV2(ctx context.Context, req *UpdateExternalMetadataRequest, opts ...call.Option) (*ExternalMetadata, error) { + wireReq, err := updateExternalMetadataRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.ExternalMetadata) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/lineage-tracking/external-metadata/") + pb.singleSegment(*req.ExternalMetadata.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ExternalMetadata + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp externalMetadataWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = externalMetadataFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/externalmetadata/v1/genhelper.go b/uc/externalmetadata/v1/genhelper.go new file mode 100755 index 0000000..70cfe89 --- /dev/null +++ b/uc/externalmetadata/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externalmetadata + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/externalmetadata/v1/model.go b/uc/externalmetadata/v1/model.go new file mode 100755 index 0000000..256bc8e --- /dev/null +++ b/uc/externalmetadata/v1/model.go @@ -0,0 +1,97 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externalmetadata + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type SystemType string + +const ( + SystemType_Unspecified SystemType = "" + SystemType_Other SystemType = "OTHER" + SystemType_Tableau SystemType = "TABLEAU" + SystemType_PowerBi SystemType = "POWER_BI" + SystemType_Looker SystemType = "LOOKER" + SystemType_Kafka SystemType = "KAFKA" + SystemType_Sap SystemType = "SAP" + SystemType_Oracle SystemType = "ORACLE" + SystemType_Salesforce SystemType = "SALESFORCE" + SystemType_Workday SystemType = "WORKDAY" + SystemType_Mysql SystemType = "MYSQL" + SystemType_Postgresql SystemType = "POSTGRESQL" + SystemType_MicrosoftSqlServer SystemType = "MICROSOFT_SQL_SERVER" + SystemType_Servicenow SystemType = "SERVICENOW" + SystemType_AmazonRedshift SystemType = "AMAZON_REDSHIFT" + SystemType_AzureSynapse SystemType = "AZURE_SYNAPSE" + SystemType_Snowflake SystemType = "SNOWFLAKE" + SystemType_GoogleBigquery SystemType = "GOOGLE_BIGQUERY" + SystemType_MicrosoftFabric SystemType = "MICROSOFT_FABRIC" + SystemType_Mongodb SystemType = "MONGODB" + SystemType_Teradata SystemType = "TERADATA" + SystemType_Confluent SystemType = "CONFLUENT" + SystemType_Databricks SystemType = "DATABRICKS" + SystemType_StreamNative SystemType = "STREAM_NATIVE" +) + +type CreateExternalMetadataRequest struct { + ExternalMetadata *ExternalMetadata +} + +type DeleteExternalMetadataRequest struct { + Name *string +} + +type ExternalMetadata struct { + // Name of the external metadata object. + Name *string `fieldmask:"name"` + // Type of external system. + SystemType SystemType `fieldmask:"system_type"` + // Type of entity within the external system. + EntityType *string `fieldmask:"entity_type"` + // URL associated with the external metadata object. + Url *string `fieldmask:"url"` + // User-provided free-form text description. + Description *string `fieldmask:"description"` + // List of columns associated with the external metadata object. + Columns []string `fieldmask:"columns"` + // A map of key-value properties attached to the external metadata object. + Properties map[string]string `fieldmask:"properties"` + // Owner of the external metadata object. + Owner *string `fieldmask:"owner"` + // Unique identifier of parent metastore. + MetastoreId *string `fieldmask:"metastore_id"` + // Time at which this external metadata object was created. + CreateTime *types.Time `fieldmask:"create_time"` + // Username of external metadata object creator. + CreatedBy *string `fieldmask:"created_by"` + // Time at which this external metadata object was last modified. + UpdateTime *types.Time `fieldmask:"update_time"` + // Username of user who last modified external metadata object. + UpdatedBy *string `fieldmask:"updated_by"` + // Unique identifier of the external metadata object. + Id *string `fieldmask:"id"` +} + +type GetExternalMetadataRequest struct { + Name *string +} + +type ListExternalMetadataRequest struct { + // Specifies the maximum number of external metadata objects to return in a + // single response. The value must be less than or equal to 1000. + PageSize *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListExternalMetadataResponseV2 struct { + ExternalMetadata []ExternalMetadata + NextPageToken *string +} + +type UpdateExternalMetadataRequest struct { + ExternalMetadata *ExternalMetadata + UpdateMask *types.FieldMask[ExternalMetadata] +} diff --git a/uc/externalmetadata/v1/wire.go b/uc/externalmetadata/v1/wire.go new file mode 100755 index 0000000..88a3f5f --- /dev/null +++ b/uc/externalmetadata/v1/wire.go @@ -0,0 +1,163 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package externalmetadata + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createExternalMetadataRequestWire struct { + ExternalMetadata *externalMetadataWire `json:"external_metadata,omitempty"` +} + +func createExternalMetadataRequestToWire(v *CreateExternalMetadataRequest) (*createExternalMetadataRequestWire, error) { + if v == nil { + return nil, nil + } + externalMetadataWireValue, err := externalMetadataToWire(v.ExternalMetadata) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateExternalMetadataRequest.ExternalMetadata", err) + } + return &createExternalMetadataRequestWire{ + ExternalMetadata: externalMetadataWireValue, + }, nil +} + +type externalMetadataWire struct { + Name *string `json:"name,omitempty"` + SystemType SystemType `json:"system_type,omitempty"` + EntityType *string `json:"entity_type,omitempty"` + Url *string `json:"url,omitempty"` + Description *string `json:"description,omitempty"` + Columns []string `json:"columns,omitempty"` + Properties map[string]string `json:"properties,omitempty"` + Owner *string `json:"owner,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Id *string `json:"id,omitempty"` +} + +func externalMetadataToWire(v *ExternalMetadata) (*externalMetadataWire, error) { + if v == nil { + return nil, nil + } + return &externalMetadataWire{ + Name: v.Name, + SystemType: v.SystemType, + EntityType: v.EntityType, + Url: v.Url, + Description: v.Description, + Columns: v.Columns, + Properties: v.Properties, + Owner: v.Owner, + MetastoreId: v.MetastoreId, + CreateTime: v.CreateTime, + CreatedBy: v.CreatedBy, + UpdateTime: v.UpdateTime, + UpdatedBy: v.UpdatedBy, + Id: v.Id, + }, nil +} + +func externalMetadataFromWire(w *externalMetadataWire) (*ExternalMetadata, error) { + if w == nil { + return nil, nil + } + return &ExternalMetadata{ + Name: w.Name, + SystemType: w.SystemType, + EntityType: w.EntityType, + Url: w.Url, + Description: w.Description, + Columns: w.Columns, + Properties: w.Properties, + Owner: w.Owner, + MetastoreId: w.MetastoreId, + CreateTime: w.CreateTime, + CreatedBy: w.CreatedBy, + UpdateTime: w.UpdateTime, + UpdatedBy: w.UpdatedBy, + Id: w.Id, + }, nil +} + +type listExternalMetadataRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listExternalMetadataRequestToWire(v *ListExternalMetadataRequest) (*listExternalMetadataRequestWire, error) { + if v == nil { + return nil, nil + } + return &listExternalMetadataRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listExternalMetadataResponseV2Wire struct { + ExternalMetadata []externalMetadataWire `json:"external_metadata,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listExternalMetadataResponseV2FromWire(w *listExternalMetadataResponseV2Wire) (*ListExternalMetadataResponseV2, error) { + if w == nil { + return nil, nil + } + externalMetadataPublicValue, err := convertSlice(w.ExternalMetadata, externalMetadataFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListExternalMetadataResponseV2.ExternalMetadata", err) + } + return &ListExternalMetadataResponseV2{ + ExternalMetadata: externalMetadataPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type updateExternalMetadataRequestWire struct { + ExternalMetadata *externalMetadataWire `json:"external_metadata,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateExternalMetadataRequestToWire(v *UpdateExternalMetadataRequest) (*updateExternalMetadataRequestWire, error) { + if v == nil { + return nil, nil + } + externalMetadataWireValue, err := externalMetadataToWire(v.ExternalMetadata) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateExternalMetadataRequest.ExternalMetadata", err) + } + return &updateExternalMetadataRequestWire{ + ExternalMetadata: externalMetadataWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/functions/.package.json b/uc/functions/.package.json new file mode 100644 index 0000000..f3b7220 --- /dev/null +++ b/uc/functions/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/functions" +} diff --git a/uc/functions/CHANGELOG.md b/uc/functions/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/functions/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/functions/README.md b/uc/functions/README.md new file mode 100644 index 0000000..70b372f --- /dev/null +++ b/uc/functions/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/functions + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/functions@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/functions/v1" + +client, err := functions.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/functions/go.mod b/uc/functions/go.mod new file mode 100644 index 0000000..d6e68d8 --- /dev/null +++ b/uc/functions/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/functions + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/functions/internal/version.go b/uc/functions/internal/version.go new file mode 100644 index 0000000..64bf9f4 --- /dev/null +++ b/uc/functions/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-functions" + +const Version = "0.0.1-dev.1" diff --git a/uc/functions/v1/client.go b/uc/functions/v1/client.go new file mode 100755 index 0000000..2d39620 --- /dev/null +++ b/uc/functions/v1/client.go @@ -0,0 +1,497 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package functions + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/functions/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// **WARNING: This API is experimental and will change in future versions** +// +// # Creates a new function +// +// The user must have the following permissions in order for the function to be +// created: - **USE_CATALOG** on the function's parent catalog - **USE_SCHEMA** +// and **CREATE_FUNCTION** on the function's parent schema +func (c *internalClient) CreateFunction(ctx context.Context, req *CreateFunctionRequest, opts ...call.Option) (*FunctionInfo, error) { + wireReq, err := createFunctionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/functions" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FunctionInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp functionInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = functionInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the function that matches the supplied name. For the deletion to +// succeed, the user must satisfy one of the following conditions: - Is the +// owner of the function's parent catalog - Is the owner of the function's +// parent schema and have the **USE_CATALOG** privilege on its parent catalog - +// Is the owner of the function itself and have both the **USE_CATALOG** +// privilege on its parent catalog and the **USE_SCHEMA** privilege on its +// parent schema +func (c *internalClient) DeleteFunction(ctx context.Context, req *DeleteFunctionRequest, opts ...call.Option) (*DeleteFunctionResponse, error) { + wireReq, err := deleteFunctionRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/functions/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteFunctionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteFunctionResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a function from within a parent catalog and schema. For the fetch to +// succeed, the user must satisfy one of the following requirements: - Is a +// metastore admin - Is an owner of the function's parent catalog - Have the +// **USE_CATALOG** privilege on the function's parent catalog and be the owner +// of the function - Have the **USE_CATALOG** privilege on the function's parent +// catalog, the **USE_SCHEMA** privilege on the function's parent schema, and +// the **EXECUTE** privilege on the function itself +func (c *internalClient) GetFunction(ctx context.Context, req *GetFunctionRequest, opts ...call.Option) (*FunctionInfo, error) { + wireReq, err := getFunctionRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/functions/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FunctionInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp functionInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = functionInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List functions within the specified parent catalog and schema. If the user is +// a metastore admin, all functions are returned in the output list. Otherwise, +// the user must have the **USE_CATALOG** privilege on the catalog and the +// **USE_SCHEMA** privilege on the schema, and the output list contains only +// functions for which either the user has the **EXECUTE** privilege or the user +// is the owner. There is no guarantee of a specific ordering of the elements in +// the array. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) ListFunctions(ctx context.Context, req *ListFunctionsRequest, opts ...call.Option) (*ListFunctionsResponse, error) { + wireReq, err := listFunctionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/functions" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "catalog_name", wireReq.CatalogName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "schema_name", wireReq.SchemaName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListFunctionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listFunctionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listFunctionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListFunctionsIter returns an iterator that iterates +// over the results of ListFunctions. +// +// For example: +// +// for item, err := range c.ListFunctionsIter(ctx, &ListFunctionsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListFunctions call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListFunctions directly. +func (c *internalClient) ListFunctionsIter(ctx context.Context, req *ListFunctionsRequest, opts ...call.Option) iter.Seq2[*FunctionInfo, error] { + return func(yield func(*FunctionInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListFunctionsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListFunctions(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Functions { + if !yield(&resp.Functions[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates the function that matches the supplied name. Only the owner of the +// function can be updated. If the user is not a metastore admin, the user must +// be a member of the group that is the new function owner. - Is a metastore +// admin - Is the owner of the function's parent catalog - Is the owner of the +// function's parent schema and has the **USE_CATALOG** privilege on its parent +// catalog - Is the owner of the function itself and has the **USE_CATALOG** +// privilege on its parent catalog as well as the **USE_SCHEMA** privilege on +// the function's parent schema. +func (c *internalClient) UpdateFunction(ctx context.Context, req *UpdateFunctionRequest, opts ...call.Option) (*FunctionInfo, error) { + wireReq, err := updateFunctionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/functions/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *FunctionInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp functionInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = functionInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/functions/v1/genhelper.go b/uc/functions/v1/genhelper.go new file mode 100755 index 0000000..e15811e --- /dev/null +++ b/uc/functions/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package functions + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/functions/v1/model.go b/uc/functions/v1/model.go new file mode 100755 index 0000000..e541e27 --- /dev/null +++ b/uc/functions/v1/model.go @@ -0,0 +1,447 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package functions + +type ColumnTypeName string + +const ( + ColumnTypeName_Unspecified ColumnTypeName = "" + ColumnTypeName_Boolean ColumnTypeName = "BOOLEAN" + ColumnTypeName_Byte ColumnTypeName = "BYTE" + ColumnTypeName_Short ColumnTypeName = "SHORT" + ColumnTypeName_Int ColumnTypeName = "INT" + ColumnTypeName_Long ColumnTypeName = "LONG" + ColumnTypeName_Float ColumnTypeName = "FLOAT" + ColumnTypeName_Double ColumnTypeName = "DOUBLE" + ColumnTypeName_Date ColumnTypeName = "DATE" + ColumnTypeName_Timestamp ColumnTypeName = "TIMESTAMP" + ColumnTypeName_String ColumnTypeName = "STRING" + ColumnTypeName_Binary ColumnTypeName = "BINARY" + ColumnTypeName_Decimal ColumnTypeName = "DECIMAL" + ColumnTypeName_Interval ColumnTypeName = "INTERVAL" + ColumnTypeName_Array ColumnTypeName = "ARRAY" + ColumnTypeName_Struct ColumnTypeName = "STRUCT" + ColumnTypeName_Map ColumnTypeName = "MAP" + ColumnTypeName_Char ColumnTypeName = "CHAR" + ColumnTypeName_Null ColumnTypeName = "NULL" + ColumnTypeName_UserDefinedType ColumnTypeName = "USER_DEFINED_TYPE" + ColumnTypeName_TimestampNtz ColumnTypeName = "TIMESTAMP_NTZ" + ColumnTypeName_Variant ColumnTypeName = "VARIANT" + ColumnTypeName_Geometry ColumnTypeName = "GEOMETRY" + ColumnTypeName_Geography ColumnTypeName = "GEOGRAPHY" + ColumnTypeName_TableType ColumnTypeName = "TABLE_TYPE" +) + +type FunctionParameterMode string + +const ( + FunctionParameterMode_Unspecified FunctionParameterMode = "" + FunctionParameterMode_In FunctionParameterMode = "IN" +) + +type FunctionParameterType string + +const ( + FunctionParameterType_Unspecified FunctionParameterType = "" + FunctionParameterType_Param FunctionParameterType = "PARAM" + FunctionParameterType_Column FunctionParameterType = "COLUMN" +) + +type FunctionInfo_ParameterStyle string + +const ( + FunctionInfo_ParameterStyle_Unspecified FunctionInfo_ParameterStyle = "" + FunctionInfo_ParameterStyle_S FunctionInfo_ParameterStyle = "S" +) + +type FunctionInfo_RoutineBody string + +const ( + FunctionInfo_RoutineBody_Unspecified FunctionInfo_RoutineBody = "" + FunctionInfo_RoutineBody_Sql FunctionInfo_RoutineBody = "SQL" + // When `EXTERNAL` is used, * The language of the routine function should be + // specified in the `external_language` field. * The returnParams of the + // function cannot be used as TABLE return type is not supported. * The + // getSqlDataAccess must be NO_SQL. + FunctionInfo_RoutineBody_External FunctionInfo_RoutineBody = "EXTERNAL" +) + +type FunctionInfo_SecurityType string + +const ( + FunctionInfo_SecurityType_Unspecified FunctionInfo_SecurityType = "" + FunctionInfo_SecurityType_Definer FunctionInfo_SecurityType = "DEFINER" +) + +type FunctionInfo_SqlDataAccess string + +const ( + FunctionInfo_SqlDataAccess_Unspecified FunctionInfo_SqlDataAccess = "" + FunctionInfo_SqlDataAccess_ContainsSql FunctionInfo_SqlDataAccess = "CONTAINS_SQL" + FunctionInfo_SqlDataAccess_ReadsSqlData FunctionInfo_SqlDataAccess = "READS_SQL_DATA" + FunctionInfo_SqlDataAccess_NoSql FunctionInfo_SqlDataAccess = "NO_SQL" +) + +// A connection that is dependent on a SQL object.. +type ConnectionDependency struct { + // Full name of the dependent connection, in the form of __connection_name__. + ConnectionName *string +} + +type CreateFunction struct { + // Name of function, relative to parent schema. + Name *string + // Name of parent Catalog. + CatalogName *string + // Name of parent Schema relative to its parent Catalog. + SchemaName *string + // Function input parameters. + InputParams *FunctionParameterInfos + // Scalar function return data type. + DataType ColumnTypeName + // Pretty printed function data type. + FullDataType *string + // Function language. When **EXTERNAL** is used, the language of the routine + // function should be specified in the **external_language** field, and the + // **return_params** of the function cannot be used (as **TABLE** return type is + // not supported), and the **sql_data_access** field must be **NO_SQL**. + RoutineBody FunctionInfo_RoutineBody + // Function body. + RoutineDefinition *string + // Function parameter style. **S** is the value for SQL. + ParameterStyle FunctionInfo_ParameterStyle + // Whether the function is deterministic. + IsDeterministic *bool + // Function SQL data access. + SqlDataAccess FunctionInfo_SqlDataAccess + // Function null call. + IsNullCall *bool + // Function security type. + SecurityType FunctionInfo_SecurityType + // Specific name of the function; Reserved for future use. + SpecificName *string + // Table function return parameters. + ReturnParams *FunctionParameterInfos + // External function name. + ExternalName *string + // External function language. + ExternalLanguage *string + // List of schemes whose objects can be referenced without qualification. + SqlPath *string + // Username of current owner of the function. + Owner *string + // User-provided free-form text description. + Comment *string + // JSON-serialized key-value pair map, encoded (escaped) as a string. + Properties *string + // function dependencies. + RoutineDependencies *DependencyList + // Unique identifier of parent metastore. + MetastoreId *string + // Full name of Function, in form of + // **catalog_name**.**schema_name**.**function_name** + FullName *string + // Time at which this function was created, in epoch milliseconds. + CreatedAt *int64 + // Username of function creator. + CreatedBy *string + // Time at which this function was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the function. + UpdatedBy *string + // Id of Function, relative to parent schema. + FunctionId *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool +} + +type CreateFunctionRequest struct { + // Partial __FunctionInfo__ specifying the function to be created. + FunctionInfo *CreateFunction +} + +// A credential that is dependent on a SQL object.. +type CredentialDependency struct { + // Full name of the dependent credential, in the form of __credential_name__. + CredentialName *string +} + +type DeleteFunctionRequest struct { + // The fully-qualified name of the function (of the form + // __catalog_name__.__schema_name__.__function__name__) . + FullNameArg *string + // Force deletion even if the function is notempty. + Force *bool +} + +type DeleteFunctionResponse struct { +} + +// A dependency of a SQL object. One of the following fields must be defined: +// __table__, __function__, __connection__, __credential__, __volume__, or +// __secret__.. +type Dependency struct { + Value isDependency_Value +} + +type isDependency_Value interface { + isDependency_Value() +} + +// Dependency_Value_Table selects Table for Dependency.Value. +type Dependency_Value_Table struct { + Table TableDependency +} + +func (*Dependency_Value_Table) isDependency_Value() {} + +// Dependency_Value_Function selects Function for Dependency.Value. +type Dependency_Value_Function struct { + Function FunctionDependency +} + +func (*Dependency_Value_Function) isDependency_Value() {} + +// Dependency_Value_Connection selects Connection for Dependency.Value. +type Dependency_Value_Connection struct { + Connection ConnectionDependency +} + +func (*Dependency_Value_Connection) isDependency_Value() {} + +// Dependency_Value_Credential selects Credential for Dependency.Value. +type Dependency_Value_Credential struct { + Credential CredentialDependency +} + +func (*Dependency_Value_Credential) isDependency_Value() {} + +// A list of dependencies.. +type DependencyList struct { + // Array of dependencies. + Dependencies []Dependency +} + +// A function that is dependent on a SQL object.. +type FunctionDependency struct { + // Full name of the dependent function, in the form of + // __catalog_name__.__schema_name__.__function_name__. + FunctionFullName *string +} + +type FunctionInfo struct { + // Name of function, relative to parent schema. + Name *string + // Name of parent Catalog. + CatalogName *string + // Name of parent Schema relative to its parent Catalog. + SchemaName *string + // Function input parameters. + InputParams *FunctionParameterInfos + // Scalar function return data type. + DataType ColumnTypeName + // Pretty printed function data type. + FullDataType *string + // Function language. When **EXTERNAL** is used, the language of the routine + // function should be specified in the **external_language** field, and the + // **return_params** of the function cannot be used (as **TABLE** return type is + // not supported), and the **sql_data_access** field must be **NO_SQL**. + RoutineBody FunctionInfo_RoutineBody + // Function body. + RoutineDefinition *string + // Function parameter style. **S** is the value for SQL. + ParameterStyle FunctionInfo_ParameterStyle + // Whether the function is deterministic. + IsDeterministic *bool + // Function SQL data access. + SqlDataAccess FunctionInfo_SqlDataAccess + // Function null call. + IsNullCall *bool + // Function security type. + SecurityType FunctionInfo_SecurityType + // Specific name of the function; Reserved for future use. + SpecificName *string + // Table function return parameters. + ReturnParams *FunctionParameterInfos + // External function name. + ExternalName *string + // External function language. + ExternalLanguage *string + // List of schemes whose objects can be referenced without qualification. + SqlPath *string + // Username of current owner of the function. + Owner *string + // User-provided free-form text description. + Comment *string + // JSON-serialized key-value pair map, encoded (escaped) as a string. + Properties *string + // function dependencies. + RoutineDependencies *DependencyList + // Unique identifier of parent metastore. + MetastoreId *string + // Full name of Function, in form of + // **catalog_name**.**schema_name**.**function_name** + FullName *string + // Time at which this function was created, in epoch milliseconds. + CreatedAt *int64 + // Username of function creator. + CreatedBy *string + // Time at which this function was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the function. + UpdatedBy *string + // Id of Function, relative to parent schema. + FunctionId *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool +} + +type FunctionParameterInfo struct { + // Name of Parameter. + Name *string + // Full data type spec, SQL/catalogString text. + TypeText *string + // Full data type spec, JSON-serialized. + TypeJson *string + // Name of type (INT, STRUCT, MAP, etc.) + TypeName ColumnTypeName + // Digits of precision; required on Create for DecimalTypes. + TypePrecision *int + // Digits to right of decimal; Required on Create for DecimalTypes. + TypeScale *int + // Format of IntervalType. + TypeIntervalType *string + // Ordinal position of column (starting at position 0). + Position *int + // Function parameter mode. + ParameterMode FunctionParameterMode + // Function parameter type. + ParameterType FunctionParameterType + // Default value of the parameter. + ParameterDefault *string + // User-provided free-form text description. + Comment *string +} + +type FunctionParameterInfos struct { + Parameters []FunctionParameterInfo +} + +type GetFunctionRequest struct { + // The fully-qualified name of the function (of the form + // __catalog_name__.__schema_name__.__function__name__). + FullNameArg *string + // Whether to include functions in the response for which the principal can only + // access selective metadata for + IncludeBrowse *bool +} + +type ListFunctionsRequest struct { + // Name of parent catalog for functions of interest. + CatalogName *string + // Parent schema of functions. + SchemaName *string + // Whether to include functions in the response for which the principal can only + // access selective metadata for + IncludeBrowse *bool + // Maximum number of functions to return. If not set, all the functions are + // returned (not recommended). - when set to a value greater than 0, the page + // length is the minimum of this value and a server configured value; - when set + // to 0, the page length is set to a server configured value (recommended); - + // when set to a value less than 0, an invalid parameter error is returned; + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListFunctionsResponse struct { + // An array of function information objects. + Functions []FunctionInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +// A table that is dependent on a SQL object.. +type TableDependency struct { + // Full name of the dependent table, in the form of + // __catalog_name__.__schema_name__.__table_name__. + TableFullName *string +} + +type UpdateFunctionRequest struct { + // The fully-qualified name of the function (of the form + // __catalog_name__.__schema_name__.__function__name__). + FullNameArg *string + // Name of function, relative to parent schema. + Name *string + // Name of parent Catalog. + CatalogName *string + // Name of parent Schema relative to its parent Catalog. + SchemaName *string + // Function input parameters. + InputParams *FunctionParameterInfos + // Scalar function return data type. + DataType ColumnTypeName + // Pretty printed function data type. + FullDataType *string + // Function language. When **EXTERNAL** is used, the language of the routine + // function should be specified in the **external_language** field, and the + // **return_params** of the function cannot be used (as **TABLE** return type is + // not supported), and the **sql_data_access** field must be **NO_SQL**. + RoutineBody FunctionInfo_RoutineBody + // Function body. + RoutineDefinition *string + // Function parameter style. **S** is the value for SQL. + ParameterStyle FunctionInfo_ParameterStyle + // Whether the function is deterministic. + IsDeterministic *bool + // Function SQL data access. + SqlDataAccess FunctionInfo_SqlDataAccess + // Function null call. + IsNullCall *bool + // Function security type. + SecurityType FunctionInfo_SecurityType + // Specific name of the function; Reserved for future use. + SpecificName *string + // Table function return parameters. + ReturnParams *FunctionParameterInfos + // External function name. + ExternalName *string + // External function language. + ExternalLanguage *string + // List of schemes whose objects can be referenced without qualification. + SqlPath *string + // Username of current owner of the function. + Owner *string + // User-provided free-form text description. + Comment *string + // JSON-serialized key-value pair map, encoded (escaped) as a string. + Properties *string + // function dependencies. + RoutineDependencies *DependencyList + // Unique identifier of parent metastore. + MetastoreId *string + // Full name of Function, in form of + // **catalog_name**.**schema_name**.**function_name** + FullName *string + // Time at which this function was created, in epoch milliseconds. + CreatedAt *int64 + // Username of function creator. + CreatedBy *string + // Time at which this function was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the function. + UpdatedBy *string + // Id of Function, relative to parent schema. + FunctionId *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool +} diff --git a/uc/functions/v1/wire.go b/uc/functions/v1/wire.go new file mode 100755 index 0000000..b6afbde --- /dev/null +++ b/uc/functions/v1/wire.go @@ -0,0 +1,675 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package functions + +import ( + "fmt" +) + +type connectionDependencyWire struct { + ConnectionName *string `json:"connection_name,omitempty"` +} + +func connectionDependencyToWire(v *ConnectionDependency) (*connectionDependencyWire, error) { + if v == nil { + return nil, nil + } + return &connectionDependencyWire{ + ConnectionName: v.ConnectionName, + }, nil +} + +func connectionDependencyFromWire(w *connectionDependencyWire) (*ConnectionDependency, error) { + if w == nil { + return nil, nil + } + return &ConnectionDependency{ + ConnectionName: w.ConnectionName, + }, nil +} + +type createFunctionWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + InputParams *functionParameterInfosWire `json:"input_params,omitempty"` + DataType ColumnTypeName `json:"data_type,omitempty"` + FullDataType *string `json:"full_data_type,omitempty"` + RoutineBody FunctionInfo_RoutineBody `json:"routine_body,omitempty"` + RoutineDefinition *string `json:"routine_definition,omitempty"` + ParameterStyle FunctionInfo_ParameterStyle `json:"parameter_style,omitempty"` + IsDeterministic *bool `json:"is_deterministic,omitempty"` + SqlDataAccess FunctionInfo_SqlDataAccess `json:"sql_data_access,omitempty"` + IsNullCall *bool `json:"is_null_call,omitempty"` + SecurityType FunctionInfo_SecurityType `json:"security_type,omitempty"` + SpecificName *string `json:"specific_name,omitempty"` + ReturnParams *functionParameterInfosWire `json:"return_params,omitempty"` + ExternalName *string `json:"external_name,omitempty"` + ExternalLanguage *string `json:"external_language,omitempty"` + SqlPath *string `json:"sql_path,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + Properties *string `json:"properties,omitempty"` + RoutineDependencies *dependencyListWire `json:"routine_dependencies,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + FunctionId *string `json:"function_id,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` +} + +func createFunctionToWire(v *CreateFunction) (*createFunctionWire, error) { + if v == nil { + return nil, nil + } + inputParamsWireValue, err := functionParameterInfosToWire(v.InputParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateFunction.InputParams", err) + } + returnParamsWireValue, err := functionParameterInfosToWire(v.ReturnParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateFunction.ReturnParams", err) + } + routineDependenciesWireValue, err := dependencyListToWire(v.RoutineDependencies) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateFunction.RoutineDependencies", err) + } + return &createFunctionWire{ + Name: v.Name, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + InputParams: inputParamsWireValue, + DataType: v.DataType, + FullDataType: v.FullDataType, + RoutineBody: v.RoutineBody, + RoutineDefinition: v.RoutineDefinition, + ParameterStyle: v.ParameterStyle, + IsDeterministic: v.IsDeterministic, + SqlDataAccess: v.SqlDataAccess, + IsNullCall: v.IsNullCall, + SecurityType: v.SecurityType, + SpecificName: v.SpecificName, + ReturnParams: returnParamsWireValue, + ExternalName: v.ExternalName, + ExternalLanguage: v.ExternalLanguage, + SqlPath: v.SqlPath, + Owner: v.Owner, + Comment: v.Comment, + Properties: v.Properties, + RoutineDependencies: routineDependenciesWireValue, + MetastoreId: v.MetastoreId, + FullName: v.FullName, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + FunctionId: v.FunctionId, + BrowseOnly: v.BrowseOnly, + }, nil +} + +type createFunctionRequestWire struct { + FunctionInfo *createFunctionWire `json:"function_info,omitempty"` +} + +func createFunctionRequestToWire(v *CreateFunctionRequest) (*createFunctionRequestWire, error) { + if v == nil { + return nil, nil + } + functionInfoWireValue, err := createFunctionToWire(v.FunctionInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateFunctionRequest.FunctionInfo", err) + } + return &createFunctionRequestWire{ + FunctionInfo: functionInfoWireValue, + }, nil +} + +type credentialDependencyWire struct { + CredentialName *string `json:"credential_name,omitempty"` +} + +func credentialDependencyToWire(v *CredentialDependency) (*credentialDependencyWire, error) { + if v == nil { + return nil, nil + } + return &credentialDependencyWire{ + CredentialName: v.CredentialName, + }, nil +} + +func credentialDependencyFromWire(w *credentialDependencyWire) (*CredentialDependency, error) { + if w == nil { + return nil, nil + } + return &CredentialDependency{ + CredentialName: w.CredentialName, + }, nil +} + +type deleteFunctionRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + Force *bool `json:"force,omitempty"` +} + +func deleteFunctionRequestToWire(v *DeleteFunctionRequest) (*deleteFunctionRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteFunctionRequestWire{ + FullNameArg: v.FullNameArg, + Force: v.Force, + }, nil +} + +type dependencyWire struct { + Table *tableDependencyWire `json:"table,omitempty"` + Function *functionDependencyWire `json:"function,omitempty"` + Connection *connectionDependencyWire `json:"connection,omitempty"` + Credential *credentialDependencyWire `json:"credential,omitempty"` +} + +func dependencyToWire(v *Dependency) (*dependencyWire, error) { + if v == nil { + return nil, nil + } + var valueTableWire *tableDependencyWire + var valueFunctionWire *functionDependencyWire + var valueConnectionWire *connectionDependencyWire + var valueCredentialWire *credentialDependencyWire + switch value := v.Value.(type) { + case nil: + case *Dependency_Value_Table: + if value != nil { + valueTableConverted, err := tableDependencyToWire(&value.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Table", err) + } + valueTableWire = valueTableConverted + } + case *Dependency_Value_Function: + if value != nil { + valueFunctionConverted, err := functionDependencyToWire(&value.Function) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Function", err) + } + valueFunctionWire = valueFunctionConverted + } + case *Dependency_Value_Connection: + if value != nil { + valueConnectionConverted, err := connectionDependencyToWire(&value.Connection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Connection", err) + } + valueConnectionWire = valueConnectionConverted + } + case *Dependency_Value_Credential: + if value != nil { + valueCredentialConverted, err := credentialDependencyToWire(&value.Credential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Credential", err) + } + valueCredentialWire = valueCredentialConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Dependency.Value", value) + } + return &dependencyWire{ + Table: valueTableWire, + Function: valueFunctionWire, + Connection: valueConnectionWire, + Credential: valueCredentialWire, + }, nil +} + +func dependencyFromWire(w *dependencyWire) (*Dependency, error) { + if w == nil { + return nil, nil + } + valueMembers := 0 + if w.Table != nil { + valueMembers++ + } + if w.Function != nil { + valueMembers++ + } + if w.Connection != nil { + valueMembers++ + } + if w.Credential != nil { + valueMembers++ + } + if valueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Dependency.Value") + } + var valueSelection isDependency_Value + switch { + case w.Table != nil: + valueTableConverted, err := tableDependencyFromWire(w.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Table", err) + } + valueSelection = &Dependency_Value_Table{Table: *valueTableConverted} + case w.Function != nil: + valueFunctionConverted, err := functionDependencyFromWire(w.Function) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Function", err) + } + valueSelection = &Dependency_Value_Function{Function: *valueFunctionConverted} + case w.Connection != nil: + valueConnectionConverted, err := connectionDependencyFromWire(w.Connection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Connection", err) + } + valueSelection = &Dependency_Value_Connection{Connection: *valueConnectionConverted} + case w.Credential != nil: + valueCredentialConverted, err := credentialDependencyFromWire(w.Credential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Credential", err) + } + valueSelection = &Dependency_Value_Credential{Credential: *valueCredentialConverted} + } + return &Dependency{ + Value: valueSelection, + }, nil +} + +type dependencyListWire struct { + Dependencies []dependencyWire `json:"dependencies,omitempty"` +} + +func dependencyListToWire(v *DependencyList) (*dependencyListWire, error) { + if v == nil { + return nil, nil + } + dependenciesWireValue, err := convertSlice(v.Dependencies, dependencyToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DependencyList.Dependencies", err) + } + return &dependencyListWire{ + Dependencies: dependenciesWireValue, + }, nil +} + +func dependencyListFromWire(w *dependencyListWire) (*DependencyList, error) { + if w == nil { + return nil, nil + } + dependenciesPublicValue, err := convertSlice(w.Dependencies, dependencyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DependencyList.Dependencies", err) + } + return &DependencyList{ + Dependencies: dependenciesPublicValue, + }, nil +} + +type functionDependencyWire struct { + FunctionFullName *string `json:"function_full_name,omitempty"` +} + +func functionDependencyToWire(v *FunctionDependency) (*functionDependencyWire, error) { + if v == nil { + return nil, nil + } + return &functionDependencyWire{ + FunctionFullName: v.FunctionFullName, + }, nil +} + +func functionDependencyFromWire(w *functionDependencyWire) (*FunctionDependency, error) { + if w == nil { + return nil, nil + } + return &FunctionDependency{ + FunctionFullName: w.FunctionFullName, + }, nil +} + +type functionInfoWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + InputParams *functionParameterInfosWire `json:"input_params,omitempty"` + DataType ColumnTypeName `json:"data_type,omitempty"` + FullDataType *string `json:"full_data_type,omitempty"` + RoutineBody FunctionInfo_RoutineBody `json:"routine_body,omitempty"` + RoutineDefinition *string `json:"routine_definition,omitempty"` + ParameterStyle FunctionInfo_ParameterStyle `json:"parameter_style,omitempty"` + IsDeterministic *bool `json:"is_deterministic,omitempty"` + SqlDataAccess FunctionInfo_SqlDataAccess `json:"sql_data_access,omitempty"` + IsNullCall *bool `json:"is_null_call,omitempty"` + SecurityType FunctionInfo_SecurityType `json:"security_type,omitempty"` + SpecificName *string `json:"specific_name,omitempty"` + ReturnParams *functionParameterInfosWire `json:"return_params,omitempty"` + ExternalName *string `json:"external_name,omitempty"` + ExternalLanguage *string `json:"external_language,omitempty"` + SqlPath *string `json:"sql_path,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + Properties *string `json:"properties,omitempty"` + RoutineDependencies *dependencyListWire `json:"routine_dependencies,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + FunctionId *string `json:"function_id,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` +} + +func functionInfoFromWire(w *functionInfoWire) (*FunctionInfo, error) { + if w == nil { + return nil, nil + } + inputParamsPublicValue, err := functionParameterInfosFromWire(w.InputParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FunctionInfo.InputParams", err) + } + returnParamsPublicValue, err := functionParameterInfosFromWire(w.ReturnParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FunctionInfo.ReturnParams", err) + } + routineDependenciesPublicValue, err := dependencyListFromWire(w.RoutineDependencies) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FunctionInfo.RoutineDependencies", err) + } + return &FunctionInfo{ + Name: w.Name, + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + InputParams: inputParamsPublicValue, + DataType: w.DataType, + FullDataType: w.FullDataType, + RoutineBody: w.RoutineBody, + RoutineDefinition: w.RoutineDefinition, + ParameterStyle: w.ParameterStyle, + IsDeterministic: w.IsDeterministic, + SqlDataAccess: w.SqlDataAccess, + IsNullCall: w.IsNullCall, + SecurityType: w.SecurityType, + SpecificName: w.SpecificName, + ReturnParams: returnParamsPublicValue, + ExternalName: w.ExternalName, + ExternalLanguage: w.ExternalLanguage, + SqlPath: w.SqlPath, + Owner: w.Owner, + Comment: w.Comment, + Properties: w.Properties, + RoutineDependencies: routineDependenciesPublicValue, + MetastoreId: w.MetastoreId, + FullName: w.FullName, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + FunctionId: w.FunctionId, + BrowseOnly: w.BrowseOnly, + }, nil +} + +type functionParameterInfoWire struct { + Name *string `json:"name,omitempty"` + TypeText *string `json:"type_text,omitempty"` + TypeJson *string `json:"type_json,omitempty"` + TypeName ColumnTypeName `json:"type_name,omitempty"` + TypePrecision *int `json:"type_precision,omitempty"` + TypeScale *int `json:"type_scale,omitempty"` + TypeIntervalType *string `json:"type_interval_type,omitempty"` + Position *int `json:"position,omitempty"` + ParameterMode FunctionParameterMode `json:"parameter_mode,omitempty"` + ParameterType FunctionParameterType `json:"parameter_type,omitempty"` + ParameterDefault *string `json:"parameter_default,omitempty"` + Comment *string `json:"comment,omitempty"` +} + +func functionParameterInfoToWire(v *FunctionParameterInfo) (*functionParameterInfoWire, error) { + if v == nil { + return nil, nil + } + return &functionParameterInfoWire{ + Name: v.Name, + TypeText: v.TypeText, + TypeJson: v.TypeJson, + TypeName: v.TypeName, + TypePrecision: v.TypePrecision, + TypeScale: v.TypeScale, + TypeIntervalType: v.TypeIntervalType, + Position: v.Position, + ParameterMode: v.ParameterMode, + ParameterType: v.ParameterType, + ParameterDefault: v.ParameterDefault, + Comment: v.Comment, + }, nil +} + +func functionParameterInfoFromWire(w *functionParameterInfoWire) (*FunctionParameterInfo, error) { + if w == nil { + return nil, nil + } + return &FunctionParameterInfo{ + Name: w.Name, + TypeText: w.TypeText, + TypeJson: w.TypeJson, + TypeName: w.TypeName, + TypePrecision: w.TypePrecision, + TypeScale: w.TypeScale, + TypeIntervalType: w.TypeIntervalType, + Position: w.Position, + ParameterMode: w.ParameterMode, + ParameterType: w.ParameterType, + ParameterDefault: w.ParameterDefault, + Comment: w.Comment, + }, nil +} + +type functionParameterInfosWire struct { + Parameters []functionParameterInfoWire `json:"parameters,omitempty"` +} + +func functionParameterInfosToWire(v *FunctionParameterInfos) (*functionParameterInfosWire, error) { + if v == nil { + return nil, nil + } + parametersWireValue, err := convertSlice(v.Parameters, functionParameterInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FunctionParameterInfos.Parameters", err) + } + return &functionParameterInfosWire{ + Parameters: parametersWireValue, + }, nil +} + +func functionParameterInfosFromWire(w *functionParameterInfosWire) (*FunctionParameterInfos, error) { + if w == nil { + return nil, nil + } + parametersPublicValue, err := convertSlice(w.Parameters, functionParameterInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "FunctionParameterInfos.Parameters", err) + } + return &FunctionParameterInfos{ + Parameters: parametersPublicValue, + }, nil +} + +type getFunctionRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` +} + +func getFunctionRequestToWire(v *GetFunctionRequest) (*getFunctionRequestWire, error) { + if v == nil { + return nil, nil + } + return &getFunctionRequestWire{ + FullNameArg: v.FullNameArg, + IncludeBrowse: v.IncludeBrowse, + }, nil +} + +type listFunctionsRequestWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listFunctionsRequestToWire(v *ListFunctionsRequest) (*listFunctionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listFunctionsRequestWire{ + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + IncludeBrowse: v.IncludeBrowse, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listFunctionsResponseWire struct { + Functions []functionInfoWire `json:"functions,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listFunctionsResponseFromWire(w *listFunctionsResponseWire) (*ListFunctionsResponse, error) { + if w == nil { + return nil, nil + } + functionsPublicValue, err := convertSlice(w.Functions, functionInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListFunctionsResponse.Functions", err) + } + return &ListFunctionsResponse{ + Functions: functionsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type tableDependencyWire struct { + TableFullName *string `json:"table_full_name,omitempty"` +} + +func tableDependencyToWire(v *TableDependency) (*tableDependencyWire, error) { + if v == nil { + return nil, nil + } + return &tableDependencyWire{ + TableFullName: v.TableFullName, + }, nil +} + +func tableDependencyFromWire(w *tableDependencyWire) (*TableDependency, error) { + if w == nil { + return nil, nil + } + return &TableDependency{ + TableFullName: w.TableFullName, + }, nil +} + +type updateFunctionRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + InputParams *functionParameterInfosWire `json:"input_params,omitempty"` + DataType ColumnTypeName `json:"data_type,omitempty"` + FullDataType *string `json:"full_data_type,omitempty"` + RoutineBody FunctionInfo_RoutineBody `json:"routine_body,omitempty"` + RoutineDefinition *string `json:"routine_definition,omitempty"` + ParameterStyle FunctionInfo_ParameterStyle `json:"parameter_style,omitempty"` + IsDeterministic *bool `json:"is_deterministic,omitempty"` + SqlDataAccess FunctionInfo_SqlDataAccess `json:"sql_data_access,omitempty"` + IsNullCall *bool `json:"is_null_call,omitempty"` + SecurityType FunctionInfo_SecurityType `json:"security_type,omitempty"` + SpecificName *string `json:"specific_name,omitempty"` + ReturnParams *functionParameterInfosWire `json:"return_params,omitempty"` + ExternalName *string `json:"external_name,omitempty"` + ExternalLanguage *string `json:"external_language,omitempty"` + SqlPath *string `json:"sql_path,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + Properties *string `json:"properties,omitempty"` + RoutineDependencies *dependencyListWire `json:"routine_dependencies,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + FunctionId *string `json:"function_id,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` +} + +func updateFunctionRequestToWire(v *UpdateFunctionRequest) (*updateFunctionRequestWire, error) { + if v == nil { + return nil, nil + } + inputParamsWireValue, err := functionParameterInfosToWire(v.InputParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateFunctionRequest.InputParams", err) + } + returnParamsWireValue, err := functionParameterInfosToWire(v.ReturnParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateFunctionRequest.ReturnParams", err) + } + routineDependenciesWireValue, err := dependencyListToWire(v.RoutineDependencies) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateFunctionRequest.RoutineDependencies", err) + } + return &updateFunctionRequestWire{ + FullNameArg: v.FullNameArg, + Name: v.Name, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + InputParams: inputParamsWireValue, + DataType: v.DataType, + FullDataType: v.FullDataType, + RoutineBody: v.RoutineBody, + RoutineDefinition: v.RoutineDefinition, + ParameterStyle: v.ParameterStyle, + IsDeterministic: v.IsDeterministic, + SqlDataAccess: v.SqlDataAccess, + IsNullCall: v.IsNullCall, + SecurityType: v.SecurityType, + SpecificName: v.SpecificName, + ReturnParams: returnParamsWireValue, + ExternalName: v.ExternalName, + ExternalLanguage: v.ExternalLanguage, + SqlPath: v.SqlPath, + Owner: v.Owner, + Comment: v.Comment, + Properties: v.Properties, + RoutineDependencies: routineDependenciesWireValue, + MetastoreId: v.MetastoreId, + FullName: v.FullName, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + FunctionId: v.FunctionId, + BrowseOnly: v.BrowseOnly, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/grants/.package.json b/uc/grants/.package.json new file mode 100644 index 0000000..16a05f1 --- /dev/null +++ b/uc/grants/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/grants" +} diff --git a/uc/grants/CHANGELOG.md b/uc/grants/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/grants/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/grants/README.md b/uc/grants/README.md new file mode 100644 index 0000000..ba177e0 --- /dev/null +++ b/uc/grants/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/grants + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/grants@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/grants/v1" + +client, err := grants.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/grants/go.mod b/uc/grants/go.mod new file mode 100644 index 0000000..04066e2 --- /dev/null +++ b/uc/grants/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/grants + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/grants/internal/version.go b/uc/grants/internal/version.go new file mode 100644 index 0000000..99b7ca3 --- /dev/null +++ b/uc/grants/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-grants" + +const Version = "0.0.1-dev.1" diff --git a/uc/grants/v1/client.go b/uc/grants/v1/client.go new file mode 100755 index 0000000..3b11cfa --- /dev/null +++ b/uc/grants/v1/client.go @@ -0,0 +1,553 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package grants + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/grants/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Gets the effective permissions for a securable. Includes inherited +// permissions from any parent securables. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) GetEffectivePermissions(ctx context.Context, req *GetEffectivePermissionsRequest, opts ...call.Option) (*GetEffectivePermissionsResponse, error) { + wireReq, err := getEffectivePermissionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/effective-permissions/") + pb.singleSegment(*req.SecurableType) + pb.literal("/") + pb.singleSegment(*req.SecurableFullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "principal", wireReq.Principal); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetEffectivePermissionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getEffectivePermissionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getEffectivePermissionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the permissions for a securable. Does not include inherited permissions. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) GetPermissions(ctx context.Context, req *GetPermissionsRequest, opts ...call.Option) (*GetPermissionsResponse, error) { + wireReq, err := getPermissionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/permissions/") + pb.singleSegment(*req.SecurableType) + pb.literal("/") + pb.singleSegment(*req.SecurableFullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "principal", wireReq.Principal); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetPermissionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getPermissionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getPermissionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists the effective privilege assignments for a securable. Includes inherited +// privileges. Paginated version of Get Effective Permissions API. +func (c *internalClient) ListEffectivePrivilegeAssignments(ctx context.Context, req *ListEffectivePrivilegeAssignmentsRequest, opts ...call.Option) (*ListEffectivePrivilegeAssignmentsResponse, error) { + wireReq, err := listEffectivePrivilegeAssignmentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/effective-privilege-assignments/") + pb.singleSegment(*req.SecurableType) + pb.literal("/") + pb.singleSegment(*req.FullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "principal", wireReq.Principal); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListEffectivePrivilegeAssignmentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listEffectivePrivilegeAssignmentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listEffectivePrivilegeAssignmentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListEffectivePrivilegeAssignmentsIter returns an iterator that iterates +// over the results of ListEffectivePrivilegeAssignments. +// +// For example: +// +// for item, err := range c.ListEffectivePrivilegeAssignmentsIter(ctx, &ListEffectivePrivilegeAssignmentsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListEffectivePrivilegeAssignments call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListEffectivePrivilegeAssignments directly. +func (c *internalClient) ListEffectivePrivilegeAssignmentsIter(ctx context.Context, req *ListEffectivePrivilegeAssignmentsRequest, opts ...call.Option) iter.Seq2[*EffectivePrivilegeAssignment, error] { + return func(yield func(*EffectivePrivilegeAssignment, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListEffectivePrivilegeAssignmentsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListEffectivePrivilegeAssignments(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.EffectivePrivilegeAssignments { + if !yield(&resp.EffectivePrivilegeAssignments[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Lists the privilege assignments for a securable. Does not include inherited +// privileges. Paginated version of Get Permissions API. +func (c *internalClient) ListPrivilegeAssignments(ctx context.Context, req *ListPrivilegeAssignmentsRequest, opts ...call.Option) (*ListPrivilegeAssignmentsResponse, error) { + wireReq, err := listPrivilegeAssignmentsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/privilege-assignments/") + pb.singleSegment(*req.SecurableType) + pb.literal("/") + pb.singleSegment(*req.FullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "principal", wireReq.Principal); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListPrivilegeAssignmentsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listPrivilegeAssignmentsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listPrivilegeAssignmentsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListPrivilegeAssignmentsIter returns an iterator that iterates +// over the results of ListPrivilegeAssignments. +// +// For example: +// +// for item, err := range c.ListPrivilegeAssignmentsIter(ctx, &ListPrivilegeAssignmentsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListPrivilegeAssignments call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListPrivilegeAssignments directly. +func (c *internalClient) ListPrivilegeAssignmentsIter(ctx context.Context, req *ListPrivilegeAssignmentsRequest, opts ...call.Option) iter.Seq2[*PrivilegeAssignment, error] { + return func(yield func(*PrivilegeAssignment, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListPrivilegeAssignmentsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListPrivilegeAssignments(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.PrivilegeAssignments { + if !yield(&resp.PrivilegeAssignments[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates the permissions for a securable. +func (c *internalClient) UpdatePermissions(ctx context.Context, req *UpdatePermissionsRequest, opts ...call.Option) (*UpdatePermissionsResponse, error) { + wireReq, err := updatePermissionsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/permissions/") + pb.singleSegment(*req.SecurableType) + pb.literal("/") + pb.singleSegment(*req.SecurableFullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdatePermissionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updatePermissionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updatePermissionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/grants/v1/genhelper.go b/uc/grants/v1/genhelper.go new file mode 100755 index 0000000..9384e9d --- /dev/null +++ b/uc/grants/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package grants + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/grants/v1/model.go b/uc/grants/v1/model.go new file mode 100755 index 0000000..81133ac --- /dev/null +++ b/uc/grants/v1/model.go @@ -0,0 +1,194 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package grants + +type EffectivePrivilege struct { + // The privilege assigned to the principal. + Privilege *string + // The type of the object that conveys this privilege via inheritance. This + // field is omitted when privilege is not inherited (it's assigned to the + // securable itself). + InheritedFromType *string + // The full name of the object that conveys this privilege via inheritance. This + // field is omitted when privilege is not inherited (it's assigned to the + // securable itself). + InheritedFromName *string +} + +type EffectivePrivilegeAssignment struct { + // The principal (user email address or group name). + Principal *string + // The privileges conveyed to the principal (either directly or via + // inheritance). + Privileges []EffectivePrivilege +} + +type GetEffectivePermissionsRequest struct { + // Type of securable. + SecurableType *string + // Full name of securable. + SecurableFullName *string + // If provided, only the effective permissions for the specified principal (user + // or group) are returned. + Principal *string + // Specifies the maximum number of privileges to return (page length). Every + // EffectivePrivilegeAssignment present in a single page response is guaranteed + // to contain all the effective privileges granted on (or inherited by) the + // requested Securable for the respective principal. + // + // If not set, all the effective permissions are returned. If set to - lesser + // than 0: invalid parameter error - 0: page length is set to a server + // configured value - lesser than 150 but greater than 0: invalid parameter + // error (this is to ensure that server is able to return at least one complete + // EffectivePrivilegeAssignment in a single page response) - greater than (or + // equal to) 150: page length is the minimum of this value and a server + // configured value + MaxResults *int + // Opaque token for the next page of results (pagination). + PageToken *string +} + +type GetEffectivePermissionsResponse struct { + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string + // The privileges conveyed to each principal (either directly or via + // inheritance) + PrivilegeAssignments []EffectivePrivilegeAssignment +} + +type GetPermissionsRequest struct { + // Type of securable. + SecurableType *string + // Full name of securable. + SecurableFullName *string + // If provided, only the permissions for the specified principal (user or group) + // are returned. + Principal *string + // Specifies the maximum number of privileges to return (page length). Every + // PrivilegeAssignment present in a single page response is guaranteed to + // contain all the privileges granted on the requested Securable for the + // respective principal. + // + // If not set, all the permissions are returned. If set to - lesser than 0: + // invalid parameter error - 0: page length is set to a server configured value + // - lesser than 150 but greater than 0: invalid parameter error (this is to + // ensure that server is able to return at least one complete + // PrivilegeAssignment in a single page response) - greater than (or equal to) + // 150: page length is the minimum of this value and a server configured value + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type GetPermissionsResponse struct { + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string + // The privileges assigned to each principal + PrivilegeAssignments []PrivilegeAssignment +} + +type ListEffectivePrivilegeAssignmentsRequest struct { + // Type of securable. + SecurableType *string + // Full name of securable. + FullName *string + // If provided, only the effective permissions for the specified principal (user + // or group) are returned. + Principal *string + // Specifies the maximum number of privilege assignments to return (page + // length). Every EffectivePrivilegeAssignment present in a single page response + // is guaranteed to contain all the effective privileges granted on (or + // inherited by) the requested Securable for the respective principal. + // + // If not set, a server-configured default is used. If set to - lesser than 0: + // invalid parameter error - 0: page length is set to a server configured value + // - lesser than 150 but greater than 0: invalid parameter error (this is to + // ensure that server is able to return at least one complete + // EffectivePrivilegeAssignment in a single page response) - greater than (or + // equal to) 150: page length is the minimum of this value and a server + // configured value + PageSize *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListEffectivePrivilegeAssignmentsResponse struct { + // The effective privilege assignments for the securable (and optional + // principal). + EffectivePrivilegeAssignments []EffectivePrivilegeAssignment + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type ListPrivilegeAssignmentsRequest struct { + // Type of securable. + SecurableType *string + // Full name of securable. + FullName *string + // If provided, only the permissions for the specified principal (user or group) + // are returned. + Principal *string + // Specifies the maximum number of privilege assignments to return (page + // length). Every PrivilegeAssignment present in a single page response is + // guaranteed to contain all the privileges granted on the requested Securable + // for the respective principal. + // + // If not set, page length is the server configured value. If set to - lesser + // than 0: invalid parameter error - 0: page length is set to a server + // configured value - lesser than 150 but greater than 0: invalid parameter + // error (this is to ensure that server is able to return at least one complete + // PrivilegeAssignment in a single page response) - greater than (or equal to) + // 150: page length is the minimum of this value and a server configured value + PageSize *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListPrivilegeAssignmentsResponse struct { + PrivilegeAssignments []PrivilegeAssignment + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type PermissionsChange struct { + // The principal whose privileges we are changing. Only one of principal or + // principal_id should be specified, never both at the same time. + Principal *string + // The set of privileges to add. + Add []string + // The set of privileges to remove. + Remove []string +} + +type PrivilegeAssignment struct { + // The principal (user email address or group name). For deleted principals, + // `principal` is empty while `principal_id` is populated. + Principal *string + // The privileges assigned to the principal. + Privileges []string +} + +type UpdatePermissionsRequest struct { + // Type of securable. + SecurableType *string + // Full name of securable. + SecurableFullName *string + // Optional, default false. Specifies whether all the permissions should be + // returned in the response. + OmitPermissionsInResponse *bool + // Array of permissions change objects. + Changes []PermissionsChange +} + +type UpdatePermissionsResponse struct { + // The privileges assigned to each principal + PrivilegeAssignments []PrivilegeAssignment +} diff --git a/uc/grants/v1/wire.go b/uc/grants/v1/wire.go new file mode 100755 index 0000000..4b27732 --- /dev/null +++ b/uc/grants/v1/wire.go @@ -0,0 +1,290 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package grants + +import ( + "fmt" +) + +type effectivePrivilegeWire struct { + Privilege *string `json:"privilege,omitempty"` + InheritedFromType *string `json:"inherited_from_type,omitempty"` + InheritedFromName *string `json:"inherited_from_name,omitempty"` +} + +func effectivePrivilegeFromWire(w *effectivePrivilegeWire) (*EffectivePrivilege, error) { + if w == nil { + return nil, nil + } + return &EffectivePrivilege{ + Privilege: w.Privilege, + InheritedFromType: w.InheritedFromType, + InheritedFromName: w.InheritedFromName, + }, nil +} + +type effectivePrivilegeAssignmentWire struct { + Principal *string `json:"principal,omitempty"` + Privileges []effectivePrivilegeWire `json:"privileges,omitempty"` +} + +func effectivePrivilegeAssignmentFromWire(w *effectivePrivilegeAssignmentWire) (*EffectivePrivilegeAssignment, error) { + if w == nil { + return nil, nil + } + privilegesPublicValue, err := convertSlice(w.Privileges, effectivePrivilegeFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EffectivePrivilegeAssignment.Privileges", err) + } + return &EffectivePrivilegeAssignment{ + Principal: w.Principal, + Privileges: privilegesPublicValue, + }, nil +} + +type getEffectivePermissionsRequestWire struct { + SecurableType *string `json:"securable_type,omitempty"` + SecurableFullName *string `json:"securable_full_name,omitempty"` + Principal *string `json:"principal,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func getEffectivePermissionsRequestToWire(v *GetEffectivePermissionsRequest) (*getEffectivePermissionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &getEffectivePermissionsRequestWire{ + SecurableType: v.SecurableType, + SecurableFullName: v.SecurableFullName, + Principal: v.Principal, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type getEffectivePermissionsResponseWire struct { + NextPageToken *string `json:"next_page_token,omitempty"` + PrivilegeAssignments []effectivePrivilegeAssignmentWire `json:"privilege_assignments,omitempty"` +} + +func getEffectivePermissionsResponseFromWire(w *getEffectivePermissionsResponseWire) (*GetEffectivePermissionsResponse, error) { + if w == nil { + return nil, nil + } + privilegeAssignmentsPublicValue, err := convertSlice(w.PrivilegeAssignments, effectivePrivilegeAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetEffectivePermissionsResponse.PrivilegeAssignments", err) + } + return &GetEffectivePermissionsResponse{ + NextPageToken: w.NextPageToken, + PrivilegeAssignments: privilegeAssignmentsPublicValue, + }, nil +} + +type getPermissionsRequestWire struct { + SecurableType *string `json:"securable_type,omitempty"` + SecurableFullName *string `json:"securable_full_name,omitempty"` + Principal *string `json:"principal,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func getPermissionsRequestToWire(v *GetPermissionsRequest) (*getPermissionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &getPermissionsRequestWire{ + SecurableType: v.SecurableType, + SecurableFullName: v.SecurableFullName, + Principal: v.Principal, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type getPermissionsResponseWire struct { + NextPageToken *string `json:"next_page_token,omitempty"` + PrivilegeAssignments []privilegeAssignmentWire `json:"privilege_assignments,omitempty"` +} + +func getPermissionsResponseFromWire(w *getPermissionsResponseWire) (*GetPermissionsResponse, error) { + if w == nil { + return nil, nil + } + privilegeAssignmentsPublicValue, err := convertSlice(w.PrivilegeAssignments, privilegeAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetPermissionsResponse.PrivilegeAssignments", err) + } + return &GetPermissionsResponse{ + NextPageToken: w.NextPageToken, + PrivilegeAssignments: privilegeAssignmentsPublicValue, + }, nil +} + +type listEffectivePrivilegeAssignmentsRequestWire struct { + SecurableType *string `json:"securable_type,omitempty"` + FullName *string `json:"full_name,omitempty"` + Principal *string `json:"principal,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listEffectivePrivilegeAssignmentsRequestToWire(v *ListEffectivePrivilegeAssignmentsRequest) (*listEffectivePrivilegeAssignmentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listEffectivePrivilegeAssignmentsRequestWire{ + SecurableType: v.SecurableType, + FullName: v.FullName, + Principal: v.Principal, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listEffectivePrivilegeAssignmentsResponseWire struct { + EffectivePrivilegeAssignments []effectivePrivilegeAssignmentWire `json:"effective_privilege_assignments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listEffectivePrivilegeAssignmentsResponseFromWire(w *listEffectivePrivilegeAssignmentsResponseWire) (*ListEffectivePrivilegeAssignmentsResponse, error) { + if w == nil { + return nil, nil + } + effectivePrivilegeAssignmentsPublicValue, err := convertSlice(w.EffectivePrivilegeAssignments, effectivePrivilegeAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListEffectivePrivilegeAssignmentsResponse.EffectivePrivilegeAssignments", err) + } + return &ListEffectivePrivilegeAssignmentsResponse{ + EffectivePrivilegeAssignments: effectivePrivilegeAssignmentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listPrivilegeAssignmentsRequestWire struct { + SecurableType *string `json:"securable_type,omitempty"` + FullName *string `json:"full_name,omitempty"` + Principal *string `json:"principal,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listPrivilegeAssignmentsRequestToWire(v *ListPrivilegeAssignmentsRequest) (*listPrivilegeAssignmentsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listPrivilegeAssignmentsRequestWire{ + SecurableType: v.SecurableType, + FullName: v.FullName, + Principal: v.Principal, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listPrivilegeAssignmentsResponseWire struct { + PrivilegeAssignments []privilegeAssignmentWire `json:"privilege_assignments,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listPrivilegeAssignmentsResponseFromWire(w *listPrivilegeAssignmentsResponseWire) (*ListPrivilegeAssignmentsResponse, error) { + if w == nil { + return nil, nil + } + privilegeAssignmentsPublicValue, err := convertSlice(w.PrivilegeAssignments, privilegeAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListPrivilegeAssignmentsResponse.PrivilegeAssignments", err) + } + return &ListPrivilegeAssignmentsResponse{ + PrivilegeAssignments: privilegeAssignmentsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type permissionsChangeWire struct { + Principal *string `json:"principal,omitempty"` + Add []string `json:"add,omitempty"` + Remove []string `json:"remove,omitempty"` +} + +func permissionsChangeToWire(v *PermissionsChange) (*permissionsChangeWire, error) { + if v == nil { + return nil, nil + } + return &permissionsChangeWire{ + Principal: v.Principal, + Add: v.Add, + Remove: v.Remove, + }, nil +} + +type privilegeAssignmentWire struct { + Principal *string `json:"principal,omitempty"` + Privileges []string `json:"privileges,omitempty"` +} + +func privilegeAssignmentFromWire(w *privilegeAssignmentWire) (*PrivilegeAssignment, error) { + if w == nil { + return nil, nil + } + return &PrivilegeAssignment{ + Principal: w.Principal, + Privileges: w.Privileges, + }, nil +} + +type updatePermissionsRequestWire struct { + SecurableType *string `json:"securable_type,omitempty"` + SecurableFullName *string `json:"securable_full_name,omitempty"` + OmitPermissionsInResponse *bool `json:"omit_permissions_in_response,omitempty"` + Changes []permissionsChangeWire `json:"changes,omitempty"` +} + +func updatePermissionsRequestToWire(v *UpdatePermissionsRequest) (*updatePermissionsRequestWire, error) { + if v == nil { + return nil, nil + } + changesWireValue, err := convertSlice(v.Changes, permissionsChangeToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdatePermissionsRequest.Changes", err) + } + return &updatePermissionsRequestWire{ + SecurableType: v.SecurableType, + SecurableFullName: v.SecurableFullName, + OmitPermissionsInResponse: v.OmitPermissionsInResponse, + Changes: changesWireValue, + }, nil +} + +type updatePermissionsResponseWire struct { + PrivilegeAssignments []privilegeAssignmentWire `json:"privilege_assignments,omitempty"` +} + +func updatePermissionsResponseFromWire(w *updatePermissionsResponseWire) (*UpdatePermissionsResponse, error) { + if w == nil { + return nil, nil + } + privilegeAssignmentsPublicValue, err := convertSlice(w.PrivilegeAssignments, privilegeAssignmentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdatePermissionsResponse.PrivilegeAssignments", err) + } + return &UpdatePermissionsResponse{ + PrivilegeAssignments: privilegeAssignmentsPublicValue, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/metastores/.package.json b/uc/metastores/.package.json new file mode 100644 index 0000000..24566b8 --- /dev/null +++ b/uc/metastores/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/metastores" +} diff --git a/uc/metastores/CHANGELOG.md b/uc/metastores/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/metastores/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/metastores/README.md b/uc/metastores/README.md new file mode 100644 index 0000000..a81b7be --- /dev/null +++ b/uc/metastores/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/metastores + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/metastores@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/metastores/v1" + +client, err := metastores.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/metastores/go.mod b/uc/metastores/go.mod new file mode 100644 index 0000000..c81ab1b --- /dev/null +++ b/uc/metastores/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/metastores + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/metastores/internal/version.go b/uc/metastores/internal/version.go new file mode 100644 index 0000000..6a76018 --- /dev/null +++ b/uc/metastores/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-metastores" + +const Version = "0.0.1-dev.1" diff --git a/uc/metastores/v1/client.go b/uc/metastores/v1/client.go new file mode 100755 index 0000000..ae93a6f --- /dev/null +++ b/uc/metastores/v1/client.go @@ -0,0 +1,1441 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package metastores + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/metastores/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a Unity Catalog metastore. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateAccountsMetastore(ctx context.Context, req *AccountsCreateMetastoreRequest, opts ...call.Option) (*AccountsCreateMetastoreResponse, error) { + wireReq, err := accountsCreateMetastoreRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsCreateMetastoreResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountsCreateMetastoreResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountsCreateMetastoreResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates an assignment to a metastore for a workspace +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateAccountsMetastoreAssignment(ctx context.Context, req *AccountsCreateMetastoreAssignmentRequest, opts ...call.Option) (*AccountsCreateMetastoreAssignmentResponse, error) { + wireReq, err := accountsCreateMetastoreAssignmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsCreateMetastoreAssignmentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &AccountsCreateMetastoreAssignmentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a Unity Catalog metastore for an account, both specified by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteAccountsMetastore(ctx context.Context, req *AccountsDeleteMetastoreRequest, opts ...call.Option) (*AccountsDeleteMetastoreResponse, error) { + wireReq, err := accountsDeleteMetastoreRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsDeleteMetastoreResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &AccountsDeleteMetastoreResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a metastore assignment to a workspace, leaving the workspace with no +// metastore. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteAccountsMetastoreAssignment(ctx context.Context, req *AccountsDeleteMetastoreAssignmentRequest, opts ...call.Option) (*AccountsDeleteMetastoreAssignmentResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsDeleteMetastoreAssignmentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &AccountsDeleteMetastoreAssignmentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a Unity Catalog metastore from an account, both specified by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetAccountsMetastore(ctx context.Context, req *AccountsGetMetastoreRequest, opts ...call.Option) (*AccountsGetMetastoreResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsGetMetastoreResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountsGetMetastoreResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountsGetMetastoreResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the metastore assignment, if any, for the workspace specified by ID. If +// the workspace is assigned a metastore, the mapping will be returned. If no +// metastore is assigned to the workspace, the assignment will not be found and +// a 404 returned. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetMetastoreAssignment(ctx context.Context, req *AccountsGetMetastoreAssignmentRequest, opts ...call.Option) (*AccountsGetMetastoreAssignmentResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/metastore") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsGetMetastoreAssignmentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountsGetMetastoreAssignmentResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountsGetMetastoreAssignmentResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets all Unity Catalog metastores associated with an account specified by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListAccountsMetastores(ctx context.Context, req *AccountsListMetastoresRequest, opts ...call.Option) (*AccountsListMetastoresResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsListMetastoresResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountsListMetastoresResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountsListMetastoresResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a list of all workspace IDs that have been assigned to +// given metastore. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListMetastoreAssignments(ctx context.Context, req *AccountsListWorkspaceIdsForMetastoreRequest, opts ...call.Option) (*AccountsListWorkspaceIdsForMetastoreResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + pb.literal("/workspaces") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsListWorkspaceIdsForMetastoreResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountsListWorkspaceIdsForMetastoreResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountsListWorkspaceIdsForMetastoreResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an existing Unity Catalog metastore. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateAccountsMetastore(ctx context.Context, req *AccountsUpdateMetastoreRequest, opts ...call.Option) (*AccountsUpdateMetastoreResponse, error) { + wireReq, err := accountsUpdateMetastoreRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsUpdateMetastoreResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accountsUpdateMetastoreResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accountsUpdateMetastoreResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates an assignment to a metastore for a workspace. Currently, only the +// default catalog may be updated. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) UpdateAccountsMetastoreAssignment(ctx context.Context, req *AccountsUpdateMetastoreAssignmentRequest, opts ...call.Option) (*AccountsUpdateMetastoreAssignmentResponse, error) { + wireReq, err := accountsUpdateMetastoreAssignmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/metastores/") + pb.singleSegment(*req.MetastoreId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccountsUpdateMetastoreAssignmentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &AccountsUpdateMetastoreAssignmentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new metastore based on a provided name and optional storage root +// path. By default (if the __owner__ field is not set), the owner of the new +// metastore is the user calling the __createMetastore__ API. If the __owner__ +// field is set to the empty string (**""**), the ownership is assigned to the +// System User instead. +func (c *internalClient) CreateMetastore(ctx context.Context, req *CreateMetastoreRequest, opts ...call.Option) (*MetastoreInfo, error) { + wireReq, err := createMetastoreRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/metastores" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *MetastoreInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp metastoreInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = metastoreInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new metastore assignment. If an assignment for the same +// __workspace_id__ exists, it will be overwritten by the new __metastore_id__ +// and __default_catalog_name__. The caller must be an account admin. +func (c *internalClient) CreateMetastoreAssignment(ctx context.Context, req *CreateMetastoreAssignmentRequest, opts ...call.Option) (*CreateMetastoreAssignmentResponse, error) { + wireReq, err := createMetastoreAssignmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/metastore") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateMetastoreAssignmentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &CreateMetastoreAssignmentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a metastore. The caller must be a metastore admin. +func (c *internalClient) DeleteMetastore(ctx context.Context, req *DeleteMetastoreRequest, opts ...call.Option) (*DeleteMetastoreResponse, error) { + wireReq, err := deleteMetastoreRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/metastores/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteMetastoreResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteMetastoreResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a metastore assignment. The caller must be an account administrator. +func (c *internalClient) DeleteMetastoreAssignment(ctx context.Context, req *DeleteMetastoreAssignmentRequest, opts ...call.Option) (*DeleteMetastoreAssignmentResponse, error) { + wireReq, err := deleteMetastoreAssignmentRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/metastore") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "metastore_id", wireReq.MetastoreId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteMetastoreAssignmentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteMetastoreAssignmentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the metastore assignment for the workspace being accessed. +func (c *internalClient) GetCurrentMetastoreAssignment(ctx context.Context, req *GetCurrentMetastoreAssignmentRequest, opts ...call.Option) (*MetastoreAssignment, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/current-metastore-assignment" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *MetastoreAssignment + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp metastoreAssignmentWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = metastoreAssignmentFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a metastore that matches the supplied ID. The caller must be a metastore +// admin to retrieve this info. +func (c *internalClient) GetMetastore(ctx context.Context, req *GetMetastoreRequest, opts ...call.Option) (*MetastoreInfo, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/metastores/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *MetastoreInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp metastoreInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = metastoreInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets information about a metastore. This summary includes the storage +// credential, the cloud vendor, the cloud region, and the global metastore ID. +func (c *internalClient) GetMetastoreSummary(ctx context.Context, req *GetMetastoreSummaryRequest, opts ...call.Option) (*GetMetastoreSummaryResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/metastore_summary" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetMetastoreSummaryResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getMetastoreSummaryResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getMetastoreSummaryResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of the available metastores (as __MetastoreInfo__ objects). The +// caller must be an admin to retrieve this info. There is no guarantee of a +// specific ordering of the elements in the array. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) ListMetastores(ctx context.Context, req *ListMetastoresRequest, opts ...call.Option) (*ListMetastoresResponse, error) { + wireReq, err := listMetastoresRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/metastores" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListMetastoresResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listMetastoresResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listMetastoresResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListMetastoresIter returns an iterator that iterates +// over the results of ListMetastores. +// +// For example: +// +// for item, err := range c.ListMetastoresIter(ctx, &ListMetastoresRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListMetastores call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListMetastores directly. +func (c *internalClient) ListMetastoresIter(ctx context.Context, req *ListMetastoresRequest, opts ...call.Option) iter.Seq2[*MetastoreInfo, error] { + return func(yield func(*MetastoreInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListMetastoresRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListMetastores(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Metastores { + if !yield(&resp.Metastores[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates information for a specific metastore. The caller must be a metastore +// admin. If the __owner__ field is set to the empty string (**""**), the +// ownership is updated to the System User. +func (c *internalClient) UpdateMetastore(ctx context.Context, req *UpdateMetastoreRequest, opts ...call.Option) (*MetastoreInfo, error) { + wireReq, err := updateMetastoreRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/metastores/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *MetastoreInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp metastoreInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = metastoreInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a metastore assignment. This operation can be used to update +// __metastore_id__ or __default_catalog_name__ for a specified Workspace, if +// the Workspace is already assigned a metastore. The caller must be an account +// admin to update __metastore_id__; otherwise, the caller can be a Workspace +// admin. +func (c *internalClient) UpdateMetastoreAssignment(ctx context.Context, req *UpdateMetastoreAssignmentRequest, opts ...call.Option) (*UpdateMetastoreAssignmentResponse, error) { + wireReq, err := updateMetastoreAssignmentRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/workspaces/") + pb.singleSegment(*req.WorkspaceId) + pb.literal("/metastore") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateMetastoreAssignmentResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateMetastoreAssignmentResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/metastores/v1/genhelper.go b/uc/metastores/v1/genhelper.go new file mode 100755 index 0000000..1767964 --- /dev/null +++ b/uc/metastores/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package metastores + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/metastores/v1/model.go b/uc/metastores/v1/model.go new file mode 100755 index 0000000..86183a5 --- /dev/null +++ b/uc/metastores/v1/model.go @@ -0,0 +1,552 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package metastores + +type DeltaSharingScope_Enum string + +const ( + DeltaSharingScope_Enum_Unspecified DeltaSharingScope_Enum = "" + // Internal Delta Sharing enabled on metastore. This applies to + // Databricks-managed authentication where both provider and recipient are under + // the same account. + DeltaSharingScope_Enum_Internal DeltaSharingScope_Enum = "INTERNAL" + // Internal and External Delta Sharing enabled on metastore. This allows all + // flavors of Delta Sharing. + DeltaSharingScope_Enum_InternalAndExternal DeltaSharingScope_Enum = "INTERNAL_AND_EXTERNAL" +) + +// The mapping from workspace to metastore.. +type AccountsCreateMetastoreAssignmentRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Workspace ID. + WorkspaceId *int64 + // Unity Catalog metastore ID + MetastoreId *string + MetastoreAssignment *MetastoreAssignment +} + +// The metastore assignment was successfully created.. +type AccountsCreateMetastoreAssignmentResponse struct { +} + +// Properties of the new metastore.. +type AccountsCreateMetastoreRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + MetastoreInfo *CreateAccountsMetastore +} + +type AccountsCreateMetastoreResponse struct { + MetastoreInfo *MetastoreInfo +} + +// Delete a metastore assignment to a workspace. +type AccountsDeleteMetastoreAssignmentRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Workspace ID. + WorkspaceId *int64 + // Unity Catalog metastore ID + MetastoreId *string +} + +// The metastore assignment was successfully deleted.. +type AccountsDeleteMetastoreAssignmentResponse struct { +} + +// Delete a metastore for the given account. +type AccountsDeleteMetastoreRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Unity Catalog metastore ID + MetastoreId *string + // Force deletion even if the metastore is not empty. Default is false. + Force *bool +} + +// The metastore was successfully deleted.. +type AccountsDeleteMetastoreResponse struct { +} + +// Retrieves the assignment of which metastore to a given workspace. +type AccountsGetMetastoreAssignmentRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Workspace ID. + WorkspaceId *int64 +} + +// The workspace metastore assignment was successfully returned.. +type AccountsGetMetastoreAssignmentResponse struct { + MetastoreAssignment *MetastoreAssignment +} + +// Get a metastore for a given account. +type AccountsGetMetastoreRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Unity Catalog metastore ID + MetastoreId *string +} + +// The metastore was successfully returned.. +type AccountsGetMetastoreResponse struct { + MetastoreInfo *MetastoreInfo +} + +// List the metastores for an account. +type AccountsListMetastoresRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string +} + +// Metastores were returned successfully.. +type AccountsListMetastoresResponse struct { + // An array of metastore information objects. + Metastores []MetastoreInfo +} + +// Lists all workspace IDs for a given metastore. +type AccountsListWorkspaceIdsForMetastoreRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Unity Catalog metastore ID + MetastoreId *string +} + +// The metastore assignments were successfully returned.. +type AccountsListWorkspaceIdsForMetastoreResponse struct { + WorkspaceIds []int64 +} + +// The metastore assignment to update.. +type AccountsUpdateMetastoreAssignmentRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Workspace ID. + WorkspaceId *int64 + // Unity Catalog metastore ID + MetastoreId *string + MetastoreAssignment *MetastoreAssignment +} + +// The metastore assignment was successfully updated.. +type AccountsUpdateMetastoreAssignmentResponse struct { +} + +// Properties of the metastore to change.. +type AccountsUpdateMetastoreRequest struct { + // account ID of any type. For non-E2 account types, get your + // account ID from the [Accounts Console] + // + // [Accounts Console]: https://docs.databricks.com/administration-guide/account-settings/usage.html + AccountId *string + // Unity Catalog metastore ID + MetastoreId *string + // Properties of the metastore to change. + MetastoreInfo *UpdateAccountsMetastore +} + +// The metastore update request succeeded.. +type AccountsUpdateMetastoreResponse struct { + MetastoreInfo *MetastoreInfo +} + +type CreateAccountsMetastore struct { + // The user-specified name of the metastore. + Name *string + // The storage root URL for metastore + StorageRoot *string + // Unique identifier of the metastore's (Default) Data Access Configuration. + DefaultDataAccessConfigId *string + // UUID of storage credential to access the metastore storage_root. + StorageRootCredentialId *string + // The scope of Delta Sharing enabled for the metastore. + DeltaSharingScope DeltaSharingScope_Enum + // The lifetime of delta sharing recipient token in seconds. + DeltaSharingRecipientTokenLifetimeInSeconds *int64 + // The organization name of a Delta Sharing entity, to be used in + // Databricks-to-Databricks Delta Sharing as the official name. + DeltaSharingOrganizationName *string + // The owner of the metastore. + Owner *string + // Privilege model version of the metastore, of the form `major.minor` (e.g., + // `1.0`). + PrivilegeModelVersion *string + // Cloud region which the metastore serves (e.g., `us-west-2`, `westus`). + Region *string + // Unique identifier of metastore. + MetastoreId *string + // Time at which this metastore was created, in epoch milliseconds. + CreatedAt *int64 + // Username of metastore creator. + CreatedBy *string + // Time at which the metastore was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the metastore. + UpdatedBy *string + // Name of the storage credential to access the metastore storage_root. + StorageRootCredentialName *string + // Cloud vendor of the metastore home shard (e.g., `aws`, `azure`, `gcp`). + Cloud *string + // Globally unique metastore ID across clouds and regions, of the form + // `cloud:region:metastore_id`. + GlobalMetastoreId *string + // Whether to allow non-DBR clients to directly access entities under the + // metastore. + ExternalAccessEnabled *bool +} + +type CreateMetastoreAssignmentRequest struct { + // A workspace ID. + WorkspaceId *int64 + // The unique ID of the metastore. + MetastoreId *string + // The name of the default catalog in the metastore. This field is deprecated. + // Please use "Default Namespace API" to configure the default catalog for a + // workspace. + DefaultCatalogName *string +} + +type CreateMetastoreAssignmentResponse struct { +} + +type CreateMetastoreRequest struct { + // The user-specified name of the metastore. + Name *string + // The storage root URL for metastore + StorageRoot *string + // Unique identifier of the metastore's (Default) Data Access Configuration. + DefaultDataAccessConfigId *string + // UUID of storage credential to access the metastore storage_root. + StorageRootCredentialId *string + // The scope of Delta Sharing enabled for the metastore. + DeltaSharingScope DeltaSharingScope_Enum + // The lifetime of delta sharing recipient token in seconds. + DeltaSharingRecipientTokenLifetimeInSeconds *int64 + // The organization name of a Delta Sharing entity, to be used in + // Databricks-to-Databricks Delta Sharing as the official name. + DeltaSharingOrganizationName *string + // The owner of the metastore. + Owner *string + // Privilege model version of the metastore, of the form `major.minor` (e.g., + // `1.0`). + PrivilegeModelVersion *string + // Cloud region which the metastore serves (e.g., `us-west-2`, `westus`). + Region *string + // Unique identifier of metastore. + MetastoreId *string + // Time at which this metastore was created, in epoch milliseconds. + CreatedAt *int64 + // Username of metastore creator. + CreatedBy *string + // Time at which the metastore was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the metastore. + UpdatedBy *string + // Name of the storage credential to access the metastore storage_root. + StorageRootCredentialName *string + // Cloud vendor of the metastore home shard (e.g., `aws`, `azure`, `gcp`). + Cloud *string + // Globally unique metastore ID across clouds and regions, of the form + // `cloud:region:metastore_id`. + GlobalMetastoreId *string + // Whether to allow non-DBR clients to directly access entities under the + // metastore. + ExternalAccessEnabled *bool +} + +type DeleteMetastoreAssignmentRequest struct { + // A workspace ID. + WorkspaceId *int64 + // Query for the ID of the metastore to delete. + MetastoreId *string +} + +type DeleteMetastoreAssignmentResponse struct { +} + +type DeleteMetastoreRequest struct { + // Unique ID of the metastore. + Id *string + // Force deletion even if the metastore is not empty. Default is false. + Force *bool +} + +type DeleteMetastoreResponse struct { +} + +type DeltaSharingScope struct { +} + +type GetCurrentMetastoreAssignmentRequest struct { +} + +type GetMetastoreRequest struct { + // Unique ID of the metastore. + Id *string +} + +type GetMetastoreSummaryRequest struct { +} + +type GetMetastoreSummaryResponse struct { + // Unique identifier of metastore. + MetastoreId *string + // The user-specified name of the metastore. + Name *string + // Unique identifier of the metastore's (Default) Data Access Configuration. + DefaultDataAccessConfigId *string + // UUID of storage credential to access the metastore storage_root. + StorageRootCredentialId *string + // Cloud vendor of the metastore home shard (e.g., `aws`, `azure`, `gcp`). + Cloud *string + // Cloud region which the metastore serves (e.g., `us-west-2`, `westus`). + Region *string + // Globally unique metastore ID across clouds and regions, of the form + // `cloud:region:metastore_id`. + GlobalMetastoreId *string + // Name of the storage credential to access the metastore storage_root. + StorageRootCredentialName *string + // Privilege model version of the metastore, of the form `major.minor` (e.g., + // `1.0`). + PrivilegeModelVersion *string + // The scope of Delta Sharing enabled for the metastore. + DeltaSharingScope DeltaSharingScope_Enum + // The lifetime of delta sharing recipient token in seconds. + DeltaSharingRecipientTokenLifetimeInSeconds *int64 + // The organization name of a Delta Sharing entity, to be used in + // Databricks-to-Databricks Delta Sharing as the official name. + DeltaSharingOrganizationName *string + // The storage root URL for metastore + StorageRoot *string + // The owner of the metastore. + Owner *string + // Time at which this metastore was created, in epoch milliseconds. + CreatedAt *int64 + // Username of metastore creator. + CreatedBy *string + // Time at which the metastore was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the metastore. + UpdatedBy *string + // Whether to allow non-DBR clients to directly access entities under the + // metastore. + ExternalAccessEnabled *bool +} + +type ListMetastoresRequest struct { + // Maximum number of metastores to return. - when set to a value greater than 0, + // the page length is the minimum of this value and a server configured value; - + // when set to 0, the page length is set to a server configured value + // (recommended); - when set to a value less than 0, an invalid parameter error + // is returned; - If not set, all the metastores are returned (not recommended). + // - Note: The number of returned metastores might be less than the specified + // max_results size, even zero. The only definitive indication that no further + // metastores can be fetched is when the next_page_token is unset from the + // response. + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListMetastoresResponse struct { + // An array of metastore information objects. + Metastores []MetastoreInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type MetastoreAssignment struct { + // The unique ID of the workspace. + WorkspaceId *int64 + // The unique ID of the metastore. + MetastoreId *string + // The name of the default catalog in the metastore. This field is deprecated. + // Please use "Default Namespace API" to configure the default catalog for a + // workspace. + DefaultCatalogName *string +} + +type MetastoreInfo struct { + // The user-specified name of the metastore. + Name *string + // The storage root URL for metastore + StorageRoot *string + // Unique identifier of the metastore's (Default) Data Access Configuration. + DefaultDataAccessConfigId *string + // UUID of storage credential to access the metastore storage_root. + StorageRootCredentialId *string + // The scope of Delta Sharing enabled for the metastore. + DeltaSharingScope DeltaSharingScope_Enum + // The lifetime of delta sharing recipient token in seconds. + DeltaSharingRecipientTokenLifetimeInSeconds *int64 + // The organization name of a Delta Sharing entity, to be used in + // Databricks-to-Databricks Delta Sharing as the official name. + DeltaSharingOrganizationName *string + // The owner of the metastore. + Owner *string + // Privilege model version of the metastore, of the form `major.minor` (e.g., + // `1.0`). + PrivilegeModelVersion *string + // Cloud region which the metastore serves (e.g., `us-west-2`, `westus`). + Region *string + // Unique identifier of metastore. + MetastoreId *string + // Time at which this metastore was created, in epoch milliseconds. + CreatedAt *int64 + // Username of metastore creator. + CreatedBy *string + // Time at which the metastore was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the metastore. + UpdatedBy *string + // Name of the storage credential to access the metastore storage_root. + StorageRootCredentialName *string + // Cloud vendor of the metastore home shard (e.g., `aws`, `azure`, `gcp`). + Cloud *string + // Globally unique metastore ID across clouds and regions, of the form + // `cloud:region:metastore_id`. + GlobalMetastoreId *string + // Whether to allow non-DBR clients to directly access entities under the + // metastore. + ExternalAccessEnabled *bool +} + +type UpdateAccountsMetastore struct { + // The user-specified name of the metastore. + Name *string + // The storage root URL for metastore + StorageRoot *string + // Unique identifier of the metastore's (Default) Data Access Configuration. + DefaultDataAccessConfigId *string + // UUID of storage credential to access the metastore storage_root. + StorageRootCredentialId *string + // The scope of Delta Sharing enabled for the metastore. + DeltaSharingScope DeltaSharingScope_Enum + // The lifetime of delta sharing recipient token in seconds. + DeltaSharingRecipientTokenLifetimeInSeconds *int64 + // The organization name of a Delta Sharing entity, to be used in + // Databricks-to-Databricks Delta Sharing as the official name. + DeltaSharingOrganizationName *string + // The owner of the metastore. + Owner *string + // Privilege model version of the metastore, of the form `major.minor` (e.g., + // `1.0`). + PrivilegeModelVersion *string + // Cloud region which the metastore serves (e.g., `us-west-2`, `westus`). + Region *string + // Unique identifier of metastore. + MetastoreId *string + // Time at which this metastore was created, in epoch milliseconds. + CreatedAt *int64 + // Username of metastore creator. + CreatedBy *string + // Time at which the metastore was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the metastore. + UpdatedBy *string + // Name of the storage credential to access the metastore storage_root. + StorageRootCredentialName *string + // Cloud vendor of the metastore home shard (e.g., `aws`, `azure`, `gcp`). + Cloud *string + // Globally unique metastore ID across clouds and regions, of the form + // `cloud:region:metastore_id`. + GlobalMetastoreId *string + // Whether to allow non-DBR clients to directly access entities under the + // metastore. + ExternalAccessEnabled *bool +} + +type UpdateMetastoreAssignmentRequest struct { + // A workspace ID. + WorkspaceId *int64 + // The unique ID of the metastore. + MetastoreId *string + // The name of the default catalog in the metastore. This field is deprecated. + // Please use "Default Namespace API" to configure the default catalog for a + // workspace. + DefaultCatalogName *string +} + +type UpdateMetastoreAssignmentResponse struct { +} + +type UpdateMetastoreRequest struct { + // Unique ID of the metastore. + Id *string + // New name for the metastore. + NewName *string + // The user-specified name of the metastore. + Name *string + // The storage root URL for metastore + StorageRoot *string + // Unique identifier of the metastore's (Default) Data Access Configuration. + DefaultDataAccessConfigId *string + // UUID of storage credential to access the metastore storage_root. + StorageRootCredentialId *string + // The scope of Delta Sharing enabled for the metastore. + DeltaSharingScope DeltaSharingScope_Enum + // The lifetime of delta sharing recipient token in seconds. + DeltaSharingRecipientTokenLifetimeInSeconds *int64 + // The organization name of a Delta Sharing entity, to be used in + // Databricks-to-Databricks Delta Sharing as the official name. + DeltaSharingOrganizationName *string + // The owner of the metastore. + Owner *string + // Privilege model version of the metastore, of the form `major.minor` (e.g., + // `1.0`). + PrivilegeModelVersion *string + // Cloud region which the metastore serves (e.g., `us-west-2`, `westus`). + Region *string + // Unique identifier of metastore. + MetastoreId *string + // Time at which this metastore was created, in epoch milliseconds. + CreatedAt *int64 + // Username of metastore creator. + CreatedBy *string + // Time at which the metastore was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the metastore. + UpdatedBy *string + // Name of the storage credential to access the metastore storage_root. + StorageRootCredentialName *string + // Cloud vendor of the metastore home shard (e.g., `aws`, `azure`, `gcp`). + Cloud *string + // Globally unique metastore ID across clouds and regions, of the form + // `cloud:region:metastore_id`. + GlobalMetastoreId *string + // Whether to allow non-DBR clients to directly access entities under the + // metastore. + ExternalAccessEnabled *bool +} diff --git a/uc/metastores/v1/wire.go b/uc/metastores/v1/wire.go new file mode 100755 index 0000000..2b9b807 --- /dev/null +++ b/uc/metastores/v1/wire.go @@ -0,0 +1,647 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package metastores + +import ( + "fmt" +) + +type accountsCreateMetastoreAssignmentRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + WorkspaceId *int64 `json:"workspace_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + MetastoreAssignment *metastoreAssignmentWire `json:"metastore_assignment,omitempty"` +} + +func accountsCreateMetastoreAssignmentRequestToWire(v *AccountsCreateMetastoreAssignmentRequest) (*accountsCreateMetastoreAssignmentRequestWire, error) { + if v == nil { + return nil, nil + } + metastoreAssignmentWireValue, err := metastoreAssignmentToWire(v.MetastoreAssignment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsCreateMetastoreAssignmentRequest.MetastoreAssignment", err) + } + return &accountsCreateMetastoreAssignmentRequestWire{ + AccountId: v.AccountId, + WorkspaceId: v.WorkspaceId, + MetastoreId: v.MetastoreId, + MetastoreAssignment: metastoreAssignmentWireValue, + }, nil +} + +type accountsCreateMetastoreRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + MetastoreInfo *createAccountsMetastoreWire `json:"metastore_info,omitempty"` +} + +func accountsCreateMetastoreRequestToWire(v *AccountsCreateMetastoreRequest) (*accountsCreateMetastoreRequestWire, error) { + if v == nil { + return nil, nil + } + metastoreInfoWireValue, err := createAccountsMetastoreToWire(v.MetastoreInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsCreateMetastoreRequest.MetastoreInfo", err) + } + return &accountsCreateMetastoreRequestWire{ + AccountId: v.AccountId, + MetastoreInfo: metastoreInfoWireValue, + }, nil +} + +type accountsCreateMetastoreResponseWire struct { + MetastoreInfo *metastoreInfoWire `json:"metastore_info,omitempty"` +} + +func accountsCreateMetastoreResponseFromWire(w *accountsCreateMetastoreResponseWire) (*AccountsCreateMetastoreResponse, error) { + if w == nil { + return nil, nil + } + metastoreInfoPublicValue, err := metastoreInfoFromWire(w.MetastoreInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsCreateMetastoreResponse.MetastoreInfo", err) + } + return &AccountsCreateMetastoreResponse{ + MetastoreInfo: metastoreInfoPublicValue, + }, nil +} + +type accountsDeleteMetastoreRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + Force *bool `json:"force,omitempty"` +} + +func accountsDeleteMetastoreRequestToWire(v *AccountsDeleteMetastoreRequest) (*accountsDeleteMetastoreRequestWire, error) { + if v == nil { + return nil, nil + } + return &accountsDeleteMetastoreRequestWire{ + AccountId: v.AccountId, + MetastoreId: v.MetastoreId, + Force: v.Force, + }, nil +} + +type accountsGetMetastoreAssignmentResponseWire struct { + MetastoreAssignment *metastoreAssignmentWire `json:"metastore_assignment,omitempty"` +} + +func accountsGetMetastoreAssignmentResponseFromWire(w *accountsGetMetastoreAssignmentResponseWire) (*AccountsGetMetastoreAssignmentResponse, error) { + if w == nil { + return nil, nil + } + metastoreAssignmentPublicValue, err := metastoreAssignmentFromWire(w.MetastoreAssignment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsGetMetastoreAssignmentResponse.MetastoreAssignment", err) + } + return &AccountsGetMetastoreAssignmentResponse{ + MetastoreAssignment: metastoreAssignmentPublicValue, + }, nil +} + +type accountsGetMetastoreResponseWire struct { + MetastoreInfo *metastoreInfoWire `json:"metastore_info,omitempty"` +} + +func accountsGetMetastoreResponseFromWire(w *accountsGetMetastoreResponseWire) (*AccountsGetMetastoreResponse, error) { + if w == nil { + return nil, nil + } + metastoreInfoPublicValue, err := metastoreInfoFromWire(w.MetastoreInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsGetMetastoreResponse.MetastoreInfo", err) + } + return &AccountsGetMetastoreResponse{ + MetastoreInfo: metastoreInfoPublicValue, + }, nil +} + +type accountsListMetastoresResponseWire struct { + Metastores []metastoreInfoWire `json:"metastores,omitempty"` +} + +func accountsListMetastoresResponseFromWire(w *accountsListMetastoresResponseWire) (*AccountsListMetastoresResponse, error) { + if w == nil { + return nil, nil + } + metastoresPublicValue, err := convertSlice(w.Metastores, metastoreInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsListMetastoresResponse.Metastores", err) + } + return &AccountsListMetastoresResponse{ + Metastores: metastoresPublicValue, + }, nil +} + +type accountsListWorkspaceIdsForMetastoreResponseWire struct { + WorkspaceIds []int64 `json:"workspace_ids,omitempty"` +} + +func accountsListWorkspaceIdsForMetastoreResponseFromWire(w *accountsListWorkspaceIdsForMetastoreResponseWire) (*AccountsListWorkspaceIdsForMetastoreResponse, error) { + if w == nil { + return nil, nil + } + return &AccountsListWorkspaceIdsForMetastoreResponse{ + WorkspaceIds: w.WorkspaceIds, + }, nil +} + +type accountsUpdateMetastoreAssignmentRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + WorkspaceId *int64 `json:"workspace_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + MetastoreAssignment *metastoreAssignmentWire `json:"metastore_assignment,omitempty"` +} + +func accountsUpdateMetastoreAssignmentRequestToWire(v *AccountsUpdateMetastoreAssignmentRequest) (*accountsUpdateMetastoreAssignmentRequestWire, error) { + if v == nil { + return nil, nil + } + metastoreAssignmentWireValue, err := metastoreAssignmentToWire(v.MetastoreAssignment) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsUpdateMetastoreAssignmentRequest.MetastoreAssignment", err) + } + return &accountsUpdateMetastoreAssignmentRequestWire{ + AccountId: v.AccountId, + WorkspaceId: v.WorkspaceId, + MetastoreId: v.MetastoreId, + MetastoreAssignment: metastoreAssignmentWireValue, + }, nil +} + +type accountsUpdateMetastoreRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + MetastoreInfo *updateAccountsMetastoreWire `json:"metastore_info,omitempty"` +} + +func accountsUpdateMetastoreRequestToWire(v *AccountsUpdateMetastoreRequest) (*accountsUpdateMetastoreRequestWire, error) { + if v == nil { + return nil, nil + } + metastoreInfoWireValue, err := updateAccountsMetastoreToWire(v.MetastoreInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsUpdateMetastoreRequest.MetastoreInfo", err) + } + return &accountsUpdateMetastoreRequestWire{ + AccountId: v.AccountId, + MetastoreId: v.MetastoreId, + MetastoreInfo: metastoreInfoWireValue, + }, nil +} + +type accountsUpdateMetastoreResponseWire struct { + MetastoreInfo *metastoreInfoWire `json:"metastore_info,omitempty"` +} + +func accountsUpdateMetastoreResponseFromWire(w *accountsUpdateMetastoreResponseWire) (*AccountsUpdateMetastoreResponse, error) { + if w == nil { + return nil, nil + } + metastoreInfoPublicValue, err := metastoreInfoFromWire(w.MetastoreInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccountsUpdateMetastoreResponse.MetastoreInfo", err) + } + return &AccountsUpdateMetastoreResponse{ + MetastoreInfo: metastoreInfoPublicValue, + }, nil +} + +type createAccountsMetastoreWire struct { + Name *string `json:"name,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + DefaultDataAccessConfigId *string `json:"default_data_access_config_id,omitempty"` + StorageRootCredentialId *string `json:"storage_root_credential_id,omitempty"` + DeltaSharingScope DeltaSharingScope_Enum `json:"delta_sharing_scope,omitempty"` + DeltaSharingRecipientTokenLifetimeInSeconds *int64 `json:"delta_sharing_recipient_token_lifetime_in_seconds,omitempty"` + DeltaSharingOrganizationName *string `json:"delta_sharing_organization_name,omitempty"` + Owner *string `json:"owner,omitempty"` + PrivilegeModelVersion *string `json:"privilege_model_version,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageRootCredentialName *string `json:"storage_root_credential_name,omitempty"` + Cloud *string `json:"cloud,omitempty"` + GlobalMetastoreId *string `json:"global_metastore_id,omitempty"` + ExternalAccessEnabled *bool `json:"external_access_enabled,omitempty"` +} + +func createAccountsMetastoreToWire(v *CreateAccountsMetastore) (*createAccountsMetastoreWire, error) { + if v == nil { + return nil, nil + } + return &createAccountsMetastoreWire{ + Name: v.Name, + StorageRoot: v.StorageRoot, + DefaultDataAccessConfigId: v.DefaultDataAccessConfigId, + StorageRootCredentialId: v.StorageRootCredentialId, + DeltaSharingScope: v.DeltaSharingScope, + DeltaSharingRecipientTokenLifetimeInSeconds: v.DeltaSharingRecipientTokenLifetimeInSeconds, + DeltaSharingOrganizationName: v.DeltaSharingOrganizationName, + Owner: v.Owner, + PrivilegeModelVersion: v.PrivilegeModelVersion, + Region: v.Region, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + StorageRootCredentialName: v.StorageRootCredentialName, + Cloud: v.Cloud, + GlobalMetastoreId: v.GlobalMetastoreId, + ExternalAccessEnabled: v.ExternalAccessEnabled, + }, nil +} + +type createMetastoreAssignmentRequestWire struct { + WorkspaceId *int64 `json:"workspace_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + DefaultCatalogName *string `json:"default_catalog_name,omitempty"` +} + +func createMetastoreAssignmentRequestToWire(v *CreateMetastoreAssignmentRequest) (*createMetastoreAssignmentRequestWire, error) { + if v == nil { + return nil, nil + } + return &createMetastoreAssignmentRequestWire{ + WorkspaceId: v.WorkspaceId, + MetastoreId: v.MetastoreId, + DefaultCatalogName: v.DefaultCatalogName, + }, nil +} + +type createMetastoreRequestWire struct { + Name *string `json:"name,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + DefaultDataAccessConfigId *string `json:"default_data_access_config_id,omitempty"` + StorageRootCredentialId *string `json:"storage_root_credential_id,omitempty"` + DeltaSharingScope DeltaSharingScope_Enum `json:"delta_sharing_scope,omitempty"` + DeltaSharingRecipientTokenLifetimeInSeconds *int64 `json:"delta_sharing_recipient_token_lifetime_in_seconds,omitempty"` + DeltaSharingOrganizationName *string `json:"delta_sharing_organization_name,omitempty"` + Owner *string `json:"owner,omitempty"` + PrivilegeModelVersion *string `json:"privilege_model_version,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageRootCredentialName *string `json:"storage_root_credential_name,omitempty"` + Cloud *string `json:"cloud,omitempty"` + GlobalMetastoreId *string `json:"global_metastore_id,omitempty"` + ExternalAccessEnabled *bool `json:"external_access_enabled,omitempty"` +} + +func createMetastoreRequestToWire(v *CreateMetastoreRequest) (*createMetastoreRequestWire, error) { + if v == nil { + return nil, nil + } + return &createMetastoreRequestWire{ + Name: v.Name, + StorageRoot: v.StorageRoot, + DefaultDataAccessConfigId: v.DefaultDataAccessConfigId, + StorageRootCredentialId: v.StorageRootCredentialId, + DeltaSharingScope: v.DeltaSharingScope, + DeltaSharingRecipientTokenLifetimeInSeconds: v.DeltaSharingRecipientTokenLifetimeInSeconds, + DeltaSharingOrganizationName: v.DeltaSharingOrganizationName, + Owner: v.Owner, + PrivilegeModelVersion: v.PrivilegeModelVersion, + Region: v.Region, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + StorageRootCredentialName: v.StorageRootCredentialName, + Cloud: v.Cloud, + GlobalMetastoreId: v.GlobalMetastoreId, + ExternalAccessEnabled: v.ExternalAccessEnabled, + }, nil +} + +type deleteMetastoreAssignmentRequestWire struct { + WorkspaceId *int64 `json:"workspace_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` +} + +func deleteMetastoreAssignmentRequestToWire(v *DeleteMetastoreAssignmentRequest) (*deleteMetastoreAssignmentRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteMetastoreAssignmentRequestWire{ + WorkspaceId: v.WorkspaceId, + MetastoreId: v.MetastoreId, + }, nil +} + +type deleteMetastoreRequestWire struct { + Id *string `json:"id,omitempty"` + Force *bool `json:"force,omitempty"` +} + +func deleteMetastoreRequestToWire(v *DeleteMetastoreRequest) (*deleteMetastoreRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteMetastoreRequestWire{ + Id: v.Id, + Force: v.Force, + }, nil +} + +type getMetastoreSummaryResponseWire struct { + MetastoreId *string `json:"metastore_id,omitempty"` + Name *string `json:"name,omitempty"` + DefaultDataAccessConfigId *string `json:"default_data_access_config_id,omitempty"` + StorageRootCredentialId *string `json:"storage_root_credential_id,omitempty"` + Cloud *string `json:"cloud,omitempty"` + Region *string `json:"region,omitempty"` + GlobalMetastoreId *string `json:"global_metastore_id,omitempty"` + StorageRootCredentialName *string `json:"storage_root_credential_name,omitempty"` + PrivilegeModelVersion *string `json:"privilege_model_version,omitempty"` + DeltaSharingScope DeltaSharingScope_Enum `json:"delta_sharing_scope,omitempty"` + DeltaSharingRecipientTokenLifetimeInSeconds *int64 `json:"delta_sharing_recipient_token_lifetime_in_seconds,omitempty"` + DeltaSharingOrganizationName *string `json:"delta_sharing_organization_name,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + Owner *string `json:"owner,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + ExternalAccessEnabled *bool `json:"external_access_enabled,omitempty"` +} + +func getMetastoreSummaryResponseFromWire(w *getMetastoreSummaryResponseWire) (*GetMetastoreSummaryResponse, error) { + if w == nil { + return nil, nil + } + return &GetMetastoreSummaryResponse{ + MetastoreId: w.MetastoreId, + Name: w.Name, + DefaultDataAccessConfigId: w.DefaultDataAccessConfigId, + StorageRootCredentialId: w.StorageRootCredentialId, + Cloud: w.Cloud, + Region: w.Region, + GlobalMetastoreId: w.GlobalMetastoreId, + StorageRootCredentialName: w.StorageRootCredentialName, + PrivilegeModelVersion: w.PrivilegeModelVersion, + DeltaSharingScope: w.DeltaSharingScope, + DeltaSharingRecipientTokenLifetimeInSeconds: w.DeltaSharingRecipientTokenLifetimeInSeconds, + DeltaSharingOrganizationName: w.DeltaSharingOrganizationName, + StorageRoot: w.StorageRoot, + Owner: w.Owner, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + ExternalAccessEnabled: w.ExternalAccessEnabled, + }, nil +} + +type listMetastoresRequestWire struct { + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listMetastoresRequestToWire(v *ListMetastoresRequest) (*listMetastoresRequestWire, error) { + if v == nil { + return nil, nil + } + return &listMetastoresRequestWire{ + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listMetastoresResponseWire struct { + Metastores []metastoreInfoWire `json:"metastores,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listMetastoresResponseFromWire(w *listMetastoresResponseWire) (*ListMetastoresResponse, error) { + if w == nil { + return nil, nil + } + metastoresPublicValue, err := convertSlice(w.Metastores, metastoreInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListMetastoresResponse.Metastores", err) + } + return &ListMetastoresResponse{ + Metastores: metastoresPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type metastoreAssignmentWire struct { + WorkspaceId *int64 `json:"workspace_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + DefaultCatalogName *string `json:"default_catalog_name,omitempty"` +} + +func metastoreAssignmentToWire(v *MetastoreAssignment) (*metastoreAssignmentWire, error) { + if v == nil { + return nil, nil + } + return &metastoreAssignmentWire{ + WorkspaceId: v.WorkspaceId, + MetastoreId: v.MetastoreId, + DefaultCatalogName: v.DefaultCatalogName, + }, nil +} + +func metastoreAssignmentFromWire(w *metastoreAssignmentWire) (*MetastoreAssignment, error) { + if w == nil { + return nil, nil + } + return &MetastoreAssignment{ + WorkspaceId: w.WorkspaceId, + MetastoreId: w.MetastoreId, + DefaultCatalogName: w.DefaultCatalogName, + }, nil +} + +type metastoreInfoWire struct { + Name *string `json:"name,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + DefaultDataAccessConfigId *string `json:"default_data_access_config_id,omitempty"` + StorageRootCredentialId *string `json:"storage_root_credential_id,omitempty"` + DeltaSharingScope DeltaSharingScope_Enum `json:"delta_sharing_scope,omitempty"` + DeltaSharingRecipientTokenLifetimeInSeconds *int64 `json:"delta_sharing_recipient_token_lifetime_in_seconds,omitempty"` + DeltaSharingOrganizationName *string `json:"delta_sharing_organization_name,omitempty"` + Owner *string `json:"owner,omitempty"` + PrivilegeModelVersion *string `json:"privilege_model_version,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageRootCredentialName *string `json:"storage_root_credential_name,omitempty"` + Cloud *string `json:"cloud,omitempty"` + GlobalMetastoreId *string `json:"global_metastore_id,omitempty"` + ExternalAccessEnabled *bool `json:"external_access_enabled,omitempty"` +} + +func metastoreInfoFromWire(w *metastoreInfoWire) (*MetastoreInfo, error) { + if w == nil { + return nil, nil + } + return &MetastoreInfo{ + Name: w.Name, + StorageRoot: w.StorageRoot, + DefaultDataAccessConfigId: w.DefaultDataAccessConfigId, + StorageRootCredentialId: w.StorageRootCredentialId, + DeltaSharingScope: w.DeltaSharingScope, + DeltaSharingRecipientTokenLifetimeInSeconds: w.DeltaSharingRecipientTokenLifetimeInSeconds, + DeltaSharingOrganizationName: w.DeltaSharingOrganizationName, + Owner: w.Owner, + PrivilegeModelVersion: w.PrivilegeModelVersion, + Region: w.Region, + MetastoreId: w.MetastoreId, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + StorageRootCredentialName: w.StorageRootCredentialName, + Cloud: w.Cloud, + GlobalMetastoreId: w.GlobalMetastoreId, + ExternalAccessEnabled: w.ExternalAccessEnabled, + }, nil +} + +type updateAccountsMetastoreWire struct { + Name *string `json:"name,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + DefaultDataAccessConfigId *string `json:"default_data_access_config_id,omitempty"` + StorageRootCredentialId *string `json:"storage_root_credential_id,omitempty"` + DeltaSharingScope DeltaSharingScope_Enum `json:"delta_sharing_scope,omitempty"` + DeltaSharingRecipientTokenLifetimeInSeconds *int64 `json:"delta_sharing_recipient_token_lifetime_in_seconds,omitempty"` + DeltaSharingOrganizationName *string `json:"delta_sharing_organization_name,omitempty"` + Owner *string `json:"owner,omitempty"` + PrivilegeModelVersion *string `json:"privilege_model_version,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageRootCredentialName *string `json:"storage_root_credential_name,omitempty"` + Cloud *string `json:"cloud,omitempty"` + GlobalMetastoreId *string `json:"global_metastore_id,omitempty"` + ExternalAccessEnabled *bool `json:"external_access_enabled,omitempty"` +} + +func updateAccountsMetastoreToWire(v *UpdateAccountsMetastore) (*updateAccountsMetastoreWire, error) { + if v == nil { + return nil, nil + } + return &updateAccountsMetastoreWire{ + Name: v.Name, + StorageRoot: v.StorageRoot, + DefaultDataAccessConfigId: v.DefaultDataAccessConfigId, + StorageRootCredentialId: v.StorageRootCredentialId, + DeltaSharingScope: v.DeltaSharingScope, + DeltaSharingRecipientTokenLifetimeInSeconds: v.DeltaSharingRecipientTokenLifetimeInSeconds, + DeltaSharingOrganizationName: v.DeltaSharingOrganizationName, + Owner: v.Owner, + PrivilegeModelVersion: v.PrivilegeModelVersion, + Region: v.Region, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + StorageRootCredentialName: v.StorageRootCredentialName, + Cloud: v.Cloud, + GlobalMetastoreId: v.GlobalMetastoreId, + ExternalAccessEnabled: v.ExternalAccessEnabled, + }, nil +} + +type updateMetastoreAssignmentRequestWire struct { + WorkspaceId *int64 `json:"workspace_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + DefaultCatalogName *string `json:"default_catalog_name,omitempty"` +} + +func updateMetastoreAssignmentRequestToWire(v *UpdateMetastoreAssignmentRequest) (*updateMetastoreAssignmentRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateMetastoreAssignmentRequestWire{ + WorkspaceId: v.WorkspaceId, + MetastoreId: v.MetastoreId, + DefaultCatalogName: v.DefaultCatalogName, + }, nil +} + +type updateMetastoreRequestWire struct { + Id *string `json:"id,omitempty"` + NewName *string `json:"new_name,omitempty"` + Name *string `json:"name,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + DefaultDataAccessConfigId *string `json:"default_data_access_config_id,omitempty"` + StorageRootCredentialId *string `json:"storage_root_credential_id,omitempty"` + DeltaSharingScope DeltaSharingScope_Enum `json:"delta_sharing_scope,omitempty"` + DeltaSharingRecipientTokenLifetimeInSeconds *int64 `json:"delta_sharing_recipient_token_lifetime_in_seconds,omitempty"` + DeltaSharingOrganizationName *string `json:"delta_sharing_organization_name,omitempty"` + Owner *string `json:"owner,omitempty"` + PrivilegeModelVersion *string `json:"privilege_model_version,omitempty"` + Region *string `json:"region,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + StorageRootCredentialName *string `json:"storage_root_credential_name,omitempty"` + Cloud *string `json:"cloud,omitempty"` + GlobalMetastoreId *string `json:"global_metastore_id,omitempty"` + ExternalAccessEnabled *bool `json:"external_access_enabled,omitempty"` +} + +func updateMetastoreRequestToWire(v *UpdateMetastoreRequest) (*updateMetastoreRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateMetastoreRequestWire{ + Id: v.Id, + NewName: v.NewName, + Name: v.Name, + StorageRoot: v.StorageRoot, + DefaultDataAccessConfigId: v.DefaultDataAccessConfigId, + StorageRootCredentialId: v.StorageRootCredentialId, + DeltaSharingScope: v.DeltaSharingScope, + DeltaSharingRecipientTokenLifetimeInSeconds: v.DeltaSharingRecipientTokenLifetimeInSeconds, + DeltaSharingOrganizationName: v.DeltaSharingOrganizationName, + Owner: v.Owner, + PrivilegeModelVersion: v.PrivilegeModelVersion, + Region: v.Region, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + StorageRootCredentialName: v.StorageRootCredentialName, + Cloud: v.Cloud, + GlobalMetastoreId: v.GlobalMetastoreId, + ExternalAccessEnabled: v.ExternalAccessEnabled, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/onlinetables/.package.json b/uc/onlinetables/.package.json new file mode 100644 index 0000000..4905cf1 --- /dev/null +++ b/uc/onlinetables/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/onlinetables" +} diff --git a/uc/onlinetables/CHANGELOG.md b/uc/onlinetables/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/onlinetables/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/onlinetables/README.md b/uc/onlinetables/README.md new file mode 100644 index 0000000..ec17320 --- /dev/null +++ b/uc/onlinetables/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/onlinetables + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/onlinetables@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/onlinetables/v1" + +client, err := onlinetables.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/onlinetables/go.mod b/uc/onlinetables/go.mod new file mode 100644 index 0000000..2e436ff --- /dev/null +++ b/uc/onlinetables/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/onlinetables + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/onlinetables/internal/version.go b/uc/onlinetables/internal/version.go new file mode 100644 index 0000000..90c0e69 --- /dev/null +++ b/uc/onlinetables/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-onlinetables" + +const Version = "0.0.1-dev.1" diff --git a/uc/onlinetables/v1/client.go b/uc/onlinetables/v1/client.go new file mode 100755 index 0000000..ec11ab6 --- /dev/null +++ b/uc/onlinetables/v1/client.go @@ -0,0 +1,333 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package onlinetables + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" + "github.com/databricks/sdk-go/uc/onlinetables/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a new Online Table. +func (c *internalClient) createOnlineTableBase(ctx context.Context, req *CreateOnlineTableRequest, opts ...call.Option) (*OnlineTable, error) { + wireReq, err := createOnlineTableRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Table) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/online-tables" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *OnlineTable + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp onlineTableWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = onlineTableFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a new Online Table. +func (c *internalClient) CreateOnlineTable(ctx context.Context, req *CreateOnlineTableRequest, opts ...call.Option) (*CreateOnlineTableWaiter, error) { + resp, err := c.createOnlineTableBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.Name == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "Name") + } + return &CreateOnlineTableWaiter{ + poll: c.GetOnlineTable, + name: *resp.Name, + }, nil +} + +// CreateOnlineTableWaiter tracks the state of the operation started by CreateOnlineTable. +type CreateOnlineTableWaiter struct { + poll func(context.Context, *GetOnlineTableRequest, ...call.Option) (*OnlineTable, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateOnlineTableWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetOnlineTableRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.UnityCatalogProvisioningState + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case ProvisioningInfo_State_Active, ProvisioningInfo_State_Failed: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateOnlineTableWaiter) Wait(ctx context.Context, opts ...lro.Option) (*OnlineTable, error) { + var result *OnlineTable + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetOnlineTableRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.UnityCatalogProvisioningState + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case ProvisioningInfo_State_Active: + result = pollResp + return nil + case ProvisioningInfo_State_Failed: + message := "(no message)" + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Delete an online table. Warning: This will delete all the data in the online +// table. If the source Delta table was deleted or modified since this Online +// Table was created, this will lose the data forever! +func (c *internalClient) DeleteOnlineTable(ctx context.Context, req *DeleteOnlineTableRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.0/online-tables/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Get information about an existing online table and its status. +func (c *internalClient) GetOnlineTable(ctx context.Context, req *GetOnlineTableRequest, opts ...call.Option) (*OnlineTable, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/online-tables/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *OnlineTable + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp onlineTableWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = onlineTableFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/onlinetables/v1/genhelper.go b/uc/onlinetables/v1/genhelper.go new file mode 100755 index 0000000..7437b9d --- /dev/null +++ b/uc/onlinetables/v1/genhelper.go @@ -0,0 +1,209 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package onlinetables + +import ( + "context" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/onlinetables/v1/model.go b/uc/onlinetables/v1/model.go new file mode 100755 index 0000000..37e52d8 --- /dev/null +++ b/uc/onlinetables/v1/model.go @@ -0,0 +1,255 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package onlinetables + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// The state of an online table. +type OnlineTableState string + +const ( + OnlineTableState_Unspecified OnlineTableState = "" + // The online table has just been created and resources are being provisioned. + // This is also the catch-all state if there is not a more suitable state to + // report for the online table. + OnlineTableState_Provisioning OnlineTableState = "PROVISIONING" + // The online table is provisioning resources for the data synchronization + // pipeline. + OnlineTableState_ProvisioningPipelineResources OnlineTableState = "PROVISIONING_PIPELINE_RESOURCES" + // The online table is executing the initial data synchronization. + OnlineTableState_ProvisioningInitialSnapshot OnlineTableState = "PROVISIONING_INITIAL_SNAPSHOT" + // The online table is ready to serve data. + OnlineTableState_Online OnlineTableState = "ONLINE" + // The online table is ready to serve data and is continuously updating. Only + // shown for online tables using the "Continuous" sync mode. + OnlineTableState_OnlineContinuousUpdate OnlineTableState = "ONLINE_CONTINUOUS_UPDATE" + // The online table is ready to serve data and an active update is in progress. + // Only shown for online tables using the "Triggered" sync mode. + OnlineTableState_OnlineTriggeredUpdate OnlineTableState = "ONLINE_TRIGGERED_UPDATE" + // The online table is ready to serve data and there are no active updates. Only + // shown for online tables using the "Triggered" sync mode. + OnlineTableState_OnlineNoPendingUpdate OnlineTableState = "ONLINE_NO_PENDING_UPDATE" + // The online table has encountered an internal error and is not available for + // serving. + OnlineTableState_Offline OnlineTableState = "OFFLINE" + // The online table is not available for serving because the data + // synchronization pipeline has failed. Please review the pipeline event logs to + // troubleshoot. + OnlineTableState_OfflineFailed OnlineTableState = "OFFLINE_FAILED" + // The data synchronization pipeline has encountered an error but the online + // table is still available for serving (potentially stale) data. Please review + // the pipeline event logs to troubleshoot. + OnlineTableState_OnlinePipelineFailed OnlineTableState = "ONLINE_PIPELINE_FAILED" + // The online table is available for serving, and is provisioning resources for + // a newly started data synchronization pipeline. + OnlineTableState_OnlineUpdatingPipelineResources OnlineTableState = "ONLINE_UPDATING_PIPELINE_RESOURCES" +) + +type ProvisioningInfo_State string + +const ( + ProvisioningInfo_State_Unspecified ProvisioningInfo_State = "" + ProvisioningInfo_State_Provisioning ProvisioningInfo_State = "PROVISIONING" + ProvisioningInfo_State_Active ProvisioningInfo_State = "ACTIVE" + ProvisioningInfo_State_Failed ProvisioningInfo_State = "FAILED" + ProvisioningInfo_State_Deleting ProvisioningInfo_State = "DELETING" + ProvisioningInfo_State_Updating ProvisioningInfo_State = "UPDATING" + ProvisioningInfo_State_Degraded ProvisioningInfo_State = "DEGRADED" +) + +// Detailed status of an online table. Shown if the online table is in the +// ONLINE_CONTINUOUS_UPDATE or the ONLINE_UPDATING_PIPELINE_RESOURCES state.. +type ContinuousUpdateStatus struct { + // The last source table Delta version that was synced to the online table. Note + // that this Delta version may not be completely synced to the online table yet. + LastProcessedCommitVersion *int64 + // The timestamp of the last time any data was synchronized from the source + // table to the online table. + Timestamp *types.Time + // Progress of the initial data synchronization. + InitialPipelineSyncProgress *PipelineProgress +} + +// Create an online table. +type CreateOnlineTableRequest struct { + // Specification of the online table to be created. + Table *OnlineTable +} + +// Delete an online table.. +type DeleteOnlineTableRequest struct { + // Full three-part (catalog, schema, table) name of the table. + Name *string +} + +// Detailed status of an online table. Shown if the online table is in the +// OFFLINE_FAILED or the ONLINE_PIPELINE_FAILED state.. +type FailedStatus struct { + // The last source table Delta version that was synced to the online table. Note + // that this Delta version may only be partially synced to the online table. + // Only populated if the table is still online and available for serving. + LastProcessedCommitVersion *int64 + // The timestamp of the last time any data was synchronized from the source + // table to the online table. Only populated if the table is still online and + // available for serving. + Timestamp *types.Time +} + +// Get information about an online table.. +type GetOnlineTableRequest struct { + // Full three-part (catalog, schema, table) name of the table. + Name *string +} + +// Online Table information.. +type OnlineTable struct { + // Full three-part (catalog, schema, table) name of the table. + Name *string + // Specification of the online table. + Spec *OnlineTableSpec + // Online Table data synchronization status + Status *OnlineTableStatus + // Data serving REST API URL for this table + TableServingUrl *string + // The provisioning state of the online table entity in Unity Catalog. This is + // distinct from the state of the data synchronization pipeline (i.e. the table + // may be in "ACTIVE" but the pipeline may be in "PROVISIONING" as it runs + // asynchronously). + UnityCatalogProvisioningState ProvisioningInfo_State +} + +// Specification of an online table.. +type OnlineTableSpec struct { + // Exactly one type of scheduling policy should be applied. + SchedulingPolicy isOnlineTableSpec_SchedulingPolicy + // Three-part (catalog, schema, table) name of the source Delta table. + SourceTableFullName *string + // Primary Key columns to be used for data insert/update in the destination. + PrimaryKeyColumns []string + // Time series key to deduplicate (tie-break) rows with the same primary key. + TimeseriesKey *string + // Whether to create a full-copy pipeline -- a pipeline that stops after creates + // a full copy of the source table upon initialization and does not process any + // change data feeds (CDFs) afterwards. The pipeline can still be manually + // triggered afterwards, but it always perform a full copy of the source table + // and there are no incremental updates. This mode is useful for syncing views + // or tables without CDFs to online tables. Note that the full-copy pipeline + // only supports "triggered" scheduling policy. + PerformFullCopy *bool + // ID of the associated pipeline. Generated by the server - cannot be set by the + // caller. + PipelineId *string +} + +type isOnlineTableSpec_SchedulingPolicy interface { + isOnlineTableSpec_SchedulingPolicy() +} + +// OnlineTableSpec_SchedulingPolicy_RunContinuously selects RunContinuously for OnlineTableSpec.SchedulingPolicy. +// Pipeline runs continuously after generating the initial data. +type OnlineTableSpec_SchedulingPolicy_RunContinuously struct { + RunContinuously OnlineTableSpec_ContinuousSchedulingPolicy +} + +func (*OnlineTableSpec_SchedulingPolicy_RunContinuously) isOnlineTableSpec_SchedulingPolicy() {} + +// OnlineTableSpec_SchedulingPolicy_RunTriggered selects RunTriggered for OnlineTableSpec.SchedulingPolicy. +// Pipeline stops after generating the initial data and can be triggered later +// (manually, through a cron job or through data triggers) +type OnlineTableSpec_SchedulingPolicy_RunTriggered struct { + RunTriggered OnlineTableSpec_TriggeredSchedulingPolicy +} + +func (*OnlineTableSpec_SchedulingPolicy_RunTriggered) isOnlineTableSpec_SchedulingPolicy() {} + +type OnlineTableSpec_ContinuousSchedulingPolicy struct { +} + +type OnlineTableSpec_TriggeredSchedulingPolicy struct { +} + +// Status of an online table.. +type OnlineTableStatus struct { + // The state of the online table. + DetailedState OnlineTableState + // A text description of the current state of the online table. + Message *string + // The detailed status based on the online table state. + DetailedStatus isOnlineTableStatus_DetailedStatus +} + +type isOnlineTableStatus_DetailedStatus interface { + isOnlineTableStatus_DetailedStatus() +} + +// OnlineTableStatus_DetailedStatus_ProvisioningStatus selects ProvisioningStatus for OnlineTableStatus.DetailedStatus. +type OnlineTableStatus_DetailedStatus_ProvisioningStatus struct { + ProvisioningStatus ProvisioningStatus +} + +func (*OnlineTableStatus_DetailedStatus_ProvisioningStatus) isOnlineTableStatus_DetailedStatus() {} + +// OnlineTableStatus_DetailedStatus_ContinuousUpdateStatus selects ContinuousUpdateStatus for OnlineTableStatus.DetailedStatus. +type OnlineTableStatus_DetailedStatus_ContinuousUpdateStatus struct { + ContinuousUpdateStatus ContinuousUpdateStatus +} + +func (*OnlineTableStatus_DetailedStatus_ContinuousUpdateStatus) isOnlineTableStatus_DetailedStatus() { +} + +// OnlineTableStatus_DetailedStatus_TriggeredUpdateStatus selects TriggeredUpdateStatus for OnlineTableStatus.DetailedStatus. +type OnlineTableStatus_DetailedStatus_TriggeredUpdateStatus struct { + TriggeredUpdateStatus TriggeredUpdateStatus +} + +func (*OnlineTableStatus_DetailedStatus_TriggeredUpdateStatus) isOnlineTableStatus_DetailedStatus() {} + +// OnlineTableStatus_DetailedStatus_FailedStatus selects FailedStatus for OnlineTableStatus.DetailedStatus. +type OnlineTableStatus_DetailedStatus_FailedStatus struct { + FailedStatus FailedStatus +} + +func (*OnlineTableStatus_DetailedStatus_FailedStatus) isOnlineTableStatus_DetailedStatus() {} + +// Progress information of the Online Table data synchronization pipeline.. +type PipelineProgress struct { + // The source table Delta version that was last processed by the pipeline. The + // pipeline may not have completely processed this version yet. + LatestVersionCurrentlyProcessing *int64 + // The number of rows that have been synced in this update. + SyncedRowCount *int64 + // The total number of rows that need to be synced in this update. This number + // may be an estimate. + TotalRowCount *int64 + // The completion ratio of this update. This is a number between 0 and 1. + SyncProgressCompletion *float64 + // The estimated time remaining to complete this update in seconds. + EstimatedCompletionTimeSeconds *float64 +} + +// Status of an asynchronously provisioned resource.. +type ProvisioningInfo struct { +} + +// Detailed status of an online table. Shown if the online table is in the +// PROVISIONING_PIPELINE_RESOURCES or the PROVISIONING_INITIAL_SNAPSHOT state.. +type ProvisioningStatus struct { + // Details about initial data synchronization. Only populated when in the + // PROVISIONING_INITIAL_SNAPSHOT state. + InitialPipelineSyncProgress *PipelineProgress +} + +// Detailed status of an online table. Shown if the online table is in the +// ONLINE_TRIGGERED_UPDATE or the ONLINE_NO_PENDING_UPDATE state.. +type TriggeredUpdateStatus struct { + // The last source table Delta version that was synced to the online table. Note + // that this Delta version may not be completely synced to the online table yet. + LastProcessedCommitVersion *int64 + // The timestamp of the last time any data was synchronized from the source + // table to the online table. + Timestamp *types.Time + // Progress of the active data synchronization pipeline. + TriggeredUpdateProgress *PipelineProgress +} diff --git a/uc/onlinetables/v1/wire.go b/uc/onlinetables/v1/wire.go new file mode 100755 index 0000000..19b11fb --- /dev/null +++ b/uc/onlinetables/v1/wire.go @@ -0,0 +1,476 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package onlinetables + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +type continuousUpdateStatusWire struct { + LastProcessedCommitVersion *int64 `json:"last_processed_commit_version,omitempty"` + Timestamp *types.Time `json:"timestamp,omitempty"` + InitialPipelineSyncProgress *pipelineProgressWire `json:"initial_pipeline_sync_progress,omitempty"` +} + +func continuousUpdateStatusToWire(v *ContinuousUpdateStatus) (*continuousUpdateStatusWire, error) { + if v == nil { + return nil, nil + } + initialPipelineSyncProgressWireValue, err := pipelineProgressToWire(v.InitialPipelineSyncProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ContinuousUpdateStatus.InitialPipelineSyncProgress", err) + } + return &continuousUpdateStatusWire{ + LastProcessedCommitVersion: v.LastProcessedCommitVersion, + Timestamp: v.Timestamp, + InitialPipelineSyncProgress: initialPipelineSyncProgressWireValue, + }, nil +} + +func continuousUpdateStatusFromWire(w *continuousUpdateStatusWire) (*ContinuousUpdateStatus, error) { + if w == nil { + return nil, nil + } + initialPipelineSyncProgressPublicValue, err := pipelineProgressFromWire(w.InitialPipelineSyncProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ContinuousUpdateStatus.InitialPipelineSyncProgress", err) + } + return &ContinuousUpdateStatus{ + LastProcessedCommitVersion: w.LastProcessedCommitVersion, + Timestamp: w.Timestamp, + InitialPipelineSyncProgress: initialPipelineSyncProgressPublicValue, + }, nil +} + +type createOnlineTableRequestWire struct { + Table *onlineTableWire `json:"table,omitempty"` +} + +func createOnlineTableRequestToWire(v *CreateOnlineTableRequest) (*createOnlineTableRequestWire, error) { + if v == nil { + return nil, nil + } + tableWireValue, err := onlineTableToWire(v.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateOnlineTableRequest.Table", err) + } + return &createOnlineTableRequestWire{ + Table: tableWireValue, + }, nil +} + +type failedStatusWire struct { + LastProcessedCommitVersion *int64 `json:"last_processed_commit_version,omitempty"` + Timestamp *types.Time `json:"timestamp,omitempty"` +} + +func failedStatusToWire(v *FailedStatus) (*failedStatusWire, error) { + if v == nil { + return nil, nil + } + return &failedStatusWire{ + LastProcessedCommitVersion: v.LastProcessedCommitVersion, + Timestamp: v.Timestamp, + }, nil +} + +func failedStatusFromWire(w *failedStatusWire) (*FailedStatus, error) { + if w == nil { + return nil, nil + } + return &FailedStatus{ + LastProcessedCommitVersion: w.LastProcessedCommitVersion, + Timestamp: w.Timestamp, + }, nil +} + +type onlineTableWire struct { + Name *string `json:"name,omitempty"` + Spec *onlineTableSpecWire `json:"spec,omitempty"` + Status *onlineTableStatusWire `json:"status,omitempty"` + TableServingUrl *string `json:"table_serving_url,omitempty"` + UnityCatalogProvisioningState ProvisioningInfo_State `json:"unity_catalog_provisioning_state,omitempty"` +} + +func onlineTableToWire(v *OnlineTable) (*onlineTableWire, error) { + if v == nil { + return nil, nil + } + specWireValue, err := onlineTableSpecToWire(v.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTable.Spec", err) + } + statusWireValue, err := onlineTableStatusToWire(v.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTable.Status", err) + } + return &onlineTableWire{ + Name: v.Name, + Spec: specWireValue, + Status: statusWireValue, + TableServingUrl: v.TableServingUrl, + UnityCatalogProvisioningState: v.UnityCatalogProvisioningState, + }, nil +} + +func onlineTableFromWire(w *onlineTableWire) (*OnlineTable, error) { + if w == nil { + return nil, nil + } + specPublicValue, err := onlineTableSpecFromWire(w.Spec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTable.Spec", err) + } + statusPublicValue, err := onlineTableStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTable.Status", err) + } + return &OnlineTable{ + Name: w.Name, + Spec: specPublicValue, + Status: statusPublicValue, + TableServingUrl: w.TableServingUrl, + UnityCatalogProvisioningState: w.UnityCatalogProvisioningState, + }, nil +} + +type onlineTableSpecWire struct { + RunContinuously *onlineTableSpec_ContinuousSchedulingPolicyWire `json:"run_continuously,omitempty"` + RunTriggered *onlineTableSpec_TriggeredSchedulingPolicyWire `json:"run_triggered,omitempty"` + SourceTableFullName *string `json:"source_table_full_name,omitempty"` + PrimaryKeyColumns []string `json:"primary_key_columns,omitempty"` + TimeseriesKey *string `json:"timeseries_key,omitempty"` + PerformFullCopy *bool `json:"perform_full_copy,omitempty"` + PipelineId *string `json:"pipeline_id,omitempty"` +} + +func onlineTableSpecToWire(v *OnlineTableSpec) (*onlineTableSpecWire, error) { + if v == nil { + return nil, nil + } + var schedulingPolicyRunContinuouslyWire *onlineTableSpec_ContinuousSchedulingPolicyWire + var schedulingPolicyRunTriggeredWire *onlineTableSpec_TriggeredSchedulingPolicyWire + switch value := v.SchedulingPolicy.(type) { + case nil: + case *OnlineTableSpec_SchedulingPolicy_RunContinuously: + if value != nil { + schedulingPolicyRunContinuouslyConverted, err := onlineTableSpec_ContinuousSchedulingPolicyToWire(&value.RunContinuously) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableSpec.SchedulingPolicy.RunContinuously", err) + } + schedulingPolicyRunContinuouslyWire = schedulingPolicyRunContinuouslyConverted + } + case *OnlineTableSpec_SchedulingPolicy_RunTriggered: + if value != nil { + schedulingPolicyRunTriggeredConverted, err := onlineTableSpec_TriggeredSchedulingPolicyToWire(&value.RunTriggered) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableSpec.SchedulingPolicy.RunTriggered", err) + } + schedulingPolicyRunTriggeredWire = schedulingPolicyRunTriggeredConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "OnlineTableSpec.SchedulingPolicy", value) + } + return &onlineTableSpecWire{ + RunContinuously: schedulingPolicyRunContinuouslyWire, + RunTriggered: schedulingPolicyRunTriggeredWire, + SourceTableFullName: v.SourceTableFullName, + PrimaryKeyColumns: v.PrimaryKeyColumns, + TimeseriesKey: v.TimeseriesKey, + PerformFullCopy: v.PerformFullCopy, + PipelineId: v.PipelineId, + }, nil +} + +func onlineTableSpecFromWire(w *onlineTableSpecWire) (*OnlineTableSpec, error) { + if w == nil { + return nil, nil + } + schedulingPolicyMembers := 0 + if w.RunContinuously != nil { + schedulingPolicyMembers++ + } + if w.RunTriggered != nil { + schedulingPolicyMembers++ + } + if schedulingPolicyMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "OnlineTableSpec.SchedulingPolicy") + } + var schedulingPolicySelection isOnlineTableSpec_SchedulingPolicy + switch { + case w.RunContinuously != nil: + schedulingPolicyRunContinuouslyConverted, err := onlineTableSpec_ContinuousSchedulingPolicyFromWire(w.RunContinuously) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableSpec.SchedulingPolicy.RunContinuously", err) + } + schedulingPolicySelection = &OnlineTableSpec_SchedulingPolicy_RunContinuously{RunContinuously: *schedulingPolicyRunContinuouslyConverted} + case w.RunTriggered != nil: + schedulingPolicyRunTriggeredConverted, err := onlineTableSpec_TriggeredSchedulingPolicyFromWire(w.RunTriggered) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableSpec.SchedulingPolicy.RunTriggered", err) + } + schedulingPolicySelection = &OnlineTableSpec_SchedulingPolicy_RunTriggered{RunTriggered: *schedulingPolicyRunTriggeredConverted} + } + return &OnlineTableSpec{ + SourceTableFullName: w.SourceTableFullName, + PrimaryKeyColumns: w.PrimaryKeyColumns, + TimeseriesKey: w.TimeseriesKey, + PerformFullCopy: w.PerformFullCopy, + PipelineId: w.PipelineId, + SchedulingPolicy: schedulingPolicySelection, + }, nil +} + +type onlineTableSpec_ContinuousSchedulingPolicyWire struct { +} + +func onlineTableSpec_ContinuousSchedulingPolicyToWire(v *OnlineTableSpec_ContinuousSchedulingPolicy) (*onlineTableSpec_ContinuousSchedulingPolicyWire, error) { + if v == nil { + return nil, nil + } + return &onlineTableSpec_ContinuousSchedulingPolicyWire{}, nil +} + +func onlineTableSpec_ContinuousSchedulingPolicyFromWire(w *onlineTableSpec_ContinuousSchedulingPolicyWire) (*OnlineTableSpec_ContinuousSchedulingPolicy, error) { + if w == nil { + return nil, nil + } + return &OnlineTableSpec_ContinuousSchedulingPolicy{}, nil +} + +type onlineTableSpec_TriggeredSchedulingPolicyWire struct { +} + +func onlineTableSpec_TriggeredSchedulingPolicyToWire(v *OnlineTableSpec_TriggeredSchedulingPolicy) (*onlineTableSpec_TriggeredSchedulingPolicyWire, error) { + if v == nil { + return nil, nil + } + return &onlineTableSpec_TriggeredSchedulingPolicyWire{}, nil +} + +func onlineTableSpec_TriggeredSchedulingPolicyFromWire(w *onlineTableSpec_TriggeredSchedulingPolicyWire) (*OnlineTableSpec_TriggeredSchedulingPolicy, error) { + if w == nil { + return nil, nil + } + return &OnlineTableSpec_TriggeredSchedulingPolicy{}, nil +} + +type onlineTableStatusWire struct { + DetailedState OnlineTableState `json:"detailed_state,omitempty"` + Message *string `json:"message,omitempty"` + ProvisioningStatus *provisioningStatusWire `json:"provisioning_status,omitempty"` + ContinuousUpdateStatus *continuousUpdateStatusWire `json:"continuous_update_status,omitempty"` + TriggeredUpdateStatus *triggeredUpdateStatusWire `json:"triggered_update_status,omitempty"` + FailedStatus *failedStatusWire `json:"failed_status,omitempty"` +} + +func onlineTableStatusToWire(v *OnlineTableStatus) (*onlineTableStatusWire, error) { + if v == nil { + return nil, nil + } + var detailedStatusProvisioningStatusWire *provisioningStatusWire + var detailedStatusContinuousUpdateStatusWire *continuousUpdateStatusWire + var detailedStatusTriggeredUpdateStatusWire *triggeredUpdateStatusWire + var detailedStatusFailedStatusWire *failedStatusWire + switch value := v.DetailedStatus.(type) { + case nil: + case *OnlineTableStatus_DetailedStatus_ProvisioningStatus: + if value != nil { + detailedStatusProvisioningStatusConverted, err := provisioningStatusToWire(&value.ProvisioningStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableStatus.DetailedStatus.ProvisioningStatus", err) + } + detailedStatusProvisioningStatusWire = detailedStatusProvisioningStatusConverted + } + case *OnlineTableStatus_DetailedStatus_ContinuousUpdateStatus: + if value != nil { + detailedStatusContinuousUpdateStatusConverted, err := continuousUpdateStatusToWire(&value.ContinuousUpdateStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableStatus.DetailedStatus.ContinuousUpdateStatus", err) + } + detailedStatusContinuousUpdateStatusWire = detailedStatusContinuousUpdateStatusConverted + } + case *OnlineTableStatus_DetailedStatus_TriggeredUpdateStatus: + if value != nil { + detailedStatusTriggeredUpdateStatusConverted, err := triggeredUpdateStatusToWire(&value.TriggeredUpdateStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableStatus.DetailedStatus.TriggeredUpdateStatus", err) + } + detailedStatusTriggeredUpdateStatusWire = detailedStatusTriggeredUpdateStatusConverted + } + case *OnlineTableStatus_DetailedStatus_FailedStatus: + if value != nil { + detailedStatusFailedStatusConverted, err := failedStatusToWire(&value.FailedStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableStatus.DetailedStatus.FailedStatus", err) + } + detailedStatusFailedStatusWire = detailedStatusFailedStatusConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "OnlineTableStatus.DetailedStatus", value) + } + return &onlineTableStatusWire{ + DetailedState: v.DetailedState, + Message: v.Message, + ProvisioningStatus: detailedStatusProvisioningStatusWire, + ContinuousUpdateStatus: detailedStatusContinuousUpdateStatusWire, + TriggeredUpdateStatus: detailedStatusTriggeredUpdateStatusWire, + FailedStatus: detailedStatusFailedStatusWire, + }, nil +} + +func onlineTableStatusFromWire(w *onlineTableStatusWire) (*OnlineTableStatus, error) { + if w == nil { + return nil, nil + } + detailedStatusMembers := 0 + if w.ProvisioningStatus != nil { + detailedStatusMembers++ + } + if w.ContinuousUpdateStatus != nil { + detailedStatusMembers++ + } + if w.TriggeredUpdateStatus != nil { + detailedStatusMembers++ + } + if w.FailedStatus != nil { + detailedStatusMembers++ + } + if detailedStatusMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "OnlineTableStatus.DetailedStatus") + } + var detailedStatusSelection isOnlineTableStatus_DetailedStatus + switch { + case w.ProvisioningStatus != nil: + detailedStatusProvisioningStatusConverted, err := provisioningStatusFromWire(w.ProvisioningStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableStatus.DetailedStatus.ProvisioningStatus", err) + } + detailedStatusSelection = &OnlineTableStatus_DetailedStatus_ProvisioningStatus{ProvisioningStatus: *detailedStatusProvisioningStatusConverted} + case w.ContinuousUpdateStatus != nil: + detailedStatusContinuousUpdateStatusConverted, err := continuousUpdateStatusFromWire(w.ContinuousUpdateStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableStatus.DetailedStatus.ContinuousUpdateStatus", err) + } + detailedStatusSelection = &OnlineTableStatus_DetailedStatus_ContinuousUpdateStatus{ContinuousUpdateStatus: *detailedStatusContinuousUpdateStatusConverted} + case w.TriggeredUpdateStatus != nil: + detailedStatusTriggeredUpdateStatusConverted, err := triggeredUpdateStatusFromWire(w.TriggeredUpdateStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableStatus.DetailedStatus.TriggeredUpdateStatus", err) + } + detailedStatusSelection = &OnlineTableStatus_DetailedStatus_TriggeredUpdateStatus{TriggeredUpdateStatus: *detailedStatusTriggeredUpdateStatusConverted} + case w.FailedStatus != nil: + detailedStatusFailedStatusConverted, err := failedStatusFromWire(w.FailedStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "OnlineTableStatus.DetailedStatus.FailedStatus", err) + } + detailedStatusSelection = &OnlineTableStatus_DetailedStatus_FailedStatus{FailedStatus: *detailedStatusFailedStatusConverted} + } + return &OnlineTableStatus{ + DetailedState: w.DetailedState, + Message: w.Message, + DetailedStatus: detailedStatusSelection, + }, nil +} + +type pipelineProgressWire struct { + LatestVersionCurrentlyProcessing *int64 `json:"latest_version_currently_processing,omitempty"` + SyncedRowCount *int64 `json:"synced_row_count,omitempty"` + TotalRowCount *int64 `json:"total_row_count,omitempty"` + SyncProgressCompletion *float64 `json:"sync_progress_completion,omitempty"` + EstimatedCompletionTimeSeconds *float64 `json:"estimated_completion_time_seconds,omitempty"` +} + +func pipelineProgressToWire(v *PipelineProgress) (*pipelineProgressWire, error) { + if v == nil { + return nil, nil + } + return &pipelineProgressWire{ + LatestVersionCurrentlyProcessing: v.LatestVersionCurrentlyProcessing, + SyncedRowCount: v.SyncedRowCount, + TotalRowCount: v.TotalRowCount, + SyncProgressCompletion: v.SyncProgressCompletion, + EstimatedCompletionTimeSeconds: v.EstimatedCompletionTimeSeconds, + }, nil +} + +func pipelineProgressFromWire(w *pipelineProgressWire) (*PipelineProgress, error) { + if w == nil { + return nil, nil + } + return &PipelineProgress{ + LatestVersionCurrentlyProcessing: w.LatestVersionCurrentlyProcessing, + SyncedRowCount: w.SyncedRowCount, + TotalRowCount: w.TotalRowCount, + SyncProgressCompletion: w.SyncProgressCompletion, + EstimatedCompletionTimeSeconds: w.EstimatedCompletionTimeSeconds, + }, nil +} + +type provisioningStatusWire struct { + InitialPipelineSyncProgress *pipelineProgressWire `json:"initial_pipeline_sync_progress,omitempty"` +} + +func provisioningStatusToWire(v *ProvisioningStatus) (*provisioningStatusWire, error) { + if v == nil { + return nil, nil + } + initialPipelineSyncProgressWireValue, err := pipelineProgressToWire(v.InitialPipelineSyncProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProvisioningStatus.InitialPipelineSyncProgress", err) + } + return &provisioningStatusWire{ + InitialPipelineSyncProgress: initialPipelineSyncProgressWireValue, + }, nil +} + +func provisioningStatusFromWire(w *provisioningStatusWire) (*ProvisioningStatus, error) { + if w == nil { + return nil, nil + } + initialPipelineSyncProgressPublicValue, err := pipelineProgressFromWire(w.InitialPipelineSyncProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ProvisioningStatus.InitialPipelineSyncProgress", err) + } + return &ProvisioningStatus{ + InitialPipelineSyncProgress: initialPipelineSyncProgressPublicValue, + }, nil +} + +type triggeredUpdateStatusWire struct { + LastProcessedCommitVersion *int64 `json:"last_processed_commit_version,omitempty"` + Timestamp *types.Time `json:"timestamp,omitempty"` + TriggeredUpdateProgress *pipelineProgressWire `json:"triggered_update_progress,omitempty"` +} + +func triggeredUpdateStatusToWire(v *TriggeredUpdateStatus) (*triggeredUpdateStatusWire, error) { + if v == nil { + return nil, nil + } + triggeredUpdateProgressWireValue, err := pipelineProgressToWire(v.TriggeredUpdateProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggeredUpdateStatus.TriggeredUpdateProgress", err) + } + return &triggeredUpdateStatusWire{ + LastProcessedCommitVersion: v.LastProcessedCommitVersion, + Timestamp: v.Timestamp, + TriggeredUpdateProgress: triggeredUpdateProgressWireValue, + }, nil +} + +func triggeredUpdateStatusFromWire(w *triggeredUpdateStatusWire) (*TriggeredUpdateStatus, error) { + if w == nil { + return nil, nil + } + triggeredUpdateProgressPublicValue, err := pipelineProgressFromWire(w.TriggeredUpdateProgress) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TriggeredUpdateStatus.TriggeredUpdateProgress", err) + } + return &TriggeredUpdateStatus{ + LastProcessedCommitVersion: w.LastProcessedCommitVersion, + Timestamp: w.Timestamp, + TriggeredUpdateProgress: triggeredUpdateProgressPublicValue, + }, nil +} diff --git a/uc/registeredmodels/.package.json b/uc/registeredmodels/.package.json new file mode 100644 index 0000000..0569e5a --- /dev/null +++ b/uc/registeredmodels/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/registeredmodels" +} diff --git a/uc/registeredmodels/CHANGELOG.md b/uc/registeredmodels/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/registeredmodels/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/registeredmodels/README.md b/uc/registeredmodels/README.md new file mode 100644 index 0000000..2cf21fb --- /dev/null +++ b/uc/registeredmodels/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/registeredmodels + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/registeredmodels@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/registeredmodels/v1" + +client, err := registeredmodels.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/registeredmodels/go.mod b/uc/registeredmodels/go.mod new file mode 100644 index 0000000..03bb0e9 --- /dev/null +++ b/uc/registeredmodels/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/registeredmodels + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/registeredmodels/internal/version.go b/uc/registeredmodels/internal/version.go new file mode 100644 index 0000000..9b3ca28 --- /dev/null +++ b/uc/registeredmodels/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-registeredmodels" + +const Version = "0.0.1-dev.1" diff --git a/uc/registeredmodels/v1/client.go b/uc/registeredmodels/v1/client.go new file mode 100755 index 0000000..eb71e65 --- /dev/null +++ b/uc/registeredmodels/v1/client.go @@ -0,0 +1,1063 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package registeredmodels + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/registeredmodels/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new registered model in Unity Catalog. +// +// File storage for model versions in the registered model will be located in +// the default location which is specified by the parent schema, or the parent +// catalog, or the Metastore. +// +// For registered model creation to succeed, the user must satisfy the following +// conditions: - The caller must be a metastore admin, or be the owner of the +// parent catalog and schema, or have the **USE_CATALOG** privilege on the +// parent catalog and the **USE_SCHEMA** privilege on the parent schema. - The +// caller must have the **CREATE MODEL** or **CREATE FUNCTION** privilege on the +// parent schema. +func (c *internalClient) CreateRegisteredModel(ctx context.Context, req *CreateRegisteredModelRequest, opts ...call.Option) (*RegisteredModelInfo, error) { + wireReq, err := createRegisteredModelRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/models" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RegisteredModelInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp registeredModelInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = registeredModelInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a model version from the specified registered model. Any aliases +// assigned to the model version will also be deleted. +// +// The caller must be a metastore admin or an owner of the parent registered +// model. For the latter case, the caller must also be the owner or have the +// **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** +// privilege on the parent schema. +func (c *internalClient) DeleteModelVersion(ctx context.Context, req *DeleteModelVersionRequest, opts ...call.Option) (*DeleteModelVersionResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/models/") + pb.singleSegment(*req.FullNameArg) + pb.literal("/versions/") + pb.singleSegment(*req.VersionArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteModelVersionResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteModelVersionResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a registered model and all its model versions from the specified +// parent catalog and schema. +// +// The caller must be a metastore admin or an owner of the registered model. For +// the latter case, the caller must also be the owner or have the +// **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** +// privilege on the parent schema. +func (c *internalClient) DeleteRegisteredModel(ctx context.Context, req *DeleteRegisteredModelRequest, opts ...call.Option) (*DeleteRegisteredModelResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/models/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteRegisteredModelResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteRegisteredModelResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a registered model alias. +// +// The caller must be a metastore admin or an owner of the registered model. For +// the latter case, the caller must also be the owner or have the +// **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** +// privilege on the parent schema. +func (c *internalClient) DeleteRegisteredModelAlias(ctx context.Context, req *DeleteRegisteredModelAliasRequest, opts ...call.Option) (*DeleteRegisteredModelAliasResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/models/") + pb.singleSegment(*req.FullNameArg) + pb.literal("/aliases/") + pb.singleSegment(*req.AliasArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteRegisteredModelAliasResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteRegisteredModelAliasResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a model version. +// +// The caller must be a metastore admin or an owner of (or have the **EXECUTE** +// privilege on) the parent registered model. For the latter case, the caller +// must also be the owner or have the **USE_CATALOG** privilege on the parent +// catalog and the **USE_SCHEMA** privilege on the parent schema. +func (c *internalClient) GetModelVersion(ctx context.Context, req *GetModelVersionRequest, opts ...call.Option) (*ModelVersionInfo, error) { + wireReq, err := getModelVersionRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/models/") + pb.singleSegment(*req.FullNameArg) + pb.literal("/versions/") + pb.singleSegment(*req.VersionArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_aliases", wireReq.IncludeAliases); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ModelVersionInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp modelVersionInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = modelVersionInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a model version by alias. +// +// The caller must be a metastore admin or an owner of (or have the **EXECUTE** +// privilege on) the registered model. For the latter case, the caller must also +// be the owner or have the **USE_CATALOG** privilege on the parent catalog and +// the **USE_SCHEMA** privilege on the parent schema. +func (c *internalClient) GetModelVersionByAlias(ctx context.Context, req *GetModelVersionByAliasRequest, opts ...call.Option) (*ModelVersionInfo, error) { + wireReq, err := getModelVersionByAliasRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/models/") + pb.singleSegment(*req.FullNameArg) + pb.literal("/aliases/") + pb.singleSegment(*req.AliasArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_aliases", wireReq.IncludeAliases); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ModelVersionInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp modelVersionInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = modelVersionInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a registered model. +// +// The caller must be a metastore admin or an owner of (or have the **EXECUTE** +// privilege on) the registered model. For the latter case, the caller must also +// be the owner or have the **USE_CATALOG** privilege on the parent catalog and +// the **USE_SCHEMA** privilege on the parent schema. +func (c *internalClient) GetRegisteredModel(ctx context.Context, req *GetRegisteredModelRequest, opts ...call.Option) (*RegisteredModelInfo, error) { + wireReq, err := getRegisteredModelRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/models/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_aliases", wireReq.IncludeAliases); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RegisteredModelInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp registeredModelInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = registeredModelInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List model versions. You can list model versions under a particular schema, +// or list all model versions in the current metastore. +// +// The returned models are filtered based on the privileges of the calling user. +// For example, the metastore admin is able to list all the model versions. A +// regular user needs to be the owner or have the **EXECUTE** privilege on the +// parent registered model to receive the model versions in the response. For +// the latter case, the caller must also be the owner or have the +// **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** +// privilege on the parent schema. +// +// There is no guarantee of a specific ordering of the elements in the response. +// The elements in the response will not contain any aliases or tags. +// +// PAGINATION BEHAVIOR: The API is by default paginated, a page may contain zero +// results while still providing a next_page_token. Clients must continue +// reading pages until next_page_token is absent, which is the only indication +// that the end of results has been reached. +func (c *internalClient) ListModelVersions(ctx context.Context, req *ListModelVersionsRequest, opts ...call.Option) (*ListModelVersionsResponse, error) { + wireReq, err := listModelVersionsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/models/") + pb.singleSegment(*req.FullNameArg) + pb.literal("/versions") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListModelVersionsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listModelVersionsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listModelVersionsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListModelVersionsIter returns an iterator that iterates +// over the results of ListModelVersions. +// +// For example: +// +// for item, err := range c.ListModelVersionsIter(ctx, &ListModelVersionsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListModelVersions call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListModelVersions directly. +func (c *internalClient) ListModelVersionsIter(ctx context.Context, req *ListModelVersionsRequest, opts ...call.Option) iter.Seq2[*ModelVersionInfo, error] { + return func(yield func(*ModelVersionInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListModelVersionsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListModelVersions(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.ModelVersions { + if !yield(&resp.ModelVersions[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List registered models. You can list registered models under a particular +// schema, or list all registered models in the current metastore. +// +// The returned models are filtered based on the privileges of the calling user. +// For example, the metastore admin is able to list all the registered models. A +// regular user needs to be the owner or have the **EXECUTE** privilege on the +// registered model to receive the registered models in the response. For the +// latter case, the caller must also be the owner or have the **USE_CATALOG** +// privilege on the parent catalog and the **USE_SCHEMA** privilege on the +// parent schema. +// +// There is no guarantee of a specific ordering of the elements in the response. +// +// PAGINATION BEHAVIOR: The API is by default paginated, a page may contain zero +// results while still providing a next_page_token. Clients must continue +// reading pages until next_page_token is absent, which is the only indication +// that the end of results has been reached. +func (c *internalClient) ListRegisteredModels(ctx context.Context, req *ListRegisteredModelsRequest, opts ...call.Option) (*ListRegisteredModelsResponse, error) { + wireReq, err := listRegisteredModelsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/models" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "catalog_name", wireReq.CatalogName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "schema_name", wireReq.SchemaName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListRegisteredModelsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listRegisteredModelsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listRegisteredModelsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListRegisteredModelsIter returns an iterator that iterates +// over the results of ListRegisteredModels. +// +// For example: +// +// for item, err := range c.ListRegisteredModelsIter(ctx, &ListRegisteredModelsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListRegisteredModels call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListRegisteredModels directly. +func (c *internalClient) ListRegisteredModelsIter(ctx context.Context, req *ListRegisteredModelsRequest, opts ...call.Option) iter.Seq2[*RegisteredModelInfo, error] { + return func(yield func(*RegisteredModelInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListRegisteredModelsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListRegisteredModels(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.RegisteredModels { + if !yield(&resp.RegisteredModels[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Set an alias on the specified registered model. +// +// The caller must be a metastore admin or an owner of the registered model. For +// the latter case, the caller must also be the owner or have the +// **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** +// privilege on the parent schema. +func (c *internalClient) SetRegisteredModelAlias(ctx context.Context, req *SetRegisteredModelAliasRequest, opts ...call.Option) (*RegisteredModelAliasInfo, error) { + wireReq, err := setRegisteredModelAliasRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/models/") + pb.singleSegment(*req.FullNameArg) + pb.literal("/aliases/") + pb.singleSegment(*req.AliasArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RegisteredModelAliasInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp registeredModelAliasInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = registeredModelAliasInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the specified model version. +// +// The caller must be a metastore admin or an owner of the parent registered +// model. For the latter case, the caller must also be the owner or have the +// **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** +// privilege on the parent schema. +// +// Currently only the comment of the model version can be updated. +func (c *internalClient) UpdateModelVersion(ctx context.Context, req *UpdateModelVersionRequest, opts ...call.Option) (*ModelVersionInfo, error) { + wireReq, err := updateModelVersionRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/models/") + pb.singleSegment(*req.FullNameArg) + pb.literal("/versions/") + pb.singleSegment(*req.VersionArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ModelVersionInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp modelVersionInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = modelVersionInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the specified registered model. +// +// The caller must be a metastore admin or an owner of the registered model. For +// the latter case, the caller must also be the owner or have the +// **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** +// privilege on the parent schema. +// +// Currently only the name, the owner or the comment of the registered model can +// be updated. +func (c *internalClient) UpdateRegisteredModel(ctx context.Context, req *UpdateRegisteredModelRequest, opts ...call.Option) (*RegisteredModelInfo, error) { + wireReq, err := updateRegisteredModelRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/models/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RegisteredModelInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp registeredModelInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = registeredModelInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/registeredmodels/v1/genhelper.go b/uc/registeredmodels/v1/genhelper.go new file mode 100755 index 0000000..3677467 --- /dev/null +++ b/uc/registeredmodels/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package registeredmodels + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/registeredmodels/v1/model.go b/uc/registeredmodels/v1/model.go new file mode 100755 index 0000000..3e75064 --- /dev/null +++ b/uc/registeredmodels/v1/model.go @@ -0,0 +1,443 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package registeredmodels + +type ModelVersionStatus string + +const ( + ModelVersionStatus_Unspecified ModelVersionStatus = "" + // Request to register a new model version is pending as client uploads model + // files. + ModelVersionStatus_PendingRegistration ModelVersionStatus = "PENDING_REGISTRATION" + // Request to register a new model version has failed. + ModelVersionStatus_FailedRegistration ModelVersionStatus = "FAILED_REGISTRATION" + // Model version is ready for use. + ModelVersionStatus_Ready ModelVersionStatus = "READY" +) + +// A connection that is dependent on a SQL object.. +type ConnectionDependency struct { + // Full name of the dependent connection, in the form of __connection_name__. + ConnectionName *string +} + +type CreateRegisteredModelRequest struct { + // The name of the registered model + Name *string + // The name of the catalog where the schema and the registered model reside + CatalogName *string + // The name of the schema where the registered model resides + SchemaName *string + // The identifier of the user who owns the registered model + Owner *string + // The comment attached to the registered model + Comment *string + // The storage location on the cloud under which model version data files are + // stored + StorageLocation *string + // The unique identifier of the metastore + MetastoreId *string + // The three-level (fully qualified) name of the registered model + FullName *string + // Creation timestamp of the registered model in milliseconds since the Unix + // epoch + CreatedAt *int64 + // The identifier of the user who created the registered model + CreatedBy *string + // Last-update timestamp of the registered model in milliseconds since the Unix + // epoch + UpdatedAt *int64 + // The identifier of the user who updated the registered model last time + UpdatedBy *string + // List of aliases associated with the registered model + Aliases []RegisteredModelAliasInfo + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool +} + +// A credential that is dependent on a SQL object.. +type CredentialDependency struct { + // Full name of the dependent credential, in the form of __credential_name__. + CredentialName *string +} + +type DeleteModelVersionRequest struct { + // The three-level (fully qualified) name of the model version + FullNameArg *string + // The integer version number of the model version + VersionArg *int64 +} + +type DeleteModelVersionResponse struct { +} + +type DeleteRegisteredModelAliasRequest struct { + // The three-level (fully qualified) name of the registered model + FullNameArg *string + // The name of the alias + AliasArg *string +} + +type DeleteRegisteredModelAliasResponse struct { +} + +type DeleteRegisteredModelRequest struct { + // The three-level (fully qualified) name of the registered model + FullNameArg *string +} + +type DeleteRegisteredModelResponse struct { +} + +// A dependency of a SQL object. One of the following fields must be defined: +// __table__, __function__, __connection__, __credential__, __volume__, or +// __secret__.. +type Dependency struct { + Value isDependency_Value +} + +type isDependency_Value interface { + isDependency_Value() +} + +// Dependency_Value_Table selects Table for Dependency.Value. +type Dependency_Value_Table struct { + Table TableDependency +} + +func (*Dependency_Value_Table) isDependency_Value() {} + +// Dependency_Value_Function selects Function for Dependency.Value. +type Dependency_Value_Function struct { + Function FunctionDependency +} + +func (*Dependency_Value_Function) isDependency_Value() {} + +// Dependency_Value_Connection selects Connection for Dependency.Value. +type Dependency_Value_Connection struct { + Connection ConnectionDependency +} + +func (*Dependency_Value_Connection) isDependency_Value() {} + +// Dependency_Value_Credential selects Credential for Dependency.Value. +type Dependency_Value_Credential struct { + Credential CredentialDependency +} + +func (*Dependency_Value_Credential) isDependency_Value() {} + +// A list of dependencies.. +type DependencyList struct { + // Array of dependencies. + Dependencies []Dependency +} + +// A function that is dependent on a SQL object.. +type FunctionDependency struct { + // Full name of the dependent function, in the form of + // __catalog_name__.__schema_name__.__function_name__. + FunctionFullName *string +} + +type GetModelVersionByAliasRequest struct { + // The three-level (fully qualified) name of the registered model + FullNameArg *string + // The name of the alias + AliasArg *string + // Whether to include aliases associated with the model version in the response + IncludeAliases *bool +} + +type GetModelVersionRequest struct { + // The three-level (fully qualified) name of the model version + FullNameArg *string + // The integer version number of the model version + VersionArg *int64 + // Whether to include aliases associated with the model version in the response + IncludeAliases *bool + // Whether to include model versions in the response for which the principal can + // only access selective metadata for + IncludeBrowse *bool +} + +type GetRegisteredModelRequest struct { + // The three-level (fully qualified) name of the registered model + FullNameArg *string + // Whether to include registered model aliases in the response + IncludeAliases *bool + // Whether to include registered models in the response for which the principal + // can only access selective metadata for + IncludeBrowse *bool +} + +type ListModelVersionsRequest struct { + // The full three-level name of the registered model under which to list model + // versions + FullNameArg *string + // Maximum number of model versions to return. If not set, the page length is + // set to a server configured value (100, as of 1/3/2024). - when set to a value + // greater than 0, the page length is the minimum of this value and a server + // configured value(1000, as of 1/3/2024); - when set to 0, the page length is + // set to a server configured value (100, as of 1/3/2024) (recommended); - when + // set to a value less than 0, an invalid parameter error is returned; + MaxResults *int64 + // Opaque pagination token to go to next page based on previous query. + PageToken *string + // Whether to include model versions in the response for which the principal can + // only access selective metadata for + IncludeBrowse *bool +} + +type ListModelVersionsResponse struct { + ModelVersions []ModelVersionInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type ListRegisteredModelsRequest struct { + // The identifier of the catalog under which to list registered models. If + // specified, schema_name must be specified. + CatalogName *string + // The identifier of the schema under which to list registered models. If + // specified, catalog_name must be specified. + SchemaName *string + // Whether to include registered models in the response for which the principal + // can only access selective metadata for + IncludeBrowse *bool + // Max number of registered models to return. If both catalog and schema are + // specified: - when max_results is not specified, the page length is set to a + // server configured value (10000, as of 4/2/2024). - when set to a value + // greater than 0, the page length is the minimum of this value and a server + // configured value (10000, as of 4/2/2024); - when set to 0, the page length is + // set to a server configured value (10000, as of 4/2/2024); - when set to a + // value less than 0, an invalid parameter error is returned; If neither schema + // nor catalog is specified: - when max_results is not specified, the page + // length is set to a server configured value (100, as of 4/2/2024). - when set + // to a value greater than 0, the page length is the minimum of this value and a + // server configured value (1000, as of 4/2/2024); - when set to 0, the page + // length is set to a server configured value (100, as of 4/2/2024); - when set + // to a value less than 0, an invalid parameter error is returned; + MaxResults *int64 + // Opaque token to send for the next page of results (pagination). + PageToken *string +} + +type ListRegisteredModelsResponse struct { + RegisteredModels []RegisteredModelInfo + // Opaque token for pagination. Omitted if there are no more results. page_token + // should be set to this value for fetching the next page. + NextPageToken *string +} + +type ModelVersionInfo struct { + // The name of the parent registered model of the model version, relative to + // parent schema + ModelName *string + // The name of the catalog containing the model version + CatalogName *string + // The name of the schema containing the model version, relative to parent + // catalog + SchemaName *string + // URI indicating the location of the source artifacts (files) for the model + // version + Source *string + // The comment attached to the model version + Comment *string + // MLflow run ID used when creating the model version, if ``source`` was + // generated by an experiment run stored in an MLflow tracking server + RunId *string + // ID of the workspace containing the MLflow run that generated + // this model version, if applicable + RunWorkspaceId *int64 + // Model version dependencies, for feature-store packaged models + ModelVersionDependencies *DependencyList + // Current status of the model version. Newly created model versions start in + // PENDING_REGISTRATION status, then move to READY status once the model version + // files are uploaded and the model version is finalized. Only model versions in + // READY status can be loaded for inference or served. + Status ModelVersionStatus + // Integer model version number, used to reference the model version in API + // requests. + Version *int64 + // The storage location on the cloud under which model version data files are + // stored + StorageLocation *string + // The unique identifier of the metastore containing the model version + MetastoreId *string + CreatedAt *int64 + // The identifier of the user who created the model version + CreatedBy *string + UpdatedAt *int64 + // The identifier of the user who updated the model version last time + UpdatedBy *string + // The unique identifier of the model version + Id *string + // List of aliases associated with the model version + Aliases []RegisteredModelAliasInfo +} + +type RegisteredModelAliasInfo struct { + // Name of the alias, e.g. 'champion' or 'latest_stable' + AliasName *string + // Integer version number of the model version to which this alias points. + VersionNum *int64 + // The unique identifier of the alias + Id *string + // The name of the parent registered model of the model version, relative to + // parent schema + ModelName *string + // The name of the catalog containing the model version + CatalogName *string + // The name of the schema containing the model version, relative to parent + // catalog + SchemaName *string +} + +type RegisteredModelInfo struct { + // The name of the registered model + Name *string + // The name of the catalog where the schema and the registered model reside + CatalogName *string + // The name of the schema where the registered model resides + SchemaName *string + // The identifier of the user who owns the registered model + Owner *string + // The comment attached to the registered model + Comment *string + // The storage location on the cloud under which model version data files are + // stored + StorageLocation *string + // The unique identifier of the metastore + MetastoreId *string + // The three-level (fully qualified) name of the registered model + FullName *string + // Creation timestamp of the registered model in milliseconds since the Unix + // epoch + CreatedAt *int64 + // The identifier of the user who created the registered model + CreatedBy *string + // Last-update timestamp of the registered model in milliseconds since the Unix + // epoch + UpdatedAt *int64 + // The identifier of the user who updated the registered model last time + UpdatedBy *string + // List of aliases associated with the registered model + Aliases []RegisteredModelAliasInfo + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool +} + +type SetRegisteredModelAliasRequest struct { + // The three-level (fully qualified) name of the registered model + FullNameArg *string + // The name of the alias + AliasArg *string + // The version number of the model version to which the alias points + VersionNum *int64 +} + +// A table that is dependent on a SQL object.. +type TableDependency struct { + // Full name of the dependent table, in the form of + // __catalog_name__.__schema_name__.__table_name__. + TableFullName *string +} + +type UpdateModelVersionRequest struct { + // The three-level (fully qualified) name of the model version + FullNameArg *string + // The integer version number of the model version + VersionArg *int64 + // The name of the parent registered model of the model version, relative to + // parent schema + ModelName *string + // The name of the catalog containing the model version + CatalogName *string + // The name of the schema containing the model version, relative to parent + // catalog + SchemaName *string + // URI indicating the location of the source artifacts (files) for the model + // version + Source *string + // The comment attached to the model version + Comment *string + // MLflow run ID used when creating the model version, if ``source`` was + // generated by an experiment run stored in an MLflow tracking server + RunId *string + // ID of the workspace containing the MLflow run that generated + // this model version, if applicable + RunWorkspaceId *int64 + // Model version dependencies, for feature-store packaged models + ModelVersionDependencies *DependencyList + // Current status of the model version. Newly created model versions start in + // PENDING_REGISTRATION status, then move to READY status once the model version + // files are uploaded and the model version is finalized. Only model versions in + // READY status can be loaded for inference or served. + Status ModelVersionStatus + // Integer model version number, used to reference the model version in API + // requests. + Version *int64 + // The storage location on the cloud under which model version data files are + // stored + StorageLocation *string + // The unique identifier of the metastore containing the model version + MetastoreId *string + CreatedAt *int64 + // The identifier of the user who created the model version + CreatedBy *string + UpdatedAt *int64 + // The identifier of the user who updated the model version last time + UpdatedBy *string + // The unique identifier of the model version + Id *string + // List of aliases associated with the model version + Aliases []RegisteredModelAliasInfo +} + +type UpdateRegisteredModelRequest struct { + // The three-level (fully qualified) name of the registered model + FullNameArg *string + // New name for the registered model. + NewName *string + // The name of the registered model + Name *string + // The name of the catalog where the schema and the registered model reside + CatalogName *string + // The name of the schema where the registered model resides + SchemaName *string + // The identifier of the user who owns the registered model + Owner *string + // The comment attached to the registered model + Comment *string + // The storage location on the cloud under which model version data files are + // stored + StorageLocation *string + // The unique identifier of the metastore + MetastoreId *string + // The three-level (fully qualified) name of the registered model + FullName *string + // Creation timestamp of the registered model in milliseconds since the Unix + // epoch + CreatedAt *int64 + // The identifier of the user who created the registered model + CreatedBy *string + // Last-update timestamp of the registered model in milliseconds since the Unix + // epoch + UpdatedAt *int64 + // The identifier of the user who updated the registered model last time + UpdatedBy *string + // List of aliases associated with the registered model + Aliases []RegisteredModelAliasInfo + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool +} diff --git a/uc/registeredmodels/v1/wire.go b/uc/registeredmodels/v1/wire.go new file mode 100755 index 0000000..09bf1d7 --- /dev/null +++ b/uc/registeredmodels/v1/wire.go @@ -0,0 +1,684 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package registeredmodels + +import ( + "fmt" +) + +type connectionDependencyWire struct { + ConnectionName *string `json:"connection_name,omitempty"` +} + +func connectionDependencyToWire(v *ConnectionDependency) (*connectionDependencyWire, error) { + if v == nil { + return nil, nil + } + return &connectionDependencyWire{ + ConnectionName: v.ConnectionName, + }, nil +} + +func connectionDependencyFromWire(w *connectionDependencyWire) (*ConnectionDependency, error) { + if w == nil { + return nil, nil + } + return &ConnectionDependency{ + ConnectionName: w.ConnectionName, + }, nil +} + +type createRegisteredModelRequestWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Aliases []registeredModelAliasInfoWire `json:"aliases,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` +} + +func createRegisteredModelRequestToWire(v *CreateRegisteredModelRequest) (*createRegisteredModelRequestWire, error) { + if v == nil { + return nil, nil + } + aliasesWireValue, err := convertSlice(v.Aliases, registeredModelAliasInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateRegisteredModelRequest.Aliases", err) + } + return &createRegisteredModelRequestWire{ + Name: v.Name, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + Owner: v.Owner, + Comment: v.Comment, + StorageLocation: v.StorageLocation, + MetastoreId: v.MetastoreId, + FullName: v.FullName, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + Aliases: aliasesWireValue, + BrowseOnly: v.BrowseOnly, + }, nil +} + +type credentialDependencyWire struct { + CredentialName *string `json:"credential_name,omitempty"` +} + +func credentialDependencyToWire(v *CredentialDependency) (*credentialDependencyWire, error) { + if v == nil { + return nil, nil + } + return &credentialDependencyWire{ + CredentialName: v.CredentialName, + }, nil +} + +func credentialDependencyFromWire(w *credentialDependencyWire) (*CredentialDependency, error) { + if w == nil { + return nil, nil + } + return &CredentialDependency{ + CredentialName: w.CredentialName, + }, nil +} + +type dependencyWire struct { + Table *tableDependencyWire `json:"table,omitempty"` + Function *functionDependencyWire `json:"function,omitempty"` + Connection *connectionDependencyWire `json:"connection,omitempty"` + Credential *credentialDependencyWire `json:"credential,omitempty"` +} + +func dependencyToWire(v *Dependency) (*dependencyWire, error) { + if v == nil { + return nil, nil + } + var valueTableWire *tableDependencyWire + var valueFunctionWire *functionDependencyWire + var valueConnectionWire *connectionDependencyWire + var valueCredentialWire *credentialDependencyWire + switch value := v.Value.(type) { + case nil: + case *Dependency_Value_Table: + if value != nil { + valueTableConverted, err := tableDependencyToWire(&value.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Table", err) + } + valueTableWire = valueTableConverted + } + case *Dependency_Value_Function: + if value != nil { + valueFunctionConverted, err := functionDependencyToWire(&value.Function) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Function", err) + } + valueFunctionWire = valueFunctionConverted + } + case *Dependency_Value_Connection: + if value != nil { + valueConnectionConverted, err := connectionDependencyToWire(&value.Connection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Connection", err) + } + valueConnectionWire = valueConnectionConverted + } + case *Dependency_Value_Credential: + if value != nil { + valueCredentialConverted, err := credentialDependencyToWire(&value.Credential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Credential", err) + } + valueCredentialWire = valueCredentialConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Dependency.Value", value) + } + return &dependencyWire{ + Table: valueTableWire, + Function: valueFunctionWire, + Connection: valueConnectionWire, + Credential: valueCredentialWire, + }, nil +} + +func dependencyFromWire(w *dependencyWire) (*Dependency, error) { + if w == nil { + return nil, nil + } + valueMembers := 0 + if w.Table != nil { + valueMembers++ + } + if w.Function != nil { + valueMembers++ + } + if w.Connection != nil { + valueMembers++ + } + if w.Credential != nil { + valueMembers++ + } + if valueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Dependency.Value") + } + var valueSelection isDependency_Value + switch { + case w.Table != nil: + valueTableConverted, err := tableDependencyFromWire(w.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Table", err) + } + valueSelection = &Dependency_Value_Table{Table: *valueTableConverted} + case w.Function != nil: + valueFunctionConverted, err := functionDependencyFromWire(w.Function) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Function", err) + } + valueSelection = &Dependency_Value_Function{Function: *valueFunctionConverted} + case w.Connection != nil: + valueConnectionConverted, err := connectionDependencyFromWire(w.Connection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Connection", err) + } + valueSelection = &Dependency_Value_Connection{Connection: *valueConnectionConverted} + case w.Credential != nil: + valueCredentialConverted, err := credentialDependencyFromWire(w.Credential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Credential", err) + } + valueSelection = &Dependency_Value_Credential{Credential: *valueCredentialConverted} + } + return &Dependency{ + Value: valueSelection, + }, nil +} + +type dependencyListWire struct { + Dependencies []dependencyWire `json:"dependencies,omitempty"` +} + +func dependencyListToWire(v *DependencyList) (*dependencyListWire, error) { + if v == nil { + return nil, nil + } + dependenciesWireValue, err := convertSlice(v.Dependencies, dependencyToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DependencyList.Dependencies", err) + } + return &dependencyListWire{ + Dependencies: dependenciesWireValue, + }, nil +} + +func dependencyListFromWire(w *dependencyListWire) (*DependencyList, error) { + if w == nil { + return nil, nil + } + dependenciesPublicValue, err := convertSlice(w.Dependencies, dependencyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DependencyList.Dependencies", err) + } + return &DependencyList{ + Dependencies: dependenciesPublicValue, + }, nil +} + +type functionDependencyWire struct { + FunctionFullName *string `json:"function_full_name,omitempty"` +} + +func functionDependencyToWire(v *FunctionDependency) (*functionDependencyWire, error) { + if v == nil { + return nil, nil + } + return &functionDependencyWire{ + FunctionFullName: v.FunctionFullName, + }, nil +} + +func functionDependencyFromWire(w *functionDependencyWire) (*FunctionDependency, error) { + if w == nil { + return nil, nil + } + return &FunctionDependency{ + FunctionFullName: w.FunctionFullName, + }, nil +} + +type getModelVersionByAliasRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + AliasArg *string `json:"alias_arg,omitempty"` + IncludeAliases *bool `json:"include_aliases,omitempty"` +} + +func getModelVersionByAliasRequestToWire(v *GetModelVersionByAliasRequest) (*getModelVersionByAliasRequestWire, error) { + if v == nil { + return nil, nil + } + return &getModelVersionByAliasRequestWire{ + FullNameArg: v.FullNameArg, + AliasArg: v.AliasArg, + IncludeAliases: v.IncludeAliases, + }, nil +} + +type getModelVersionRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + VersionArg *int64 `json:"version_arg,omitempty"` + IncludeAliases *bool `json:"include_aliases,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` +} + +func getModelVersionRequestToWire(v *GetModelVersionRequest) (*getModelVersionRequestWire, error) { + if v == nil { + return nil, nil + } + return &getModelVersionRequestWire{ + FullNameArg: v.FullNameArg, + VersionArg: v.VersionArg, + IncludeAliases: v.IncludeAliases, + IncludeBrowse: v.IncludeBrowse, + }, nil +} + +type getRegisteredModelRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + IncludeAliases *bool `json:"include_aliases,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` +} + +func getRegisteredModelRequestToWire(v *GetRegisteredModelRequest) (*getRegisteredModelRequestWire, error) { + if v == nil { + return nil, nil + } + return &getRegisteredModelRequestWire{ + FullNameArg: v.FullNameArg, + IncludeAliases: v.IncludeAliases, + IncludeBrowse: v.IncludeBrowse, + }, nil +} + +type listModelVersionsRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + MaxResults *int64 `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` +} + +func listModelVersionsRequestToWire(v *ListModelVersionsRequest) (*listModelVersionsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listModelVersionsRequestWire{ + FullNameArg: v.FullNameArg, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + IncludeBrowse: v.IncludeBrowse, + }, nil +} + +type listModelVersionsResponseWire struct { + ModelVersions []modelVersionInfoWire `json:"model_versions,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listModelVersionsResponseFromWire(w *listModelVersionsResponseWire) (*ListModelVersionsResponse, error) { + if w == nil { + return nil, nil + } + modelVersionsPublicValue, err := convertSlice(w.ModelVersions, modelVersionInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListModelVersionsResponse.ModelVersions", err) + } + return &ListModelVersionsResponse{ + ModelVersions: modelVersionsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listRegisteredModelsRequestWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` + MaxResults *int64 `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listRegisteredModelsRequestToWire(v *ListRegisteredModelsRequest) (*listRegisteredModelsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listRegisteredModelsRequestWire{ + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + IncludeBrowse: v.IncludeBrowse, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listRegisteredModelsResponseWire struct { + RegisteredModels []registeredModelInfoWire `json:"registered_models,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listRegisteredModelsResponseFromWire(w *listRegisteredModelsResponseWire) (*ListRegisteredModelsResponse, error) { + if w == nil { + return nil, nil + } + registeredModelsPublicValue, err := convertSlice(w.RegisteredModels, registeredModelInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListRegisteredModelsResponse.RegisteredModels", err) + } + return &ListRegisteredModelsResponse{ + RegisteredModels: registeredModelsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type modelVersionInfoWire struct { + ModelName *string `json:"model_name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + Source *string `json:"source,omitempty"` + Comment *string `json:"comment,omitempty"` + RunId *string `json:"run_id,omitempty"` + RunWorkspaceId *int64 `json:"run_workspace_id,omitempty"` + ModelVersionDependencies *dependencyListWire `json:"model_version_dependencies,omitempty"` + Status ModelVersionStatus `json:"status,omitempty"` + Version *int64 `json:"version,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Id *string `json:"id,omitempty"` + Aliases []registeredModelAliasInfoWire `json:"aliases,omitempty"` +} + +func modelVersionInfoFromWire(w *modelVersionInfoWire) (*ModelVersionInfo, error) { + if w == nil { + return nil, nil + } + modelVersionDependenciesPublicValue, err := dependencyListFromWire(w.ModelVersionDependencies) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelVersionInfo.ModelVersionDependencies", err) + } + aliasesPublicValue, err := convertSlice(w.Aliases, registeredModelAliasInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ModelVersionInfo.Aliases", err) + } + return &ModelVersionInfo{ + ModelName: w.ModelName, + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + Source: w.Source, + Comment: w.Comment, + RunId: w.RunId, + RunWorkspaceId: w.RunWorkspaceId, + ModelVersionDependencies: modelVersionDependenciesPublicValue, + Status: w.Status, + Version: w.Version, + StorageLocation: w.StorageLocation, + MetastoreId: w.MetastoreId, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + Id: w.Id, + Aliases: aliasesPublicValue, + }, nil +} + +type registeredModelAliasInfoWire struct { + AliasName *string `json:"alias_name,omitempty"` + VersionNum *int64 `json:"version_num,omitempty"` + Id *string `json:"id,omitempty"` + ModelName *string `json:"model_name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` +} + +func registeredModelAliasInfoToWire(v *RegisteredModelAliasInfo) (*registeredModelAliasInfoWire, error) { + if v == nil { + return nil, nil + } + return ®isteredModelAliasInfoWire{ + AliasName: v.AliasName, + VersionNum: v.VersionNum, + Id: v.Id, + ModelName: v.ModelName, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + }, nil +} + +func registeredModelAliasInfoFromWire(w *registeredModelAliasInfoWire) (*RegisteredModelAliasInfo, error) { + if w == nil { + return nil, nil + } + return &RegisteredModelAliasInfo{ + AliasName: w.AliasName, + VersionNum: w.VersionNum, + Id: w.Id, + ModelName: w.ModelName, + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + }, nil +} + +type registeredModelInfoWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Aliases []registeredModelAliasInfoWire `json:"aliases,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` +} + +func registeredModelInfoFromWire(w *registeredModelInfoWire) (*RegisteredModelInfo, error) { + if w == nil { + return nil, nil + } + aliasesPublicValue, err := convertSlice(w.Aliases, registeredModelAliasInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RegisteredModelInfo.Aliases", err) + } + return &RegisteredModelInfo{ + Name: w.Name, + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + Owner: w.Owner, + Comment: w.Comment, + StorageLocation: w.StorageLocation, + MetastoreId: w.MetastoreId, + FullName: w.FullName, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + Aliases: aliasesPublicValue, + BrowseOnly: w.BrowseOnly, + }, nil +} + +type setRegisteredModelAliasRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + AliasArg *string `json:"alias_arg,omitempty"` + VersionNum *int64 `json:"version_num,omitempty"` +} + +func setRegisteredModelAliasRequestToWire(v *SetRegisteredModelAliasRequest) (*setRegisteredModelAliasRequestWire, error) { + if v == nil { + return nil, nil + } + return &setRegisteredModelAliasRequestWire{ + FullNameArg: v.FullNameArg, + AliasArg: v.AliasArg, + VersionNum: v.VersionNum, + }, nil +} + +type tableDependencyWire struct { + TableFullName *string `json:"table_full_name,omitempty"` +} + +func tableDependencyToWire(v *TableDependency) (*tableDependencyWire, error) { + if v == nil { + return nil, nil + } + return &tableDependencyWire{ + TableFullName: v.TableFullName, + }, nil +} + +func tableDependencyFromWire(w *tableDependencyWire) (*TableDependency, error) { + if w == nil { + return nil, nil + } + return &TableDependency{ + TableFullName: w.TableFullName, + }, nil +} + +type updateModelVersionRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + VersionArg *int64 `json:"version_arg,omitempty"` + ModelName *string `json:"model_name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + Source *string `json:"source,omitempty"` + Comment *string `json:"comment,omitempty"` + RunId *string `json:"run_id,omitempty"` + RunWorkspaceId *int64 `json:"run_workspace_id,omitempty"` + ModelVersionDependencies *dependencyListWire `json:"model_version_dependencies,omitempty"` + Status ModelVersionStatus `json:"status,omitempty"` + Version *int64 `json:"version,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Id *string `json:"id,omitempty"` + Aliases []registeredModelAliasInfoWire `json:"aliases,omitempty"` +} + +func updateModelVersionRequestToWire(v *UpdateModelVersionRequest) (*updateModelVersionRequestWire, error) { + if v == nil { + return nil, nil + } + modelVersionDependenciesWireValue, err := dependencyListToWire(v.ModelVersionDependencies) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateModelVersionRequest.ModelVersionDependencies", err) + } + aliasesWireValue, err := convertSlice(v.Aliases, registeredModelAliasInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateModelVersionRequest.Aliases", err) + } + return &updateModelVersionRequestWire{ + FullNameArg: v.FullNameArg, + VersionArg: v.VersionArg, + ModelName: v.ModelName, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + Source: v.Source, + Comment: v.Comment, + RunId: v.RunId, + RunWorkspaceId: v.RunWorkspaceId, + ModelVersionDependencies: modelVersionDependenciesWireValue, + Status: v.Status, + Version: v.Version, + StorageLocation: v.StorageLocation, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + Id: v.Id, + Aliases: aliasesWireValue, + }, nil +} + +type updateRegisteredModelRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Aliases []registeredModelAliasInfoWire `json:"aliases,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` +} + +func updateRegisteredModelRequestToWire(v *UpdateRegisteredModelRequest) (*updateRegisteredModelRequestWire, error) { + if v == nil { + return nil, nil + } + aliasesWireValue, err := convertSlice(v.Aliases, registeredModelAliasInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateRegisteredModelRequest.Aliases", err) + } + return &updateRegisteredModelRequestWire{ + FullNameArg: v.FullNameArg, + NewName: v.NewName, + Name: v.Name, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + Owner: v.Owner, + Comment: v.Comment, + StorageLocation: v.StorageLocation, + MetastoreId: v.MetastoreId, + FullName: v.FullName, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + Aliases: aliasesWireValue, + BrowseOnly: v.BrowseOnly, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/resourcequotas/.package.json b/uc/resourcequotas/.package.json new file mode 100644 index 0000000..a7b637e --- /dev/null +++ b/uc/resourcequotas/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/resourcequotas" +} diff --git a/uc/resourcequotas/CHANGELOG.md b/uc/resourcequotas/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/resourcequotas/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/resourcequotas/README.md b/uc/resourcequotas/README.md new file mode 100644 index 0000000..1609bae --- /dev/null +++ b/uc/resourcequotas/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/resourcequotas + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/resourcequotas@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/resourcequotas/v1" + +client, err := resourcequotas.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/resourcequotas/go.mod b/uc/resourcequotas/go.mod new file mode 100644 index 0000000..57cc643 --- /dev/null +++ b/uc/resourcequotas/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/resourcequotas + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/resourcequotas/internal/version.go b/uc/resourcequotas/internal/version.go new file mode 100644 index 0000000..3e2c4da --- /dev/null +++ b/uc/resourcequotas/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-resourcequotas" + +const Version = "0.0.1-dev.1" diff --git a/uc/resourcequotas/v1/client.go b/uc/resourcequotas/v1/client.go new file mode 100755 index 0000000..bd7b2be --- /dev/null +++ b/uc/resourcequotas/v1/client.go @@ -0,0 +1,259 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package resourcequotas + +import ( + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/resourcequotas/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// The GetQuota API returns usage information for a single resource quota, +// defined as a child-parent pair. This API also refreshes the quota count if it +// is out of date. Refreshes are triggered asynchronously. The updated count +// might not be returned in the first call. +func (c *internalClient) GetQuota(ctx context.Context, req *GetQuotaRequest, opts ...call.Option) (*GetQuotaResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/resource-quotas/") + pb.singleSegment(*req.ParentSecurableType) + pb.literal("/") + pb.singleSegment(*req.ParentFullName) + pb.literal("/") + pb.singleSegment(*req.QuotaName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetQuotaResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getQuotaResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getQuotaResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListQuotas returns all quota values under the metastore. There are no SLAs on +// the freshness of the counts returned. This API does not trigger a refresh of +// quota counts. +// +// PAGINATION BEHAVIOR: The API is by default paginated, a page may contain zero +// results while still providing a next_page_token. Clients must continue +// reading pages until next_page_token is absent, which is the only indication +// that the end of results has been reached. +func (c *internalClient) ListQuotas(ctx context.Context, req *ListQuotasRequest, opts ...call.Option) (*ListQuotasResponse, error) { + wireReq, err := listQuotasRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/resource-quotas/all-resource-quotas" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListQuotasResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listQuotasResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listQuotasResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListQuotasIter returns an iterator that iterates +// over the results of ListQuotas. +// +// For example: +// +// for item, err := range c.ListQuotasIter(ctx, &ListQuotasRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListQuotas call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListQuotas directly. +func (c *internalClient) ListQuotasIter(ctx context.Context, req *ListQuotasRequest, opts ...call.Option) iter.Seq2[*QuotaInfo, error] { + return func(yield func(*QuotaInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListQuotasRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListQuotas(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Quotas { + if !yield(&resp.Quotas[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} diff --git a/uc/resourcequotas/v1/genhelper.go b/uc/resourcequotas/v1/genhelper.go new file mode 100755 index 0000000..45b9b91 --- /dev/null +++ b/uc/resourcequotas/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package resourcequotas + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/resourcequotas/v1/model.go b/uc/resourcequotas/v1/model.go new file mode 100755 index 0000000..4b06ec2 --- /dev/null +++ b/uc/resourcequotas/v1/model.go @@ -0,0 +1,75 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package resourcequotas + +// The type of Unity Catalog securable. +type SecurableType string + +const ( + SecurableType_Unspecified SecurableType = "" + SecurableType_Catalog SecurableType = "CATALOG" + SecurableType_Schema SecurableType = "SCHEMA" + SecurableType_Table SecurableType = "TABLE" + SecurableType_StorageCredential SecurableType = "STORAGE_CREDENTIAL" + SecurableType_ExternalLocation SecurableType = "EXTERNAL_LOCATION" + SecurableType_Function SecurableType = "FUNCTION" + SecurableType_Share SecurableType = "SHARE" + SecurableType_Provider SecurableType = "PROVIDER" + SecurableType_Recipient SecurableType = "RECIPIENT" + SecurableType_CleanRoom SecurableType = "CLEAN_ROOM" + SecurableType_Metastore SecurableType = "METASTORE" + SecurableType_Pipeline SecurableType = "PIPELINE" + SecurableType_Volume SecurableType = "VOLUME" + SecurableType_Connection SecurableType = "CONNECTION" + SecurableType_Credential SecurableType = "CREDENTIAL" + SecurableType_ExternalMetadata SecurableType = "EXTERNAL_METADATA" + // TODO: [UC-2980] Staging tables aren't full-fleged securables yet. + SecurableType_StagingTable SecurableType = "STAGING_TABLE" +) + +type GetQuotaRequest struct { + // Securable type of the quota parent. + ParentSecurableType *string + // Full name of the parent resource. Provide the metastore ID if the parent is a + // metastore. + ParentFullName *string + // Name of the quota. Follows the pattern of the quota type, with "-quota" added + // as a suffix. + QuotaName *string +} + +type GetQuotaResponse struct { + // The returned QuotaInfo. + QuotaInfo *QuotaInfo +} + +type ListQuotasRequest struct { + // The number of quotas to return. + MaxResults *int + // Opaque token for the next page of results. + PageToken *string +} + +type ListQuotasResponse struct { + // An array of returned QuotaInfos. + Quotas []QuotaInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request. + NextPageToken *string +} + +type QuotaInfo struct { + // The quota parent securable type. + ParentSecurableType SecurableType + // Name of the parent resource. Returns metastore ID if the parent is a + // metastore. + ParentFullName *string + // The name of the quota. + QuotaName *string + // The current usage of the resource quota. + QuotaCount *int + // The current limit of the resource quota. + QuotaLimit *int + // The timestamp that indicates when the quota count was last updated. + LastRefreshedAt *int64 +} diff --git a/uc/resourcequotas/v1/wire.go b/uc/resourcequotas/v1/wire.go new file mode 100755 index 0000000..aa20ccb --- /dev/null +++ b/uc/resourcequotas/v1/wire.go @@ -0,0 +1,96 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package resourcequotas + +import ( + "fmt" +) + +type getQuotaResponseWire struct { + QuotaInfo *quotaInfoWire `json:"quota_info,omitempty"` +} + +func getQuotaResponseFromWire(w *getQuotaResponseWire) (*GetQuotaResponse, error) { + if w == nil { + return nil, nil + } + quotaInfoPublicValue, err := quotaInfoFromWire(w.QuotaInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetQuotaResponse.QuotaInfo", err) + } + return &GetQuotaResponse{ + QuotaInfo: quotaInfoPublicValue, + }, nil +} + +type listQuotasRequestWire struct { + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listQuotasRequestToWire(v *ListQuotasRequest) (*listQuotasRequestWire, error) { + if v == nil { + return nil, nil + } + return &listQuotasRequestWire{ + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listQuotasResponseWire struct { + Quotas []quotaInfoWire `json:"quotas,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listQuotasResponseFromWire(w *listQuotasResponseWire) (*ListQuotasResponse, error) { + if w == nil { + return nil, nil + } + quotasPublicValue, err := convertSlice(w.Quotas, quotaInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListQuotasResponse.Quotas", err) + } + return &ListQuotasResponse{ + Quotas: quotasPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type quotaInfoWire struct { + ParentSecurableType SecurableType `json:"parent_securable_type,omitempty"` + ParentFullName *string `json:"parent_full_name,omitempty"` + QuotaName *string `json:"quota_name,omitempty"` + QuotaCount *int `json:"quota_count,omitempty"` + QuotaLimit *int `json:"quota_limit,omitempty"` + LastRefreshedAt *int64 `json:"last_refreshed_at,omitempty"` +} + +func quotaInfoFromWire(w *quotaInfoWire) (*QuotaInfo, error) { + if w == nil { + return nil, nil + } + return &QuotaInfo{ + ParentSecurableType: w.ParentSecurableType, + ParentFullName: w.ParentFullName, + QuotaName: w.QuotaName, + QuotaCount: w.QuotaCount, + QuotaLimit: w.QuotaLimit, + LastRefreshedAt: w.LastRefreshedAt, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/rfa/.package.json b/uc/rfa/.package.json new file mode 100644 index 0000000..afd6530 --- /dev/null +++ b/uc/rfa/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/rfa" +} diff --git a/uc/rfa/CHANGELOG.md b/uc/rfa/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/rfa/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/rfa/README.md b/uc/rfa/README.md new file mode 100644 index 0000000..2eb17a9 --- /dev/null +++ b/uc/rfa/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/rfa + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/rfa@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/rfa/v1" + +client, err := rfa.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/rfa/go.mod b/uc/rfa/go.mod new file mode 100644 index 0000000..dbc5fd2 --- /dev/null +++ b/uc/rfa/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/rfa + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/rfa/internal/version.go b/uc/rfa/internal/version.go new file mode 100644 index 0000000..a85413d --- /dev/null +++ b/uc/rfa/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-rfa" + +const Version = "0.0.1-dev.1" diff --git a/uc/rfa/v1/client.go b/uc/rfa/v1/client.go new file mode 100755 index 0000000..358c80c --- /dev/null +++ b/uc/rfa/v1/client.go @@ -0,0 +1,296 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package rfa + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/rfa/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates access requests for Unity Catalog permissions for a specified +// principal on a securable object. This Batch API can take in multiple +// principals, securable objects, and permissions as the input and returns the +// access request destinations for each. Principals must be unique across the +// API call. +// +// The supported securable types are: "metastore", "catalog", "schema", "table", +// "external_location", "connection", "credential", "function", +// "registered_model", and "volume". +func (c *internalClient) BatchCreateAccessRequests(ctx context.Context, req *BatchCreateAccessRequestsRequest, opts ...call.Option) (*BatchCreateAccessRequestsResponse, error) { + wireReq, err := batchCreateAccessRequestsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/3.0/rfa/requests" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *BatchCreateAccessRequestsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp batchCreateAccessRequestsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = batchCreateAccessRequestsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of access request destinations for the specified securable. Any +// caller can see URL destinations or the destinations on the metastore. +// Otherwise, only those with **BROWSE** permissions on the securable can see +// destinations. +// +// The supported securable types are: "metastore", "catalog", "schema", "table", +// "external_location", "connection", "credential", "function", +// "registered_model", and "volume". +func (c *internalClient) GetAccessRequestDestinations(ctx context.Context, req *GetAccessRequestDestinationsRequest, opts ...call.Option) (*AccessRequestDestinations, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/3.0/rfa/destinations/") + pb.singleSegment(*req.SecurableType) + pb.literal("/") + pb.singleSegment(*req.FullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccessRequestDestinations + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accessRequestDestinationsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accessRequestDestinationsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the access request destinations for the given securable. The caller +// must be a metastore admin, the owner of the securable, or a user that has the +// **MANAGE** privilege on the securable in order to assign destinations. A +// maximum of 5 emails and 5 external notification destinations (Slack, +// Microsoft Teams, and Generic Webhook destinations) can be assigned to a +// securable. If a URL destination is assigned, no other destinations can be +// set. +// +// The supported securable types are: "metastore", "catalog", "schema", "table", +// "external_location", "connection", "credential", "function", +// "registered_model", and "volume". +func (c *internalClient) UpdateAccessRequestDestinations(ctx context.Context, req *UpdateAccessRequestDestinationsRequest, opts ...call.Option) (*AccessRequestDestinations, error) { + wireReq, err := updateAccessRequestDestinationsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.AccessRequestDestinations) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/3.0/rfa/destinations" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *AccessRequestDestinations + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp accessRequestDestinationsWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = accessRequestDestinationsFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/rfa/v1/genhelper.go b/uc/rfa/v1/genhelper.go new file mode 100755 index 0000000..a2369ff --- /dev/null +++ b/uc/rfa/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package rfa + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/rfa/v1/model.go b/uc/rfa/v1/model.go new file mode 100755 index 0000000..5d20af5 --- /dev/null +++ b/uc/rfa/v1/model.go @@ -0,0 +1,188 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package rfa + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type DestinationType string + +const ( + DestinationType_Unspecified DestinationType = "" + DestinationType_Email DestinationType = "EMAIL" + DestinationType_Slack DestinationType = "SLACK" + DestinationType_GenericWebhook DestinationType = "GENERIC_WEBHOOK" + DestinationType_MicrosoftTeams DestinationType = "MICROSOFT_TEAMS" + DestinationType_Url DestinationType = "URL" +) + +type PrincipalType string + +const ( + PrincipalType_Unspecified PrincipalType = "" + PrincipalType_UserPrincipal PrincipalType = "USER_PRINCIPAL" + PrincipalType_GroupPrincipal PrincipalType = "GROUP_PRINCIPAL" + PrincipalType_ServicePrincipal PrincipalType = "SERVICE_PRINCIPAL" +) + +// The type of Unity Catalog securable. +type SecurableType string + +const ( + SecurableType_Unspecified SecurableType = "" + SecurableType_Catalog SecurableType = "CATALOG" + SecurableType_Schema SecurableType = "SCHEMA" + SecurableType_Table SecurableType = "TABLE" + SecurableType_StorageCredential SecurableType = "STORAGE_CREDENTIAL" + SecurableType_ExternalLocation SecurableType = "EXTERNAL_LOCATION" + SecurableType_Function SecurableType = "FUNCTION" + SecurableType_Share SecurableType = "SHARE" + SecurableType_Provider SecurableType = "PROVIDER" + SecurableType_Recipient SecurableType = "RECIPIENT" + SecurableType_CleanRoom SecurableType = "CLEAN_ROOM" + SecurableType_Metastore SecurableType = "METASTORE" + SecurableType_Pipeline SecurableType = "PIPELINE" + SecurableType_Volume SecurableType = "VOLUME" + SecurableType_Connection SecurableType = "CONNECTION" + SecurableType_Credential SecurableType = "CREDENTIAL" + SecurableType_ExternalMetadata SecurableType = "EXTERNAL_METADATA" + // TODO: [UC-2980] Staging tables aren't full-fleged securables yet. + SecurableType_StagingTable SecurableType = "STAGING_TABLE" +) + +type SpecialDestination string + +const ( + SpecialDestination_Unspecified SpecialDestination = "" + SpecialDestination_SpecialDestinationCatalogOwner SpecialDestination = "SPECIAL_DESTINATION_CATALOG_OWNER" + SpecialDestination_SpecialDestinationExternalLocationOwner SpecialDestination = "SPECIAL_DESTINATION_EXTERNAL_LOCATION_OWNER" + SpecialDestination_SpecialDestinationConnectionOwner SpecialDestination = "SPECIAL_DESTINATION_CONNECTION_OWNER" + SpecialDestination_SpecialDestinationCredentialOwner SpecialDestination = "SPECIAL_DESTINATION_CREDENTIAL_OWNER" + SpecialDestination_SpecialDestinationMetastoreOwner SpecialDestination = "SPECIAL_DESTINATION_METASTORE_OWNER" + SpecialDestination_SpecialDestinationSchemaOwner SpecialDestination = "SPECIAL_DESTINATION_SCHEMA_OWNER" + SpecialDestination_SpecialDestinationTableOwner SpecialDestination = "SPECIAL_DESTINATION_TABLE_OWNER" + SpecialDestination_SpecialDestinationVolumeOwner SpecialDestination = "SPECIAL_DESTINATION_VOLUME_OWNER" + SpecialDestination_SpecialDestinationFunctionOwner SpecialDestination = "SPECIAL_DESTINATION_FUNCTION_OWNER" + SpecialDestination_SpecialDestinationRegisteredModelOwner SpecialDestination = "SPECIAL_DESTINATION_REGISTERED_MODEL_OWNER" +) + +type AccessRequestDestinations struct { + // The access request destinations for the securable. + Destinations []NotificationDestination `fieldmask:"destinations"` + // The securable for which the access request destinations are being modified or + // read. + Securable *Securable `fieldmask:"securable"` + // Indicates whether any destinations are hidden from the caller due to a lack + // of permissions. This value is true if the caller does not have permission to + // see all destinations. + AreAnyDestinationsHidden *bool `fieldmask:"are_any_destinations_hidden"` + // The source securable from which the destinations are inherited. Either the + // same value as securable (if destination is set directly on the securable) or + // the nearest parent securable with destinations set. + DestinationSourceSecurable *Securable `fieldmask:"destination_source_securable"` + // The type of the securable. Redundant with the type in the securable object, + // but necessary for Terraform integration + SecurableType *string `fieldmask:"securable_type"` + // The full name of the securable. Redundant with the name in the securable + // object, but necessary for Terraform integration + FullName *string `fieldmask:"full_name"` +} + +type BatchCreateAccessRequestsRequest struct { + // A list of individual access requests, where each request corresponds to a set + // of permissions being requested on a list of securables for a specified + // principal. + // + // At most 30 requests per API call. + Requests []CreateAccessRequest +} + +type BatchCreateAccessRequestsResponse struct { + // The access request destinations for each securable object the principal + // requested. + Responses []CreateAccessRequestResponse +} + +type CreateAccessRequest struct { + // Optional. The principal this request is for. Empty `behalf_of` defaults to + // the requester's identity. + // + // Principals must be unique across the API call. + BehalfOf *Principal + // Optional. Comment associated with the request. + // + // At most 200 characters, can only contain lowercase/uppercase letters (a-z, + // A-Z), numbers (0-9), punctuation, and spaces. + Comment *string + // List of securables and their corresponding requested UC privileges. + // + // At most 30 securables can be requested for a principal per batched call. Each + // securable can only be requested once per principal. + SecurablePermissions []SecurablePermissions +} + +type CreateAccessRequestResponse struct { + // The principal the request was made on behalf of. + BehalfOf *Principal + // The access request destinations for all the securables the principal + // requested. + RequestDestinations []AccessRequestDestinations +} + +type GetAccessRequestDestinationsRequest struct { + // The type of the securable. + SecurableType *string + // The full name of the securable. + FullName *string +} + +type NotificationDestination struct { + // The identifier for the destination. This is the email address for EMAIL + // destinations, the URL for URL destinations, or the unique + // notification destination ID for all other external destinations. + DestinationId *string + // The type of the destination. + DestinationType DestinationType + // This field is used to denote whether the destination is the email of the + // owner of the securable object. The special destination cannot be assigned to + // a securable and only represents the default destination of the securable. The + // securable types that support default special destinations are: "catalog", + // "external_location", "connection", "credential", and "metastore". The + // **destination_type** of a **special_destination** is always EMAIL. + SpecialDestination SpecialDestination +} + +type Principal struct { + // user, group or service principal ID. + Id *string + PrincipalType PrincipalType +} + +// Generic definition of a securable, which is uniquely defined in a metastore +// by its type and full name.. +type Securable struct { + // Required. The type of securable (catalog/schema/table). Optional if + // resource_name is present. + Type SecurableType `fieldmask:"type"` + // Required. The full name of the catalog/schema/table. Optional if + // resource_name is present. + FullName *string `fieldmask:"full_name"` + // Optional. The name of the Share object that contains the securable when the + // securable is getting shared in D2D Delta Sharing. + ProviderShare *string `fieldmask:"provider_share"` +} + +type SecurablePermissions struct { + // The securable for which the access request destinations are being requested. + Securable *Securable + // List of requested Unity Catalog permissions. + Permissions []string +} + +type UpdateAccessRequestDestinationsRequest struct { + // The access request destinations to assign to the securable. For each + // destination, a **destination_id** and **destination_type** must be defined. + AccessRequestDestinations *AccessRequestDestinations + UpdateMask *types.FieldMask[AccessRequestDestinations] +} diff --git a/uc/rfa/v1/wire.go b/uc/rfa/v1/wire.go new file mode 100755 index 0000000..6c1c8bc --- /dev/null +++ b/uc/rfa/v1/wire.go @@ -0,0 +1,294 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package rfa + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type accessRequestDestinationsWire struct { + Destinations []notificationDestinationWire `json:"destinations,omitempty"` + Securable *securableWire `json:"securable,omitempty"` + AreAnyDestinationsHidden *bool `json:"are_any_destinations_hidden,omitempty"` + DestinationSourceSecurable *securableWire `json:"destination_source_securable,omitempty"` + SecurableType *string `json:"securable_type,omitempty"` + FullName *string `json:"full_name,omitempty"` +} + +func accessRequestDestinationsToWire(v *AccessRequestDestinations) (*accessRequestDestinationsWire, error) { + if v == nil { + return nil, nil + } + destinationsWireValue, err := convertSlice(v.Destinations, notificationDestinationToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccessRequestDestinations.Destinations", err) + } + securableWireValue, err := securableToWire(v.Securable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccessRequestDestinations.Securable", err) + } + destinationSourceSecurableWireValue, err := securableToWire(v.DestinationSourceSecurable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccessRequestDestinations.DestinationSourceSecurable", err) + } + return &accessRequestDestinationsWire{ + Destinations: destinationsWireValue, + Securable: securableWireValue, + AreAnyDestinationsHidden: v.AreAnyDestinationsHidden, + DestinationSourceSecurable: destinationSourceSecurableWireValue, + SecurableType: v.SecurableType, + FullName: v.FullName, + }, nil +} + +func accessRequestDestinationsFromWire(w *accessRequestDestinationsWire) (*AccessRequestDestinations, error) { + if w == nil { + return nil, nil + } + destinationsPublicValue, err := convertSlice(w.Destinations, notificationDestinationFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccessRequestDestinations.Destinations", err) + } + securablePublicValue, err := securableFromWire(w.Securable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccessRequestDestinations.Securable", err) + } + destinationSourceSecurablePublicValue, err := securableFromWire(w.DestinationSourceSecurable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "AccessRequestDestinations.DestinationSourceSecurable", err) + } + return &AccessRequestDestinations{ + Destinations: destinationsPublicValue, + Securable: securablePublicValue, + AreAnyDestinationsHidden: w.AreAnyDestinationsHidden, + DestinationSourceSecurable: destinationSourceSecurablePublicValue, + SecurableType: w.SecurableType, + FullName: w.FullName, + }, nil +} + +type batchCreateAccessRequestsRequestWire struct { + Requests []createAccessRequestWire `json:"requests,omitempty"` +} + +func batchCreateAccessRequestsRequestToWire(v *BatchCreateAccessRequestsRequest) (*batchCreateAccessRequestsRequestWire, error) { + if v == nil { + return nil, nil + } + requestsWireValue, err := convertSlice(v.Requests, createAccessRequestToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BatchCreateAccessRequestsRequest.Requests", err) + } + return &batchCreateAccessRequestsRequestWire{ + Requests: requestsWireValue, + }, nil +} + +type batchCreateAccessRequestsResponseWire struct { + Responses []createAccessRequestResponseWire `json:"responses,omitempty"` +} + +func batchCreateAccessRequestsResponseFromWire(w *batchCreateAccessRequestsResponseWire) (*BatchCreateAccessRequestsResponse, error) { + if w == nil { + return nil, nil + } + responsesPublicValue, err := convertSlice(w.Responses, createAccessRequestResponseFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "BatchCreateAccessRequestsResponse.Responses", err) + } + return &BatchCreateAccessRequestsResponse{ + Responses: responsesPublicValue, + }, nil +} + +type createAccessRequestWire struct { + BehalfOf *principalWire `json:"behalf_of,omitempty"` + Comment *string `json:"comment,omitempty"` + SecurablePermissions []securablePermissionsWire `json:"securable_permissions,omitempty"` +} + +func createAccessRequestToWire(v *CreateAccessRequest) (*createAccessRequestWire, error) { + if v == nil { + return nil, nil + } + behalfOfWireValue, err := principalToWire(v.BehalfOf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccessRequest.BehalfOf", err) + } + securablePermissionsWireValue, err := convertSlice(v.SecurablePermissions, securablePermissionsToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccessRequest.SecurablePermissions", err) + } + return &createAccessRequestWire{ + BehalfOf: behalfOfWireValue, + Comment: v.Comment, + SecurablePermissions: securablePermissionsWireValue, + }, nil +} + +type createAccessRequestResponseWire struct { + BehalfOf *principalWire `json:"behalf_of,omitempty"` + RequestDestinations []accessRequestDestinationsWire `json:"request_destinations,omitempty"` +} + +func createAccessRequestResponseFromWire(w *createAccessRequestResponseWire) (*CreateAccessRequestResponse, error) { + if w == nil { + return nil, nil + } + behalfOfPublicValue, err := principalFromWire(w.BehalfOf) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccessRequestResponse.BehalfOf", err) + } + requestDestinationsPublicValue, err := convertSlice(w.RequestDestinations, accessRequestDestinationsFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateAccessRequestResponse.RequestDestinations", err) + } + return &CreateAccessRequestResponse{ + BehalfOf: behalfOfPublicValue, + RequestDestinations: requestDestinationsPublicValue, + }, nil +} + +type notificationDestinationWire struct { + DestinationId *string `json:"destination_id,omitempty"` + DestinationType DestinationType `json:"destination_type,omitempty"` + SpecialDestination SpecialDestination `json:"special_destination,omitempty"` +} + +func notificationDestinationToWire(v *NotificationDestination) (*notificationDestinationWire, error) { + if v == nil { + return nil, nil + } + return ¬ificationDestinationWire{ + DestinationId: v.DestinationId, + DestinationType: v.DestinationType, + SpecialDestination: v.SpecialDestination, + }, nil +} + +func notificationDestinationFromWire(w *notificationDestinationWire) (*NotificationDestination, error) { + if w == nil { + return nil, nil + } + return &NotificationDestination{ + DestinationId: w.DestinationId, + DestinationType: w.DestinationType, + SpecialDestination: w.SpecialDestination, + }, nil +} + +type principalWire struct { + Id *string `json:"id,omitempty"` + PrincipalType PrincipalType `json:"principal_type,omitempty"` +} + +func principalToWire(v *Principal) (*principalWire, error) { + if v == nil { + return nil, nil + } + return &principalWire{ + Id: v.Id, + PrincipalType: v.PrincipalType, + }, nil +} + +func principalFromWire(w *principalWire) (*Principal, error) { + if w == nil { + return nil, nil + } + return &Principal{ + Id: w.Id, + PrincipalType: w.PrincipalType, + }, nil +} + +type securableWire struct { + Type SecurableType `json:"type,omitempty"` + FullName *string `json:"full_name,omitempty"` + ProviderShare *string `json:"provider_share,omitempty"` +} + +func securableToWire(v *Securable) (*securableWire, error) { + if v == nil { + return nil, nil + } + return &securableWire{ + Type: v.Type, + FullName: v.FullName, + ProviderShare: v.ProviderShare, + }, nil +} + +func securableFromWire(w *securableWire) (*Securable, error) { + if w == nil { + return nil, nil + } + return &Securable{ + Type: w.Type, + FullName: w.FullName, + ProviderShare: w.ProviderShare, + }, nil +} + +type securablePermissionsWire struct { + Securable *securableWire `json:"securable,omitempty"` + Permissions []string `json:"permissions,omitempty"` +} + +func securablePermissionsToWire(v *SecurablePermissions) (*securablePermissionsWire, error) { + if v == nil { + return nil, nil + } + securableWireValue, err := securableToWire(v.Securable) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SecurablePermissions.Securable", err) + } + return &securablePermissionsWire{ + Securable: securableWireValue, + Permissions: v.Permissions, + }, nil +} + +type updateAccessRequestDestinationsRequestWire struct { + AccessRequestDestinations *accessRequestDestinationsWire `json:"access_request_destinations,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateAccessRequestDestinationsRequestToWire(v *UpdateAccessRequestDestinationsRequest) (*updateAccessRequestDestinationsRequestWire, error) { + if v == nil { + return nil, nil + } + accessRequestDestinationsWireValue, err := accessRequestDestinationsToWire(v.AccessRequestDestinations) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateAccessRequestDestinationsRequest.AccessRequestDestinations", err) + } + return &updateAccessRequestDestinationsRequestWire{ + AccessRequestDestinations: accessRequestDestinationsWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/schemas/.package.json b/uc/schemas/.package.json new file mode 100644 index 0000000..2072898 --- /dev/null +++ b/uc/schemas/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/schemas" +} diff --git a/uc/schemas/CHANGELOG.md b/uc/schemas/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/schemas/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/schemas/README.md b/uc/schemas/README.md new file mode 100644 index 0000000..47b462f --- /dev/null +++ b/uc/schemas/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/schemas + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/schemas@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/schemas/v1" + +client, err := schemas.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/schemas/go.mod b/uc/schemas/go.mod new file mode 100644 index 0000000..030cf32 --- /dev/null +++ b/uc/schemas/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/schemas + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/schemas/internal/version.go b/uc/schemas/internal/version.go new file mode 100644 index 0000000..15382de --- /dev/null +++ b/uc/schemas/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-schemas" + +const Version = "0.0.1-dev.1" diff --git a/uc/schemas/v1/client.go b/uc/schemas/v1/client.go new file mode 100755 index 0000000..8783f82 --- /dev/null +++ b/uc/schemas/v1/client.go @@ -0,0 +1,476 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package schemas + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/schemas/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new schema for catalog in the Metastore. The caller must be a +// metastore admin, or have the **CREATE_SCHEMA** privilege in the parent +// catalog. +func (c *internalClient) CreateSchema(ctx context.Context, req *CreateSchemaRequest, opts ...call.Option) (*SchemaInfo, error) { + wireReq, err := createSchemaRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/schemas" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SchemaInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp schemaInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = schemaInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes the specified schema from the parent catalog. The caller must be the +// owner of the schema or an owner of the parent catalog. +func (c *internalClient) DeleteSchema(ctx context.Context, req *DeleteSchemaRequest, opts ...call.Option) (*DeleteSchemaResponse, error) { + wireReq, err := deleteSchemaRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/schemas/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "force", wireReq.Force); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteSchemaResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteSchemaResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the specified schema within the metastore. The caller must be a +// metastore admin, the owner of the schema, or a user that has the +// **USE_SCHEMA** privilege on the schema. +func (c *internalClient) GetSchema(ctx context.Context, req *GetSchemaRequest, opts ...call.Option) (*SchemaInfo, error) { + wireReq, err := getSchemaRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/schemas/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SchemaInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp schemaInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = schemaInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of schemas for a catalog in the metastore. If the caller is the +// metastore admin or the owner of the parent catalog, all schemas for the +// catalog will be retrieved. Otherwise, only schemas owned by the caller (or +// for which the caller has the **USE_SCHEMA** privilege) will be retrieved. +// There is no guarantee of a specific ordering of the elements in the array. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) ListSchemas(ctx context.Context, req *ListSchemasRequest, opts ...call.Option) (*ListSchemasResponse, error) { + wireReq, err := listSchemasRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/schemas" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "catalog_name", wireReq.CatalogName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListSchemasResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listSchemasResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listSchemasResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListSchemasIter returns an iterator that iterates +// over the results of ListSchemas. +// +// For example: +// +// for item, err := range c.ListSchemasIter(ctx, &ListSchemasRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListSchemas call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListSchemas directly. +func (c *internalClient) ListSchemasIter(ctx context.Context, req *ListSchemasRequest, opts ...call.Option) iter.Seq2[*SchemaInfo, error] { + return func(yield func(*SchemaInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListSchemasRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListSchemas(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Schemas { + if !yield(&resp.Schemas[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates a schema for a catalog. The caller must be the owner of the schema or +// a metastore admin. If the caller is a metastore admin, only the __owner__ +// field can be changed in the update. If the __name__ field must be updated, +// the caller must be a metastore admin or have the **CREATE_SCHEMA** privilege +// on the parent catalog. +func (c *internalClient) UpdateSchema(ctx context.Context, req *UpdateSchemaRequest, opts ...call.Option) (*SchemaInfo, error) { + wireReq, err := updateSchemaRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/schemas/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SchemaInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp schemaInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = schemaInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/schemas/v1/genhelper.go b/uc/schemas/v1/genhelper.go new file mode 100755 index 0000000..3d56735 --- /dev/null +++ b/uc/schemas/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package schemas + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/schemas/v1/model.go b/uc/schemas/v1/model.go new file mode 100755 index 0000000..3cb89c7 --- /dev/null +++ b/uc/schemas/v1/model.go @@ -0,0 +1,210 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package schemas + +// The type of the catalog. +type CatalogType string + +const ( + CatalogType_Unspecified CatalogType = "" + CatalogType_ManagedCatalog CatalogType = "MANAGED_CATALOG" + CatalogType_DeltasharingCatalog CatalogType = "DELTASHARING_CATALOG" + CatalogType_SystemCatalog CatalogType = "SYSTEM_CATALOG" + CatalogType_InternalCatalog CatalogType = "INTERNAL_CATALOG" + CatalogType_ForeignCatalog CatalogType = "FOREIGN_CATALOG" + CatalogType_ManagedOnlineCatalog CatalogType = "MANAGED_ONLINE_CATALOG" +) + +type CreateSchemaRequest struct { + // Name of schema, relative to parent catalog. + Name *string + // Name of parent catalog. + CatalogName *string + // Username of current owner of schema. + Owner *string + // User-provided free-form text description. + Comment *string + // Storage root URL for managed tables within schema. + StorageRoot *string + // Whether predictive optimization should be enabled for this object and objects + // under it. + EnablePredictiveOptimization *string + // Unique identifier of parent metastore. + MetastoreId *string + // Full name of schema, in form of __catalog_name__.__schema_name__. + FullName *string + // Time at which this schema was created, in epoch milliseconds. + CreatedAt *int64 + // Username of schema creator. + CreatedBy *string + // Time at which this schema was created, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified schema. + UpdatedBy *string + // The type of the parent catalog. + CatalogType CatalogType + // Storage location for managed tables within schema. + StorageLocation *string + EffectivePredictiveOptimizationFlag *EffectivePredictiveOptimizationFlag + // The unique identifier of the schema. + SchemaId *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + // Custom maximum retention period in hours for the schema. + CustomMaxRetentionHours *int64 + // A map of key-value properties attached to the securable. + Properties map[string]string + // A map of key-value properties attached to the securable. + Options map[string]string +} + +type DeleteSchemaRequest struct { + // Full name of the schema. + FullNameArg *string + // Force deletion even if the schema is not empty. + Force *bool +} + +type DeleteSchemaResponse struct { +} + +type EffectivePredictiveOptimizationFlag struct { + // Whether predictive optimization should be enabled for this object and objects + // under it. + Value *string + // The type of the object from which the flag was inherited. If there was no + // inheritance, this field is left blank. + InheritedFromType *string + // The name of the object from which the flag was inherited. If there was no + // inheritance, this field is left blank. + InheritedFromName *string +} + +type GetSchemaRequest struct { + // Full name of the schema. + FullNameArg *string + // Whether to include schemas in the response for which the principal can only + // access selective metadata for + IncludeBrowse *bool +} + +type ListSchemasRequest struct { + // Parent catalog for schemas of interest. + CatalogName *string + // Maximum number of schemas to return. If not set, all the schemas are returned + // (not recommended). - when set to a value greater than 0, the page length is + // the minimum of this value and a server configured value; - when set to 0, the + // page length is set to a server configured value (recommended); - when set to + // a value less than 0, an invalid parameter error is returned; + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string + // Whether to include schemas in the response for which the principal can only + // access selective metadata for + IncludeBrowse *bool +} + +type ListSchemasResponse struct { + // An array of schema information objects. + Schemas []SchemaInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type SchemaInfo struct { + // Name of schema, relative to parent catalog. + Name *string + // Name of parent catalog. + CatalogName *string + // Username of current owner of schema. + Owner *string + // User-provided free-form text description. + Comment *string + // Storage root URL for managed tables within schema. + StorageRoot *string + // Whether predictive optimization should be enabled for this object and objects + // under it. + EnablePredictiveOptimization *string + // Unique identifier of parent metastore. + MetastoreId *string + // Full name of schema, in form of __catalog_name__.__schema_name__. + FullName *string + // Time at which this schema was created, in epoch milliseconds. + CreatedAt *int64 + // Username of schema creator. + CreatedBy *string + // Time at which this schema was created, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified schema. + UpdatedBy *string + // The type of the parent catalog. + CatalogType CatalogType + // Storage location for managed tables within schema. + StorageLocation *string + EffectivePredictiveOptimizationFlag *EffectivePredictiveOptimizationFlag + // The unique identifier of the schema. + SchemaId *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + // Custom maximum retention period in hours for the schema. + CustomMaxRetentionHours *int64 + // A map of key-value properties attached to the securable. + Properties map[string]string + // A map of key-value properties attached to the securable. + Options map[string]string +} + +type UpdateSchemaRequest struct { + // Full name of the schema. + FullNameArg *string + // New name for the schema. + NewName *string + // Name of schema, relative to parent catalog. + Name *string + // Name of parent catalog. + CatalogName *string + // Username of current owner of schema. + Owner *string + // User-provided free-form text description. + Comment *string + // Storage root URL for managed tables within schema. + StorageRoot *string + // Whether predictive optimization should be enabled for this object and objects + // under it. + EnablePredictiveOptimization *string + // Unique identifier of parent metastore. + MetastoreId *string + // Full name of schema, in form of __catalog_name__.__schema_name__. + FullName *string + // Time at which this schema was created, in epoch milliseconds. + CreatedAt *int64 + // Username of schema creator. + CreatedBy *string + // Time at which this schema was created, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified schema. + UpdatedBy *string + // The type of the parent catalog. + CatalogType CatalogType + // Storage location for managed tables within schema. + StorageLocation *string + EffectivePredictiveOptimizationFlag *EffectivePredictiveOptimizationFlag + // The unique identifier of the schema. + SchemaId *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + // Custom maximum retention period in hours for the schema. + CustomMaxRetentionHours *int64 + // A map of key-value properties attached to the securable. + Properties map[string]string + // A map of key-value properties attached to the securable. + Options map[string]string +} diff --git a/uc/schemas/v1/wire.go b/uc/schemas/v1/wire.go new file mode 100755 index 0000000..c932a72 --- /dev/null +++ b/uc/schemas/v1/wire.go @@ -0,0 +1,287 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package schemas + +import ( + "fmt" +) + +type createSchemaRequestWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + EnablePredictiveOptimization *string `json:"enable_predictive_optimization,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + CatalogType CatalogType `json:"catalog_type,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + EffectivePredictiveOptimizationFlag *effectivePredictiveOptimizationFlagWire `json:"effective_predictive_optimization_flag,omitempty"` + SchemaId *string `json:"schema_id,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + CustomMaxRetentionHours *int64 `json:"custom_max_retention_hours,omitempty"` + Properties map[string]string `json:"properties,omitempty"` + Options map[string]string `json:"options,omitempty"` +} + +func createSchemaRequestToWire(v *CreateSchemaRequest) (*createSchemaRequestWire, error) { + if v == nil { + return nil, nil + } + effectivePredictiveOptimizationFlagWireValue, err := effectivePredictiveOptimizationFlagToWire(v.EffectivePredictiveOptimizationFlag) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateSchemaRequest.EffectivePredictiveOptimizationFlag", err) + } + return &createSchemaRequestWire{ + Name: v.Name, + CatalogName: v.CatalogName, + Owner: v.Owner, + Comment: v.Comment, + StorageRoot: v.StorageRoot, + EnablePredictiveOptimization: v.EnablePredictiveOptimization, + MetastoreId: v.MetastoreId, + FullName: v.FullName, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + CatalogType: v.CatalogType, + StorageLocation: v.StorageLocation, + EffectivePredictiveOptimizationFlag: effectivePredictiveOptimizationFlagWireValue, + SchemaId: v.SchemaId, + BrowseOnly: v.BrowseOnly, + CustomMaxRetentionHours: v.CustomMaxRetentionHours, + Properties: v.Properties, + Options: v.Options, + }, nil +} + +type deleteSchemaRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + Force *bool `json:"force,omitempty"` +} + +func deleteSchemaRequestToWire(v *DeleteSchemaRequest) (*deleteSchemaRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteSchemaRequestWire{ + FullNameArg: v.FullNameArg, + Force: v.Force, + }, nil +} + +type effectivePredictiveOptimizationFlagWire struct { + Value *string `json:"value,omitempty"` + InheritedFromType *string `json:"inherited_from_type,omitempty"` + InheritedFromName *string `json:"inherited_from_name,omitempty"` +} + +func effectivePredictiveOptimizationFlagToWire(v *EffectivePredictiveOptimizationFlag) (*effectivePredictiveOptimizationFlagWire, error) { + if v == nil { + return nil, nil + } + return &effectivePredictiveOptimizationFlagWire{ + Value: v.Value, + InheritedFromType: v.InheritedFromType, + InheritedFromName: v.InheritedFromName, + }, nil +} + +func effectivePredictiveOptimizationFlagFromWire(w *effectivePredictiveOptimizationFlagWire) (*EffectivePredictiveOptimizationFlag, error) { + if w == nil { + return nil, nil + } + return &EffectivePredictiveOptimizationFlag{ + Value: w.Value, + InheritedFromType: w.InheritedFromType, + InheritedFromName: w.InheritedFromName, + }, nil +} + +type getSchemaRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` +} + +func getSchemaRequestToWire(v *GetSchemaRequest) (*getSchemaRequestWire, error) { + if v == nil { + return nil, nil + } + return &getSchemaRequestWire{ + FullNameArg: v.FullNameArg, + IncludeBrowse: v.IncludeBrowse, + }, nil +} + +type listSchemasRequestWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` +} + +func listSchemasRequestToWire(v *ListSchemasRequest) (*listSchemasRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSchemasRequestWire{ + CatalogName: v.CatalogName, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + IncludeBrowse: v.IncludeBrowse, + }, nil +} + +type listSchemasResponseWire struct { + Schemas []schemaInfoWire `json:"schemas,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listSchemasResponseFromWire(w *listSchemasResponseWire) (*ListSchemasResponse, error) { + if w == nil { + return nil, nil + } + schemasPublicValue, err := convertSlice(w.Schemas, schemaInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListSchemasResponse.Schemas", err) + } + return &ListSchemasResponse{ + Schemas: schemasPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type schemaInfoWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + EnablePredictiveOptimization *string `json:"enable_predictive_optimization,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + CatalogType CatalogType `json:"catalog_type,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + EffectivePredictiveOptimizationFlag *effectivePredictiveOptimizationFlagWire `json:"effective_predictive_optimization_flag,omitempty"` + SchemaId *string `json:"schema_id,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + CustomMaxRetentionHours *int64 `json:"custom_max_retention_hours,omitempty"` + Properties map[string]string `json:"properties,omitempty"` + Options map[string]string `json:"options,omitempty"` +} + +func schemaInfoFromWire(w *schemaInfoWire) (*SchemaInfo, error) { + if w == nil { + return nil, nil + } + effectivePredictiveOptimizationFlagPublicValue, err := effectivePredictiveOptimizationFlagFromWire(w.EffectivePredictiveOptimizationFlag) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SchemaInfo.EffectivePredictiveOptimizationFlag", err) + } + return &SchemaInfo{ + Name: w.Name, + CatalogName: w.CatalogName, + Owner: w.Owner, + Comment: w.Comment, + StorageRoot: w.StorageRoot, + EnablePredictiveOptimization: w.EnablePredictiveOptimization, + MetastoreId: w.MetastoreId, + FullName: w.FullName, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + CatalogType: w.CatalogType, + StorageLocation: w.StorageLocation, + EffectivePredictiveOptimizationFlag: effectivePredictiveOptimizationFlagPublicValue, + SchemaId: w.SchemaId, + BrowseOnly: w.BrowseOnly, + CustomMaxRetentionHours: w.CustomMaxRetentionHours, + Properties: w.Properties, + Options: w.Options, + }, nil +} + +type updateSchemaRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageRoot *string `json:"storage_root,omitempty"` + EnablePredictiveOptimization *string `json:"enable_predictive_optimization,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + CatalogType CatalogType `json:"catalog_type,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + EffectivePredictiveOptimizationFlag *effectivePredictiveOptimizationFlagWire `json:"effective_predictive_optimization_flag,omitempty"` + SchemaId *string `json:"schema_id,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + CustomMaxRetentionHours *int64 `json:"custom_max_retention_hours,omitempty"` + Properties map[string]string `json:"properties,omitempty"` + Options map[string]string `json:"options,omitempty"` +} + +func updateSchemaRequestToWire(v *UpdateSchemaRequest) (*updateSchemaRequestWire, error) { + if v == nil { + return nil, nil + } + effectivePredictiveOptimizationFlagWireValue, err := effectivePredictiveOptimizationFlagToWire(v.EffectivePredictiveOptimizationFlag) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateSchemaRequest.EffectivePredictiveOptimizationFlag", err) + } + return &updateSchemaRequestWire{ + FullNameArg: v.FullNameArg, + NewName: v.NewName, + Name: v.Name, + CatalogName: v.CatalogName, + Owner: v.Owner, + Comment: v.Comment, + StorageRoot: v.StorageRoot, + EnablePredictiveOptimization: v.EnablePredictiveOptimization, + MetastoreId: v.MetastoreId, + FullName: v.FullName, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + CatalogType: v.CatalogType, + StorageLocation: v.StorageLocation, + EffectivePredictiveOptimizationFlag: effectivePredictiveOptimizationFlagWireValue, + SchemaId: v.SchemaId, + BrowseOnly: v.BrowseOnly, + CustomMaxRetentionHours: v.CustomMaxRetentionHours, + Properties: v.Properties, + Options: v.Options, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/secrets/.package.json b/uc/secrets/.package.json new file mode 100644 index 0000000..6e9ab41 --- /dev/null +++ b/uc/secrets/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/secrets" +} diff --git a/uc/secrets/CHANGELOG.md b/uc/secrets/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/secrets/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/secrets/README.md b/uc/secrets/README.md new file mode 100644 index 0000000..e237fcb --- /dev/null +++ b/uc/secrets/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/secrets + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/secrets@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/secrets/v1" + +client, err := secrets.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/secrets/go.mod b/uc/secrets/go.mod new file mode 100644 index 0000000..a3f1fd9 --- /dev/null +++ b/uc/secrets/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/secrets + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/secrets/internal/version.go b/uc/secrets/internal/version.go new file mode 100644 index 0000000..0402d5e --- /dev/null +++ b/uc/secrets/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-secrets" + +const Version = "0.0.1-dev.1" diff --git a/uc/secrets/v1/client.go b/uc/secrets/v1/client.go new file mode 100755 index 0000000..1005f05 --- /dev/null +++ b/uc/secrets/v1/client.go @@ -0,0 +1,478 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package secrets + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/secrets/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new secret in Unity Catalog. +// +// You must be the owner of the parent schema or have the **CREATE_SECRET** and +// **USE SCHEMA** privileges on the parent schema and **USE CATALOG** on the +// parent catalog. +// +// The secret is stored in the specified catalog and schema, and the **value** +// field contains the sensitive data to be securely stored. +func (c *internalClient) CreateSecret(ctx context.Context, req *CreateSecretRequest, opts ...call.Option) (*Secret, error) { + wireReq, err := createSecretRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Secret) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/secrets" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Secret + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp secretWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = secretFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a secret by its three-level (fully qualified) name. +// +// You must be the owner of the secret or a metastore admin. +func (c *internalClient) DeleteSecret(ctx context.Context, req *DeleteSecretRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/secrets/") + pb.singleSegment(*req.FullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Gets a secret by its three-level (fully qualified) name. +// +// You must be a metastore admin, the owner of the secret, or have the +// **MANAGE** privilege on the secret. +// +// The secret value isn't returned by default. To retrieve it, you must also +// have the **READ_SECRET** privilege and set **include_value** to true in the +// request. +func (c *internalClient) GetSecret(ctx context.Context, req *GetSecretRequest, opts ...call.Option) (*Secret, error) { + wireReq, err := getSecretRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/secrets/") + pb.singleSegment(*req.FullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_value", wireReq.IncludeValue); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Secret + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp secretWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = secretFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists secrets in Unity Catalog. +// +// You must be a metastore admin, the owner of the secret, or have the +// **MANAGE** privilege on the secret. +// +// Both **catalog_name** and **schema_name** must be specified together to +// filter secrets within a specific schema. Results are paginated; use the +// **page_token** field from the response to retrieve subsequent pages. +func (c *internalClient) ListSecrets(ctx context.Context, req *ListSecretsRequest, opts ...call.Option) (*ListSecretsResponse, error) { + wireReq, err := listSecretsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/secrets" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "catalog_name", wireReq.CatalogName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "schema_name", wireReq.SchemaName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListSecretsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listSecretsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listSecretsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListSecretsIter returns an iterator that iterates +// over the results of ListSecrets. +// +// For example: +// +// for item, err := range c.ListSecretsIter(ctx, &ListSecretsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListSecrets call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListSecrets directly. +func (c *internalClient) ListSecretsIter(ctx context.Context, req *ListSecretsRequest, opts ...call.Option) iter.Seq2[*Secret, error] { + return func(yield func(*Secret, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListSecretsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListSecrets(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Secrets { + if !yield(&resp.Secrets[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates an existing secret in Unity Catalog. +// +// You must be the owner of the secret or a metastore admin. If you are a +// metastore admin, only the **owner** field can be changed. +// +// Use the **update_mask** field to specify which fields to update. Supported +// updatable fields include **value**, **comment**, **owner**, and +// **expire_time**. +func (c *internalClient) UpdateSecret(ctx context.Context, req *UpdateSecretRequest, opts ...call.Option) (*Secret, error) { + wireReq, err := updateSecretRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.Secret) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/secrets/") + pb.singleSegment(*req.FullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Secret + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp secretWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = secretFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/secrets/v1/genhelper.go b/uc/secrets/v1/genhelper.go new file mode 100755 index 0000000..81cbef7 --- /dev/null +++ b/uc/secrets/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package secrets + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/secrets/v1/model.go b/uc/secrets/v1/model.go new file mode 100755 index 0000000..7a523fd --- /dev/null +++ b/uc/secrets/v1/model.go @@ -0,0 +1,125 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package secrets + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// Request message for CreateSecret.. +type CreateSecretRequest struct { + // The secret object to create. The **name**, **catalog_name**, **schema_name**, + // and **value** fields are required. + Secret *Secret +} + +// Request message for DeleteSecret.. +type DeleteSecretRequest struct { + // The three-level (fully qualified) name of the secret (for example, + // **catalog_name.schema_name.secret_name**). + FullName *string +} + +// Request message for GetSecret.. +type GetSecretRequest struct { + // The three-level (fully qualified) name of the secret (for example, + // **catalog_name.schema_name.secret_name**). + FullName *string + // Whether to include the secret value in the response. Defaults to false. + // Requires the **READ_SECRET** privilege. + IncludeValue *bool +} + +// Request message for ListSecrets.. +type ListSecretsRequest struct { + // The name of the catalog under which to list secrets. Both **catalog_name** + // and **schema_name** must be specified together. + CatalogName *string + // The name of the schema under which to list secrets. Both **catalog_name** and + // **schema_name** must be specified together. + SchemaName *string + // Opaque pagination token to go to the next page based on previous query. The + // maximum page length is determined by a server configured value. + PageToken *string + // Maximum number of secrets to return. + // + // - If not specified, at most 1000 secrets are returned. - If set to a value + // greater than 0, the page length is the minimum of this value and 1000. - If + // set to 0, the page length is set to 1000. - If set to a value less than 0, an + // invalid parameter error is returned. + PageSize *int +} + +// Response message for ListSecrets.. +type ListSecretsResponse struct { + // An array of secret objects. + Secrets []Secret + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. **page_token** should be set to this value for the next request. + NextPageToken *string +} + +// A secret stored in Unity Catalog. Secrets are three-level namespace objects +// (catalog.schema.secret) that securely store sensitive credential data such as +// passwords, tokens, and keys.. +type Secret struct { + // The name of the secret, relative to its parent schema. + Name *string `fieldmask:"name"` + // The owner of the secret. Defaults to the creating principal on creation. Can + // be updated to transfer ownership of the secret to another principal. + Owner *string `fieldmask:"owner"` + // The effective owner of the secret, which may differ from the directly-set + // **owner** due to inheritance. + EffectiveOwner *string `fieldmask:"effective_owner"` + // Unique identifier of the metastore hosting the secret. + MetastoreId *string `fieldmask:"metastore_id"` + // The time at which this secret was created. + CreateTime *types.Time `fieldmask:"create_time"` + // The principal that created the secret. + CreatedBy *string `fieldmask:"created_by"` + // The time at which this secret was last updated. + UpdateTime *types.Time `fieldmask:"update_time"` + // The principal that last updated the secret. + UpdatedBy *string `fieldmask:"updated_by"` + // User-provided free-form text description of the secret. + Comment *string `fieldmask:"comment"` + // The three-level (fully qualified) name of the secret, in the form of + // **catalog_name.schema_name.secret_name**. + FullName *string `fieldmask:"full_name"` + // The name of the catalog where the schema and the secret reside. + CatalogName *string `fieldmask:"catalog_name"` + // The name of the schema where the secret resides. + SchemaName *string `fieldmask:"schema_name"` + // The secret value to store. This field is input-only and is not returned in + // responses — use the **effective_value** field (via GetSecret with + // **include_value** set to true) to read the secret value. The maximum size is + // 60 KiB (pre-encryption). Accepted content includes passwords, tokens, keys, + // and other sensitive credential data. + Value *string `fieldmask:"value"` + // The secret value. Only populated in responses when you have the + // **READ_SECRET** privilege and **include_value** is set to true in the + // request. The maximum size is 60 KiB. + EffectiveValue *string `fieldmask:"effective_value"` + // User-provided expiration time of the secret. This field indicates when the + // secret should no longer be used and may be displayed as a warning in the UI. + // It is purely informational and does not trigger any automatic actions or + // affect the secret's lifecycle. + ExpireTime *types.Time `fieldmask:"expire_time"` +} + +// Request message for UpdateSecret.. +type UpdateSecretRequest struct { + // The three-level (fully qualified) name of the secret (for example, + // **catalog_name.schema_name.secret_name**). + FullName *string + // The secret object containing the fields to update. Only fields specified in + // **update_mask** will be updated. + Secret *Secret + // The field mask specifying which fields of the secret to update. - If + // **update_mask** is **"*"**, all fields specified in **secret** are updated. - + // If **update_mask** specifies one or more fields, only those fields are + // updated. Each specified field must be set in **secret**. Supported fields: + // **value**, **comment**, **owner**, **expire_time**. To change the secret + // name, delete and recreate the secret. + UpdateMask *types.FieldMask[Secret] +} diff --git a/uc/secrets/v1/wire.go b/uc/secrets/v1/wire.go new file mode 100755 index 0000000..ae4e1c5 --- /dev/null +++ b/uc/secrets/v1/wire.go @@ -0,0 +1,187 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package secrets + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type createSecretRequestWire struct { + Secret *secretWire `json:"secret,omitempty"` +} + +func createSecretRequestToWire(v *CreateSecretRequest) (*createSecretRequestWire, error) { + if v == nil { + return nil, nil + } + secretWireValue, err := secretToWire(v.Secret) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateSecretRequest.Secret", err) + } + return &createSecretRequestWire{ + Secret: secretWireValue, + }, nil +} + +type getSecretRequestWire struct { + FullName *string `json:"full_name,omitempty"` + IncludeValue *bool `json:"include_value,omitempty"` +} + +func getSecretRequestToWire(v *GetSecretRequest) (*getSecretRequestWire, error) { + if v == nil { + return nil, nil + } + return &getSecretRequestWire{ + FullName: v.FullName, + IncludeValue: v.IncludeValue, + }, nil +} + +type listSecretsRequestWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + PageToken *string `json:"page_token,omitempty"` + PageSize *int `json:"page_size,omitempty"` +} + +func listSecretsRequestToWire(v *ListSecretsRequest) (*listSecretsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSecretsRequestWire{ + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + PageToken: v.PageToken, + PageSize: v.PageSize, + }, nil +} + +type listSecretsResponseWire struct { + Secrets []secretWire `json:"secrets,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listSecretsResponseFromWire(w *listSecretsResponseWire) (*ListSecretsResponse, error) { + if w == nil { + return nil, nil + } + secretsPublicValue, err := convertSlice(w.Secrets, secretFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListSecretsResponse.Secrets", err) + } + return &ListSecretsResponse{ + Secrets: secretsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type secretWire struct { + Name *string `json:"name,omitempty"` + Owner *string `json:"owner,omitempty"` + EffectiveOwner *string `json:"effective_owner,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreateTime *types.Time `json:"create_time,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdateTime *types.Time `json:"update_time,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Comment *string `json:"comment,omitempty"` + FullName *string `json:"full_name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + Value *string `json:"value,omitempty"` + EffectiveValue *string `json:"effective_value,omitempty"` + ExpireTime *types.Time `json:"expire_time,omitempty"` +} + +func secretToWire(v *Secret) (*secretWire, error) { + if v == nil { + return nil, nil + } + return &secretWire{ + Name: v.Name, + Owner: v.Owner, + EffectiveOwner: v.EffectiveOwner, + MetastoreId: v.MetastoreId, + CreateTime: v.CreateTime, + CreatedBy: v.CreatedBy, + UpdateTime: v.UpdateTime, + UpdatedBy: v.UpdatedBy, + Comment: v.Comment, + FullName: v.FullName, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + Value: v.Value, + EffectiveValue: v.EffectiveValue, + ExpireTime: v.ExpireTime, + }, nil +} + +func secretFromWire(w *secretWire) (*Secret, error) { + if w == nil { + return nil, nil + } + return &Secret{ + Name: w.Name, + Owner: w.Owner, + EffectiveOwner: w.EffectiveOwner, + MetastoreId: w.MetastoreId, + CreateTime: w.CreateTime, + CreatedBy: w.CreatedBy, + UpdateTime: w.UpdateTime, + UpdatedBy: w.UpdatedBy, + Comment: w.Comment, + FullName: w.FullName, + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + Value: w.Value, + EffectiveValue: w.EffectiveValue, + ExpireTime: w.ExpireTime, + }, nil +} + +type updateSecretRequestWire struct { + FullName *string `json:"full_name,omitempty"` + Secret *secretWire `json:"secret,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateSecretRequestToWire(v *UpdateSecretRequest) (*updateSecretRequestWire, error) { + if v == nil { + return nil, nil + } + secretWireValue, err := secretToWire(v.Secret) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateSecretRequest.Secret", err) + } + return &updateSecretRequestWire{ + FullName: v.FullName, + Secret: secretWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/systemschemas/.package.json b/uc/systemschemas/.package.json new file mode 100644 index 0000000..f52fea5 --- /dev/null +++ b/uc/systemschemas/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/systemschemas" +} diff --git a/uc/systemschemas/CHANGELOG.md b/uc/systemschemas/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/systemschemas/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/systemschemas/README.md b/uc/systemschemas/README.md new file mode 100644 index 0000000..2d7812b --- /dev/null +++ b/uc/systemschemas/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/systemschemas + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/systemschemas@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/systemschemas/v1" + +client, err := systemschemas.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/systemschemas/go.mod b/uc/systemschemas/go.mod new file mode 100644 index 0000000..7cd6423 --- /dev/null +++ b/uc/systemschemas/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/systemschemas + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/systemschemas/internal/version.go b/uc/systemschemas/internal/version.go new file mode 100644 index 0000000..b91a1e8 --- /dev/null +++ b/uc/systemschemas/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-systemschemas" + +const Version = "0.0.1-dev.1" diff --git a/uc/systemschemas/v1/client.go b/uc/systemschemas/v1/client.go new file mode 100755 index 0000000..a28d30f --- /dev/null +++ b/uc/systemschemas/v1/client.go @@ -0,0 +1,322 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package systemschemas + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/systemschemas/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Disables the system schema and removes it from the system catalog. The caller +// must be an account admin or a metastore admin. +func (c *internalClient) DisableSystemSchema(ctx context.Context, req *DisableSystemSchemaRequest, opts ...call.Option) (*DisableSystemSchemaResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/metastores/") + pb.singleSegment(*req.MetastoreId) + pb.literal("/systemschemas/") + pb.singleSegment(*req.Schema) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DisableSystemSchemaResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DisableSystemSchemaResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Enables the system schema and adds it to the system catalog. The caller must +// be an account admin or a metastore admin. +func (c *internalClient) EnableSystemSchema(ctx context.Context, req *EnableSystemSchemaRequest, opts ...call.Option) (*EnableSystemSchemaResponse, error) { + wireReq, err := enableSystemSchemaRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/metastores/") + pb.singleSegment(*req.MetastoreId) + pb.literal("/systemschemas/") + pb.singleSegment(*req.Schema) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EnableSystemSchemaResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &EnableSystemSchemaResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of system schemas for a metastore. The caller must be an +// account admin or a metastore admin. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) ListSystemSchemas(ctx context.Context, req *ListSystemSchemasRequest, opts ...call.Option) (*ListSystemSchemasResponse, error) { + wireReq, err := listSystemSchemasRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/metastores/") + pb.singleSegment(*req.MetastoreId) + pb.literal("/systemschemas") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListSystemSchemasResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listSystemSchemasResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listSystemSchemasResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListSystemSchemasIter returns an iterator that iterates +// over the results of ListSystemSchemas. +// +// For example: +// +// for item, err := range c.ListSystemSchemasIter(ctx, &ListSystemSchemasRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListSystemSchemas call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListSystemSchemas directly. +func (c *internalClient) ListSystemSchemasIter(ctx context.Context, req *ListSystemSchemasRequest, opts ...call.Option) iter.Seq2[*SystemSchemaInfo, error] { + return func(yield func(*SystemSchemaInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListSystemSchemasRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListSystemSchemas(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Schemas { + if !yield(&resp.Schemas[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} diff --git a/uc/systemschemas/v1/genhelper.go b/uc/systemschemas/v1/genhelper.go new file mode 100755 index 0000000..51cb642 --- /dev/null +++ b/uc/systemschemas/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package systemschemas + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/systemschemas/v1/model.go b/uc/systemschemas/v1/model.go new file mode 100755 index 0000000..c3dc3e3 --- /dev/null +++ b/uc/systemschemas/v1/model.go @@ -0,0 +1,57 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package systemschemas + +type DisableSystemSchemaRequest struct { + // Full name of the system schema. + Schema *string + // The metastore ID under which the system schema lives. + MetastoreId *string +} + +type DisableSystemSchemaResponse struct { +} + +type EnableSystemSchemaRequest struct { + // Full name of the system schema. + Schema *string + // The metastore ID under which the system schema lives. + MetastoreId *string + // the catalog for which the system schema is to enabled in + CatalogName *string +} + +type EnableSystemSchemaResponse struct { +} + +type ListSystemSchemasRequest struct { + // The ID for the metastore in which the system schema resides. + MetastoreId *string + // Maximum number of schemas to return. - When set to 0, the page length is set + // to a server configured value (recommended); - When set to a value greater + // than 0, the page length is the minimum of this value and a server configured + // value; - When set to a value less than 0, an invalid parameter error is + // returned; - If not set, all the schemas are returned (not recommended). + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type ListSystemSchemasResponse struct { + // An array of system schema information objects. + Schemas []SystemSchemaInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type SystemSchemaInfo struct { + // Name of the system schema. + Schema *string + // The current state of enablement for the system schema. An empty string means + // the system schema is available and ready for opt-in. Possible values: + // AVAILABLE | ENABLE_INITIALIZED | ENABLE_COMPLETED | DISABLE_INITIALIZED | + // UNAVAILABLE | MANAGED + State *string +} diff --git a/uc/systemschemas/v1/wire.go b/uc/systemschemas/v1/wire.go new file mode 100755 index 0000000..7e92dd3 --- /dev/null +++ b/uc/systemschemas/v1/wire.go @@ -0,0 +1,90 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package systemschemas + +import ( + "fmt" +) + +type enableSystemSchemaRequestWire struct { + Schema *string `json:"schema,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` +} + +func enableSystemSchemaRequestToWire(v *EnableSystemSchemaRequest) (*enableSystemSchemaRequestWire, error) { + if v == nil { + return nil, nil + } + return &enableSystemSchemaRequestWire{ + Schema: v.Schema, + MetastoreId: v.MetastoreId, + CatalogName: v.CatalogName, + }, nil +} + +type listSystemSchemasRequestWire struct { + MetastoreId *string `json:"metastore_id,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listSystemSchemasRequestToWire(v *ListSystemSchemasRequest) (*listSystemSchemasRequestWire, error) { + if v == nil { + return nil, nil + } + return &listSystemSchemasRequestWire{ + MetastoreId: v.MetastoreId, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listSystemSchemasResponseWire struct { + Schemas []systemSchemaInfoWire `json:"schemas,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listSystemSchemasResponseFromWire(w *listSystemSchemasResponseWire) (*ListSystemSchemasResponse, error) { + if w == nil { + return nil, nil + } + schemasPublicValue, err := convertSlice(w.Schemas, systemSchemaInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListSystemSchemasResponse.Schemas", err) + } + return &ListSystemSchemasResponse{ + Schemas: schemasPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type systemSchemaInfoWire struct { + Schema *string `json:"schema,omitempty"` + State *string `json:"state,omitempty"` +} + +func systemSchemaInfoFromWire(w *systemSchemaInfoWire) (*SystemSchemaInfo, error) { + if w == nil { + return nil, nil + } + return &SystemSchemaInfo{ + Schema: w.Schema, + State: w.State, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/tables/.package.json b/uc/tables/.package.json new file mode 100644 index 0000000..51d9574 --- /dev/null +++ b/uc/tables/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/tables" +} diff --git a/uc/tables/CHANGELOG.md b/uc/tables/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/tables/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/tables/README.md b/uc/tables/README.md new file mode 100644 index 0000000..b2da7f3 --- /dev/null +++ b/uc/tables/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/tables + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/tables@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/tables/v1" + +client, err := tables.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/tables/go.mod b/uc/tables/go.mod new file mode 100644 index 0000000..52046c2 --- /dev/null +++ b/uc/tables/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/tables + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/tables/internal/version.go b/uc/tables/internal/version.go new file mode 100644 index 0000000..ee201a3 --- /dev/null +++ b/uc/tables/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-tables" + +const Version = "0.0.1-dev.1" diff --git a/uc/tables/v1/client.go b/uc/tables/v1/client.go new file mode 100755 index 0000000..ee9925f --- /dev/null +++ b/uc/tables/v1/client.go @@ -0,0 +1,869 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tables + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/tables/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new table in the specified catalog and schema. +// +// To create an external delta table, the caller must have the +// **EXTERNAL_USE_SCHEMA** privilege on the parent schema and the +// **EXTERNAL_USE_LOCATION** privilege on the external location. These +// privileges must always be granted explicitly, and cannot be inherited through +// ownership or **ALL_PRIVILEGES**. +// +// Standard UC permissions needed to create tables still apply: **USE_CATALOG** +// on the parent catalog (or ownership of the parent catalog), **CREATE_TABLE** +// and **USE_SCHEMA** on the parent schema (or ownership of the parent schema), +// and **CREATE_EXTERNAL_TABLE** on external location. +// +// The **columns** field needs to be in a Spark compatible format, so we +// recommend you use Spark to create these tables. The API itself does not +// validate the correctness of the column spec. If the spec is not Spark +// compatible, the tables may not be readable by Databricks Runtime. +// +// NOTE: The Create Table API for external clients only supports creating +// **external delta tables**. The values shown in the respective enums are all +// values supported by , however for this specific Create Table API, +// only **table_type** **EXTERNAL** and **data_source_format** **DELTA** are +// supported. Additionally, column masks are not supported when creating tables +// through this API. +func (c *internalClient) CreateTable(ctx context.Context, req *CreateTableRequest, opts ...call.Option) (*TableInfo, error) { + wireReq, err := createTableRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/tables" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TableInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp tableInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = tableInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new table constraint. +// +// For the table constraint creation to succeed, the user must satisfy both of +// these conditions: - the user must have the **USE_CATALOG** privilege on the +// table's parent catalog, the **USE_SCHEMA** privilege on the table's parent +// schema, and be the owner of the table. - if the new constraint is a +// __ForeignKeyConstraint__, the user must have the **USE_CATALOG** privilege on +// the referenced parent table's catalog, the **USE_SCHEMA** privilege on the +// referenced parent table's schema, and be the owner of the referenced parent +// table. +func (c *internalClient) CreateTableConstraint(ctx context.Context, req *CreateTableConstraintRequest, opts ...call.Option) (*TableConstraint, error) { + wireReq, err := createTableConstraintRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/constraints" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TableConstraint + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp tableConstraintWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = tableConstraintFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a table from the specified parent catalog and schema. The caller must +// be the owner of the parent catalog, have the **USE_CATALOG** privilege on the +// parent catalog and be the owner of the parent schema, or be the owner of the +// table and have the **USE_CATALOG** privilege on the parent catalog and the +// **USE_SCHEMA** privilege on the parent schema. +func (c *internalClient) DeleteTable(ctx context.Context, req *DeleteTableRequest, opts ...call.Option) (*DeleteTableResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/tables/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteTableResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteTableResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a table constraint. +// +// For the table constraint deletion to succeed, the user must satisfy both of +// these conditions: - the user must have the **USE_CATALOG** privilege on the +// table's parent catalog, the **USE_SCHEMA** privilege on the table's parent +// schema, and be the owner of the table. - if __cascade__ argument is **true**, +// the user must have the following permissions on all of the child tables: the +// **USE_CATALOG** privilege on the table's catalog, the **USE_SCHEMA** +// privilege on the table's schema, and be the owner of the table. +func (c *internalClient) DeleteTableConstraint(ctx context.Context, req *DeleteTableConstraintRequest, opts ...call.Option) (*DeleteTableConstraintResponse, error) { + wireReq, err := deleteTableConstraintRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/constraints/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "constraint_name", wireReq.ConstraintName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "cascade", wireReq.Cascade); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteTableConstraintResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteTableConstraintResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a table from the metastore for a specific catalog and schema. The caller +// must satisfy one of the following requirements: * Be a metastore admin * Be +// the owner of the parent catalog * Be the owner of the parent schema and have +// the **USE_CATALOG** privilege on the parent catalog * Have the +// **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** +// privilege on the parent schema, and either be the table owner or have the +// **SELECT** privilege on the table. +func (c *internalClient) GetTable(ctx context.Context, req *GetTableRequest, opts ...call.Option) (*TableInfo, error) { + wireReq, err := getTableRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/tables/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_delta_metadata", wireReq.IncludeDeltaMetadata); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_manifest_capabilities", wireReq.IncludeManifestCapabilities); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TableInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp tableInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = tableInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of summaries for tables for a schema and catalog within the +// metastore. The table summaries returned are either: +// +// * summaries for tables (within the current metastore and parent catalog and +// schema), when the user is a metastore admin, or: * summaries for tables and +// schemas (within the current metastore and parent catalog) for which the user +// has ownership or the **SELECT** privilege on the table and ownership or +// **USE_SCHEMA** privilege on the schema, provided that the user also has +// ownership or the **USE_CATALOG** privilege on the parent catalog. +// +// There is no guarantee of a specific ordering of the elements in the array. +// +// PAGINATION BEHAVIOR: The API is by default paginated, a page may contain zero +// results while still providing a next_page_token. Clients must continue +// reading pages until next_page_token is absent, which is the only indication +// that the end of results has been reached. +func (c *internalClient) ListTableSummaries(ctx context.Context, req *ListTableSummariesRequest, opts ...call.Option) (*ListTableSummariesResponse, error) { + wireReq, err := listTableSummariesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/table-summaries" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "catalog_name", wireReq.CatalogName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "schema_name_pattern", wireReq.SchemaNamePattern); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "table_name_pattern", wireReq.TableNamePattern); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_manifest_capabilities", wireReq.IncludeManifestCapabilities); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListTableSummariesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listTableSummariesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listTableSummariesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListTableSummariesIter returns an iterator that iterates +// over the results of ListTableSummaries. +// +// For example: +// +// for item, err := range c.ListTableSummariesIter(ctx, &ListTableSummariesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListTableSummaries call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListTableSummaries directly. +func (c *internalClient) ListTableSummariesIter(ctx context.Context, req *ListTableSummariesRequest, opts ...call.Option) iter.Seq2[*TableSummary, error] { + return func(yield func(*TableSummary, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListTableSummariesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListTableSummaries(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Tables { + if !yield(&resp.Tables[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Gets an array of all tables for the current metastore under the parent +// catalog and schema. The caller must be a metastore admin or an owner of (or +// have the **SELECT** privilege on) the table. For the latter case, the caller +// must also be the owner or have the **USE_CATALOG** privilege on the parent +// catalog and the **USE_SCHEMA** privilege on the parent schema. There is no +// guarantee of a specific ordering of the elements in the array. +// +// NOTE: **view_dependencies** and **table_constraints** are not returned by +// ListTables queries. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) ListTables(ctx context.Context, req *ListTablesRequest, opts ...call.Option) (*ListTablesResponse, error) { + wireReq, err := listTablesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/tables" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "catalog_name", wireReq.CatalogName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "schema_name", wireReq.SchemaName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "omit_columns", wireReq.OmitColumns); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "omit_properties", wireReq.OmitProperties); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "omit_username", wireReq.OmitUsername); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_manifest_capabilities", wireReq.IncludeManifestCapabilities); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListTablesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listTablesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listTablesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListTablesIter returns an iterator that iterates +// over the results of ListTables. +// +// For example: +// +// for item, err := range c.ListTablesIter(ctx, &ListTablesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListTables call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListTables directly. +func (c *internalClient) ListTablesIter(ctx context.Context, req *ListTablesRequest, opts ...call.Option) iter.Seq2[*TableInfo, error] { + return func(yield func(*TableInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListTablesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListTables(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Tables { + if !yield(&resp.Tables[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Gets if a table exists in the metastore for a specific catalog and schema. +// The caller must satisfy one of the following requirements: * Be a metastore +// admin * Be the owner of the parent catalog * Be the owner of the parent +// schema and have the **USE_CATALOG** privilege on the parent catalog * Have +// the **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** +// privilege on the parent schema, and either be the table owner or have the +// **SELECT** privilege on the table. * Have **BROWSE** privilege on the parent +// catalog * Have **BROWSE** privilege on the parent schema +func (c *internalClient) TableExists(ctx context.Context, req *TableExistsRequest, opts ...call.Option) (*TableExistsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/tables/") + pb.singleSegment(*req.FullNameArg) + pb.literal("/exists") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *TableExistsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp tableExistsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = tableExistsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Change the owner of the table. The caller must be the owner of the parent +// catalog, have the **USE_CATALOG** privilege on the parent catalog and be the +// owner of the parent schema, or be the owner of the table and have the +// **USE_CATALOG** privilege on the parent catalog and the **USE_SCHEMA** +// privilege on the parent schema. +func (c *internalClient) UpdateTable(ctx context.Context, req *UpdateTableRequest, opts ...call.Option) (*UpdateTableResponse, error) { + wireReq, err := updateTableRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/tables/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateTableResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &UpdateTableResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/tables/v1/genhelper.go b/uc/tables/v1/genhelper.go new file mode 100755 index 0000000..d1496c9 --- /dev/null +++ b/uc/tables/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tables + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/tables/v1/model.go b/uc/tables/v1/model.go new file mode 100755 index 0000000..5464bdd --- /dev/null +++ b/uc/tables/v1/model.go @@ -0,0 +1,913 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tables + +type ColumnTypeName string + +const ( + ColumnTypeName_Unspecified ColumnTypeName = "" + ColumnTypeName_Boolean ColumnTypeName = "BOOLEAN" + ColumnTypeName_Byte ColumnTypeName = "BYTE" + ColumnTypeName_Short ColumnTypeName = "SHORT" + ColumnTypeName_Int ColumnTypeName = "INT" + ColumnTypeName_Long ColumnTypeName = "LONG" + ColumnTypeName_Float ColumnTypeName = "FLOAT" + ColumnTypeName_Double ColumnTypeName = "DOUBLE" + ColumnTypeName_Date ColumnTypeName = "DATE" + ColumnTypeName_Timestamp ColumnTypeName = "TIMESTAMP" + ColumnTypeName_String ColumnTypeName = "STRING" + ColumnTypeName_Binary ColumnTypeName = "BINARY" + ColumnTypeName_Decimal ColumnTypeName = "DECIMAL" + ColumnTypeName_Interval ColumnTypeName = "INTERVAL" + ColumnTypeName_Array ColumnTypeName = "ARRAY" + ColumnTypeName_Struct ColumnTypeName = "STRUCT" + ColumnTypeName_Map ColumnTypeName = "MAP" + ColumnTypeName_Char ColumnTypeName = "CHAR" + ColumnTypeName_Null ColumnTypeName = "NULL" + ColumnTypeName_UserDefinedType ColumnTypeName = "USER_DEFINED_TYPE" + ColumnTypeName_TimestampNtz ColumnTypeName = "TIMESTAMP_NTZ" + ColumnTypeName_Variant ColumnTypeName = "VARIANT" + ColumnTypeName_Geometry ColumnTypeName = "GEOMETRY" + ColumnTypeName_Geography ColumnTypeName = "GEOGRAPHY" + ColumnTypeName_TableType ColumnTypeName = "TABLE_TYPE" +) + +// Data source format +type DataSourceFormat string + +const ( + DataSourceFormat_Unspecified DataSourceFormat = "" + DataSourceFormat_Delta DataSourceFormat = "DELTA" + DataSourceFormat_Csv DataSourceFormat = "CSV" + DataSourceFormat_Json DataSourceFormat = "JSON" + DataSourceFormat_Avro DataSourceFormat = "AVRO" + DataSourceFormat_Parquet DataSourceFormat = "PARQUET" + DataSourceFormat_Orc DataSourceFormat = "ORC" + DataSourceFormat_Text DataSourceFormat = "TEXT" + DataSourceFormat_UnityCatalog DataSourceFormat = "UNITY_CATALOG" + // A table shared through Delta Sharing protocol. + DataSourceFormat_Deltasharing DataSourceFormat = "DELTASHARING" + // BEGIN - Query federation data source formats. + DataSourceFormat_DatabricksFormat DataSourceFormat = "DATABRICKS_FORMAT" + DataSourceFormat_MysqlFormat DataSourceFormat = "MYSQL_FORMAT" + DataSourceFormat_OracleFormat DataSourceFormat = "ORACLE_FORMAT" + DataSourceFormat_PostgresqlFormat DataSourceFormat = "POSTGRESQL_FORMAT" + DataSourceFormat_RedshiftFormat DataSourceFormat = "REDSHIFT_FORMAT" + DataSourceFormat_SnowflakeFormat DataSourceFormat = "SNOWFLAKE_FORMAT" + DataSourceFormat_SqldwFormat DataSourceFormat = "SQLDW_FORMAT" + DataSourceFormat_SqlserverFormat DataSourceFormat = "SQLSERVER_FORMAT" + DataSourceFormat_SalesforceFormat DataSourceFormat = "SALESFORCE_FORMAT" + DataSourceFormat_SalesforceDataCloudFormat DataSourceFormat = "SALESFORCE_DATA_CLOUD_FORMAT" + DataSourceFormat_TeradataFormat DataSourceFormat = "TERADATA_FORMAT" + DataSourceFormat_BigqueryFormat DataSourceFormat = "BIGQUERY_FORMAT" + DataSourceFormat_NetsuiteFormat DataSourceFormat = "NETSUITE_FORMAT" + DataSourceFormat_WorkdayRaasFormat DataSourceFormat = "WORKDAY_RAAS_FORMAT" + DataSourceFormat_MongodbFormat DataSourceFormat = "MONGODB_FORMAT" + // datasource format used for hive tables. + DataSourceFormat_Hive DataSourceFormat = "HIVE" + // END - Query federation data source formats. Vector search managed index + // format + DataSourceFormat_VectorIndexFormat DataSourceFormat = "VECTOR_INDEX_FORMAT" + // Brickstore managed online row-oriented storage format. + DataSourceFormat_DatabricksRowStoreFormat DataSourceFormat = "DATABRICKS_ROW_STORE_FORMAT" + // Uniform storage format for Hudi + DataSourceFormat_DeltaUniformHudi DataSourceFormat = "DELTA_UNIFORM_HUDI" + // Uniform storage format for Iceberg + DataSourceFormat_DeltaUniformIceberg DataSourceFormat = "DELTA_UNIFORM_ICEBERG" + // Apache Iceberg DataFormat + DataSourceFormat_Iceberg DataSourceFormat = "ICEBERG" +) + +type SecurableKind string + +const ( + SecurableKind_Unspecified SecurableKind = "" + SecurableKind_TableStandard SecurableKind = "TABLE_STANDARD" + SecurableKind_TableExternal SecurableKind = "TABLE_EXTERNAL" + SecurableKind_TableDelta SecurableKind = "TABLE_DELTA" + SecurableKind_TableDeltaExternal SecurableKind = "TABLE_DELTA_EXTERNAL" + SecurableKind_TableView SecurableKind = "TABLE_VIEW" + SecurableKind_TableMetricView SecurableKind = "TABLE_METRIC_VIEW" + SecurableKind_TableDeltasharing SecurableKind = "TABLE_DELTASHARING" + SecurableKind_TableDeltasharingMutable SecurableKind = "TABLE_DELTASHARING_MUTABLE" + SecurableKind_TableViewDeltasharing SecurableKind = "TABLE_VIEW_DELTASHARING" + SecurableKind_TableMetricViewDeltasharing SecurableKind = "TABLE_METRIC_VIEW_DELTASHARING" + SecurableKind_TableMaterializedViewDeltasharing SecurableKind = "TABLE_MATERIALIZED_VIEW_DELTASHARING" + SecurableKind_TableStreamingLiveTableDeltasharing SecurableKind = "TABLE_STREAMING_LIVE_TABLE_DELTASHARING" + SecurableKind_TableForeignDeltasharing SecurableKind = "TABLE_FOREIGN_DELTASHARING" + SecurableKind_TableDeltaIcebergDeltasharing SecurableKind = "TABLE_DELTA_ICEBERG_DELTASHARING" + SecurableKind_TableDeltasharingOpenDirBased SecurableKind = "TABLE_DELTASHARING_OPEN_DIR_BASED" + // TABLE_FEATURE_STORE and TABLE_FEATURE_STORE_EXTERNAL are deprecated. + SecurableKind_TableFeatureStore SecurableKind = "TABLE_FEATURE_STORE" + SecurableKind_TableFeatureStoreExternal SecurableKind = "TABLE_FEATURE_STORE_EXTERNAL" + SecurableKind_TableStreamingLiveTable SecurableKind = "TABLE_STREAMING_LIVE_TABLE" + SecurableKind_TableSystem SecurableKind = "TABLE_SYSTEM" + SecurableKind_TableSystemDeltasharing SecurableKind = "TABLE_SYSTEM_DELTASHARING" + SecurableKind_TableMaterializedView SecurableKind = "TABLE_MATERIALIZED_VIEW" + SecurableKind_TableInternal SecurableKind = "TABLE_INTERNAL" + SecurableKind_TableForeignBigquery SecurableKind = "TABLE_FOREIGN_BIGQUERY" + SecurableKind_TableForeignMysql SecurableKind = "TABLE_FOREIGN_MYSQL" + SecurableKind_TableForeignOracle SecurableKind = "TABLE_FOREIGN_ORACLE" + SecurableKind_TableForeignPostgresql SecurableKind = "TABLE_FOREIGN_POSTGRESQL" + SecurableKind_TableForeignSqldw SecurableKind = "TABLE_FOREIGN_SQLDW" + SecurableKind_TableForeignRedshift SecurableKind = "TABLE_FOREIGN_REDSHIFT" + SecurableKind_TableForeignSnowflake SecurableKind = "TABLE_FOREIGN_SNOWFLAKE" + SecurableKind_TableForeignSqlserver SecurableKind = "TABLE_FOREIGN_SQLSERVER" + SecurableKind_TableForeignSalesforce SecurableKind = "TABLE_FOREIGN_SALESFORCE" + SecurableKind_TableForeignSalesforceDataCloud SecurableKind = "TABLE_FOREIGN_SALESFORCE_DATA_CLOUD" + SecurableKind_TableForeignSalesforceDataCloudFileSharing SecurableKind = "TABLE_FOREIGN_SALESFORCE_DATA_CLOUD_FILE_SHARING" + SecurableKind_TableForeignSalesforceDataCloudFileSharingView SecurableKind = "TABLE_FOREIGN_SALESFORCE_DATA_CLOUD_FILE_SHARING_VIEW" + SecurableKind_TableForeignTeradata SecurableKind = "TABLE_FOREIGN_TERADATA" + SecurableKind_TableForeignNetsuite SecurableKind = "TABLE_FOREIGN_NETSUITE" + SecurableKind_TableForeignDatabricks SecurableKind = "TABLE_FOREIGN_DATABRICKS" + SecurableKind_TableForeignWorkdayRaas SecurableKind = "TABLE_FOREIGN_WORKDAY_RAAS" + // Deprecated in favor of more specific types below + SecurableKind_TableForeignHiveMetastore SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE" + SecurableKind_TableForeignHiveMetastoreManaged SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE_MANAGED" + SecurableKind_TableForeignHiveMetastoreDbfsManaged SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE_DBFS_MANAGED" + SecurableKind_TableForeignHiveMetastoreExternal SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE_EXTERNAL" + SecurableKind_TableForeignHiveMetastoreDbfsExternal SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE_DBFS_EXTERNAL" + SecurableKind_TableForeignHiveMetastoreView SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE_VIEW" + SecurableKind_TableForeignHiveMetastoreDbfsView SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE_DBFS_VIEW" + SecurableKind_TableForeignHiveMetastoreShallowCloneManaged SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE_SHALLOW_CLONE_MANAGED" + SecurableKind_TableForeignHiveMetastoreDbfsShallowCloneManaged SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE_DBFS_SHALLOW_CLONE_MANAGED" + SecurableKind_TableForeignHiveMetastoreShallowCloneExternal SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE_SHALLOW_CLONE_EXTERNAL" + SecurableKind_TableForeignHiveMetastoreDbfsShallowCloneExternal SecurableKind = "TABLE_FOREIGN_HIVE_METASTORE_DBFS_SHALLOW_CLONE_EXTERNAL" + SecurableKind_TableForeignMongodb SecurableKind = "TABLE_FOREIGN_MONGODB" + SecurableKind_TableDeltaUniformHudiExternal SecurableKind = "TABLE_DELTA_UNIFORM_HUDI_EXTERNAL" + SecurableKind_TableDeltaUniformIcebergExternal SecurableKind = "TABLE_DELTA_UNIFORM_ICEBERG_EXTERNAL" + SecurableKind_TableDeltaUniformIcebergForeignHiveMetastoreExternal SecurableKind = "TABLE_DELTA_UNIFORM_ICEBERG_FOREIGN_HIVE_METASTORE_EXTERNAL" + SecurableKind_TableDeltaUniformIcebergForeignHiveMetastoreManaged SecurableKind = "TABLE_DELTA_UNIFORM_ICEBERG_FOREIGN_HIVE_METASTORE_MANAGED" + SecurableKind_TableDeltaUniformIcebergForeignSnowflake SecurableKind = "TABLE_DELTA_UNIFORM_ICEBERG_FOREIGN_SNOWFLAKE" + // The above uniform securableKinds come from different data sources, each + // creating a foreign catalog in Databricks with its own capabilities. UC uses + // these attributes to interact with remote connections. For shared foreign + // iceberg tables, all are under the Delta Sharing catalog with the same + // capabilities, so the recipient UC does not need to connect to the remote + // source. + SecurableKind_TableDeltaUniformIcebergForeignDeltasharing SecurableKind = "TABLE_DELTA_UNIFORM_ICEBERG_FOREIGN_DELTASHARING" + // This is the delta sharing version of TABLE_DELTA_UNIFORM_ICEBERG_EXTERNAL. + // Unlike the above foreign iceberg kinds which originate from external + // catalogs, this represents an external uniform iceberg table shared via Delta + // Sharing. + SecurableKind_TableDeltaUniformIcebergExternalDeltasharing SecurableKind = "TABLE_DELTA_UNIFORM_ICEBERG_EXTERNAL_DELTASHARING" + // These represent 2 variations of Managed Iceberg tables. See + // ManagedIcebergTableUtils.scala for more details. + SecurableKind_TableIcebergUniformManaged SecurableKind = "TABLE_ICEBERG_UNIFORM_MANAGED" + SecurableKind_TableDeltaIcebergManaged SecurableKind = "TABLE_DELTA_ICEBERG_MANAGED" + SecurableKind_TableOnlineVectorIndexReplica SecurableKind = "TABLE_ONLINE_VECTOR_INDEX_REPLICA" + SecurableKind_TableOnlineVectorIndexDirect SecurableKind = "TABLE_ONLINE_VECTOR_INDEX_DIRECT" + SecurableKind_TableOnlineView SecurableKind = "TABLE_ONLINE_VIEW" + SecurableKind_TableDbStorage SecurableKind = "TABLE_DB_STORAGE" + SecurableKind_TableManagedPostgresql SecurableKind = "TABLE_MANAGED_POSTGRESQL" +) + +// The type of Unity Catalog securable. +type SecurableType string + +const ( + SecurableType_Unspecified SecurableType = "" + SecurableType_Catalog SecurableType = "CATALOG" + SecurableType_Schema SecurableType = "SCHEMA" + SecurableType_Table SecurableType = "TABLE" + SecurableType_StorageCredential SecurableType = "STORAGE_CREDENTIAL" + SecurableType_ExternalLocation SecurableType = "EXTERNAL_LOCATION" + SecurableType_Function SecurableType = "FUNCTION" + SecurableType_Share SecurableType = "SHARE" + SecurableType_Provider SecurableType = "PROVIDER" + SecurableType_Recipient SecurableType = "RECIPIENT" + SecurableType_CleanRoom SecurableType = "CLEAN_ROOM" + SecurableType_Metastore SecurableType = "METASTORE" + SecurableType_Pipeline SecurableType = "PIPELINE" + SecurableType_Volume SecurableType = "VOLUME" + SecurableType_Connection SecurableType = "CONNECTION" + SecurableType_Credential SecurableType = "CREDENTIAL" + SecurableType_ExternalMetadata SecurableType = "EXTERNAL_METADATA" + // TODO: [UC-2980] Staging tables aren't full-fleged securables yet. + SecurableType_StagingTable SecurableType = "STAGING_TABLE" +) + +type SseEncryptionAlgorithm string + +const ( + SseEncryptionAlgorithm_Unspecified SseEncryptionAlgorithm = "" + SseEncryptionAlgorithm_AwsSseS3 SseEncryptionAlgorithm = "AWS_SSE_S3" + SseEncryptionAlgorithm_AwsSseKms SseEncryptionAlgorithm = "AWS_SSE_KMS" +) + +type TableType string + +const ( + TableType_Unspecified TableType = "" + TableType_Managed TableType = "MANAGED" + TableType_External TableType = "EXTERNAL" + TableType_View TableType = "VIEW" + TableType_MaterializedView TableType = "MATERIALIZED_VIEW" + TableType_StreamingTable TableType = "STREAMING_TABLE" + TableType_ManagedShallowClone TableType = "MANAGED_SHALLOW_CLONE" + TableType_Foreign TableType = "FOREIGN" + TableType_ExternalShallowClone TableType = "EXTERNAL_SHALLOW_CLONE" + TableType_MetricView TableType = "METRIC_VIEW" +) + +// During the OAuth flow, specifies which stage the option should be displayed +// in the UI. OAUTH_STAGE_UNSPECIFIED is the default value for options unrelated +// to the OAuth flow. BEFORE_AUTHORIZATION_CODE corresponds to options necessary +// to initiate the OAuth process. BEFORE_ACCESS_TOKEN corresponds to options +// that are necessary to create a foreign connection, but that should be +// displayed after the authorization code has already been received. +type OptionSpec_OauthStage string + +const ( + OptionSpec_OauthStage_Unspecified OptionSpec_OauthStage = "" + OptionSpec_OauthStage_BeforeAuthorizationCode OptionSpec_OauthStage = "BEFORE_AUTHORIZATION_CODE" + OptionSpec_OauthStage_BeforeAccessToken OptionSpec_OauthStage = "BEFORE_ACCESS_TOKEN" +) + +// Type of the option, we purposely follow JavaScript types so that the UI can +// map the options to JS types. https://www.w3schools.com/js/js_datatypes.asp +// Enum is a special case that it's just string with selections. +type OptionSpec_OptionType string + +const ( + OptionSpec_OptionType_Unspecified OptionSpec_OptionType = "" + OptionSpec_OptionType_OptionBoolean OptionSpec_OptionType = "OPTION_BOOLEAN" + OptionSpec_OptionType_OptionNumber OptionSpec_OptionType = "OPTION_NUMBER" + OptionSpec_OptionType_OptionBigint OptionSpec_OptionType = "OPTION_BIGINT" + OptionSpec_OptionType_OptionString OptionSpec_OptionType = "OPTION_STRING" + OptionSpec_OptionType_OptionEnum OptionSpec_OptionType = "OPTION_ENUM" + OptionSpec_OptionType_OptionServiceCredential OptionSpec_OptionType = "OPTION_SERVICE_CREDENTIAL" + OptionSpec_OptionType_OptionMultilineString OptionSpec_OptionType = "OPTION_MULTILINE_STRING" +) + +type ColumnInfo struct { + // Name of Column. + Name *string + // Full data type specification as SQL/catalogString text. + TypeText *string + TypeName ColumnTypeName + // Ordinal position of column (starting at position 0). + Position *int + // Digits of precision; required for DecimalTypes. + TypePrecision *int + // Digits to right of decimal; Required for DecimalTypes. + TypeScale *int + // Format of IntervalType. + TypeIntervalType *string + // Full data type specification, JSON-serialized. + TypeJson *string + // User-provided free-form text description. + Comment *string + // Whether field may be Null (default: true). + Nullable *bool + // Partition index for column. + PartitionIndex *int + Mask *ColumnMask +} + +type ColumnMask struct { + // The full name of the column mask SQL UDF. + FunctionName *string + // The list of additional table columns to be passed as input to the column mask + // function. The first arg of the mask function should be of the type of the + // column being masked and the types of the rest of the args should match the + // types of columns in 'using_column_names'. + UsingColumnNames []string + // The list of additional table columns or literals to be passed as additional + // arguments to a column mask function. This is the replacement of the + // deprecated using_column_names field and carries information about the types + // (alias or constant) of the arguments to the mask function. + UsingArguments []PolicyFunctionArgument +} + +// A connection that is dependent on a SQL object.. +type ConnectionDependency struct { + // Full name of the dependent connection, in the form of __connection_name__. + ConnectionName *string +} + +type CreateTableConstraintRequest struct { + // The full name of the table referenced by the constraint. + FullNameArg *string + Constraint *TableConstraint +} + +type CreateTableRequest struct { + // Name of table, relative to parent schema. + Name *string + // Name of parent catalog. + CatalogName *string + // Name of parent schema relative to its parent catalog. + SchemaName *string + TableType TableType + DataSourceFormat DataSourceFormat + // Storage root URL for table (for **MANAGED**, **EXTERNAL** tables). + StorageLocation *string + // View definition SQL (when __table_type__ is **VIEW**, **MATERIALIZED_VIEW**, + // or **STREAMING_TABLE**) + ViewDefinition *string + // View dependencies (when table_type == **VIEW** or **MATERIALIZED_VIEW**, + // **STREAMING_TABLE**) - when DependencyList is None, the dependency is not + // provided; - when DependencyList is an empty list, the dependency is provided + // but is empty; - when DependencyList is not an empty list, dependencies are + // provided and recorded. Note: this field is not set in the output of the + // __listTables__ API. + ViewDependencies *DependencyList + // List of schemes whose objects can be referenced without qualification. + SqlPath *string + // Username of current owner of table. + Owner *string + // User-provided free-form text description. + Comment *string + // Name of the storage credential, when a storage credential is configured for + // use with this table. + StorageCredentialName *string + // List of table constraints. Note: this field is not set in the output of the + // __listTables__ API. + TableConstraints []TableConstraint + RowFilter *RowFilter + // The pipeline ID of the table. Applicable for tables created by pipelines + // (Materialized View, Streaming Table, etc.). + PipelineId *string + EnablePredictiveOptimization *string + // Unique identifier of parent metastore. + MetastoreId *string + // Full name of table, in form of + // __catalog_name__.__schema_name__.__table_name__ + FullName *string + // Unique ID of the Data Access Configuration to use with the table data. + DataAccessConfigurationId *string + // Time at which this table was created, in epoch milliseconds. + CreatedAt *int64 + // Username of table creator. + CreatedBy *string + // Time at which this table was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the table. + UpdatedBy *string + // The unique identifier of the table. + TableId *string + // Information pertaining to current state of the delta table. + DeltaRuntimePropertiesKvpairs *DeltaRuntimePropertiesKvPairs + // Time at which this table was deleted, in epoch milliseconds. Field is omitted + // if table is not deleted. + DeletedAt *int64 + EffectivePredictiveOptimizationFlag *EffectivePredictiveOptimizationFlag + // The AWS access point to use when accesing s3 for this external location. + AccessPoint *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + EncryptionDetails *EncryptionDetails + // SecurableKindManifest of table, including capabilities the table has. + SecurableKindManifest *SecurableKindManifest + // The array of __ColumnInfo__ definitions of the table's columns. + Columns []ColumnInfo + // A map of key-value properties attached to the securable. + Properties map[string]string +} + +// A credential that is dependent on a SQL object.. +type CredentialDependency struct { + // Full name of the dependent credential, in the form of __credential_name__. + CredentialName *string +} + +type DeleteTableConstraintRequest struct { + // Full name of the table referenced by the constraint. + FullNameArg *string + // The name of the constraint to delete. + ConstraintName *string + // If true, try deleting all child constraints of the current constraint. If + // false, reject this operation if the current constraint has any child + // constraints. + Cascade *bool +} + +type DeleteTableConstraintResponse struct { +} + +type DeleteTableRequest struct { + // Full name of the table. + FullNameArg *string +} + +type DeleteTableResponse struct { +} + +// Properties pertaining to the current state of the delta table as given by the +// commit server. This does not contain **delta.*** (input) properties in +// __TableInfo.properties__.. +type DeltaRuntimePropertiesKvPairs struct { + // A map of key-value properties attached to the securable. + DeltaRuntimeProperties map[string]string +} + +// A dependency of a SQL object. One of the following fields must be defined: +// __table__, __function__, __connection__, __credential__, __volume__, or +// __secret__.. +type Dependency struct { + Value isDependency_Value +} + +type isDependency_Value interface { + isDependency_Value() +} + +// Dependency_Value_Table selects Table for Dependency.Value. +type Dependency_Value_Table struct { + Table TableDependency +} + +func (*Dependency_Value_Table) isDependency_Value() {} + +// Dependency_Value_Function selects Function for Dependency.Value. +type Dependency_Value_Function struct { + Function FunctionDependency +} + +func (*Dependency_Value_Function) isDependency_Value() {} + +// Dependency_Value_Connection selects Connection for Dependency.Value. +type Dependency_Value_Connection struct { + Connection ConnectionDependency +} + +func (*Dependency_Value_Connection) isDependency_Value() {} + +// Dependency_Value_Credential selects Credential for Dependency.Value. +type Dependency_Value_Credential struct { + Credential CredentialDependency +} + +func (*Dependency_Value_Credential) isDependency_Value() {} + +// A list of dependencies.. +type DependencyList struct { + // Array of dependencies. + Dependencies []Dependency +} + +type EffectivePredictiveOptimizationFlag struct { + // Whether predictive optimization should be enabled for this object and objects + // under it. + Value *string + // The type of the object from which the flag was inherited. If there was no + // inheritance, this field is left blank. + InheritedFromType *string + // The name of the object from which the flag was inherited. If there was no + // inheritance, this field is left blank. + InheritedFromName *string +} + +// Encryption options that apply to clients connecting to cloud storage.. +type EncryptionDetails struct { + EncryptionDetailsType isEncryptionDetails_EncryptionDetailsType +} + +type isEncryptionDetails_EncryptionDetailsType interface { + isEncryptionDetails_EncryptionDetailsType() +} + +// EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails selects SseEncryptionDetails for EncryptionDetails.EncryptionDetailsType. +// Server-Side Encryption properties for clients communicating with AWS s3. +type EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails struct { + SseEncryptionDetails SseEncryptionDetails +} + +func (*EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails) isEncryptionDetails_EncryptionDetailsType() { +} + +type ForeignKeyConstraint struct { + // The name of the constraint. + Name *string + // Column names for this constraint. + ChildColumns []string + // The full name of the parent constraint. + ParentTable *string + // Column names for this constraint. + ParentColumns []string + // True if the constraint is RELY, false or unset if NORELY. + Rely *bool +} + +// A function that is dependent on a SQL object.. +type FunctionDependency struct { + // Full name of the dependent function, in the form of + // __catalog_name__.__schema_name__.__function_name__. + FunctionFullName *string +} + +type GetTableRequest struct { + // Full name of the table. + FullNameArg *string + // Whether delta metadata should be included in the response. + IncludeDeltaMetadata *bool + // Whether to include tables in the response for which the principal can only + // access selective metadata for. + IncludeBrowse *bool + // Whether to include a manifest containing table capabilities in the response. + IncludeManifestCapabilities *bool +} + +type ListTableSummariesRequest struct { + // Name of parent catalog for tables of interest. + CatalogName *string + // A sql LIKE pattern (% and _) for schema names. All schemas will be returned + // if not set or empty. + SchemaNamePattern *string + // A sql LIKE pattern (% and _) for table names. All tables will be returned if + // not set or empty. + TableNamePattern *string + // Maximum number of summaries for tables to return. If not set, the page length + // is set to a server configured value (10000, as of 1/5/2024). - when set to a + // value greater than 0, the page length is the minimum of this value and a + // server configured value (10000, as of 1/5/2024); - when set to 0, the page + // length is set to a server configured value (10000, as of 1/5/2024) + // (recommended); - when set to a value less than 0, an invalid parameter error + // is returned; + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string + // Whether to include a manifest containing table capabilities in the response. + IncludeManifestCapabilities *bool +} + +type ListTableSummariesResponse struct { + // List of table summaries. + Tables []TableSummary + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type ListTablesRequest struct { + // Name of parent catalog for tables of interest. + CatalogName *string + // Parent schema of tables. + SchemaName *string + // Maximum number of tables to return. If not set, all the tables are returned + // (not recommended). - when set to a value greater than 0, the page length is + // the minimum of this value and a server configured value; - when set to 0, the + // page length is set to a server configured value (recommended); - when set to + // a value less than 0, an invalid parameter error is returned; + MaxResults *int + // Opaque token to send for the next page of results (pagination). + PageToken *string + // Whether to omit the columns of the table from the response or not. + OmitColumns *bool + // Whether to omit the properties of the table from the response or not. + OmitProperties *bool + // Whether to omit the username of the table (e.g. owner, updated_by, + // created_by) from the response or not. + OmitUsername *bool + // Whether to include tables in the response for which the principal can only + // access selective metadata for. + IncludeBrowse *bool + // Whether to include a manifest containing table capabilities in the response. + IncludeManifestCapabilities *bool +} + +type ListTablesResponse struct { + // An array of table information objects. + Tables []TableInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type NamedTableConstraint struct { + // The name of the constraint. + Name *string +} + +// Spec of an allowed option on a securable kind and its attributes. This is +// mostly used by UI to provide user friendly hints and descriptions in order to +// facilitate the securable creation process.. +type OptionSpec struct { + // The unique name of the option. + Name *string + // The type of the option. + Type OptionSpec_OptionType + // The default value of the option, for example, value '443' for 'port' option. + DefaultValue *string + // For drop down / radio button selections, UI will want to know the possible + // input values, it can also be used by other option types to limit input + // selections. + AllowedValues []string + // The hint is used on the UI to suggest what the input value can possibly be + // like, for example: example.com for 'host' option. Unlike default value, it + // will not be applied automatically without user input. + Hint *string + // A concise user facing description of what the input value of this option + // should look like. + Description *string + // Is the option required. + IsRequired *bool + // Is the option value considered secret and thus redacted on the UI. + IsSecret *bool + // Is the option value not user settable and is thus not shown on the UI. + IsHidden *bool + // Is the option updatable by users. + IsUpdatable *bool + // Specifies when the option value is displayed on the UI within the OAuth flow. + OauthStage OptionSpec_OauthStage + // Specifies whether this option is safe to log, i.e. no sensitive information. + IsLoggable *bool + // Indicates whether an option can be provided by users in the create/update + // path of an entity. + IsCreatable *bool + // Indicates whether an option should be displayed with copy button on the UI. + IsCopiable *bool +} + +// A positional argument passed to a row filter or column mask function. +// Distinguishes between column references and literals.. +type PolicyFunctionArgument struct { + Arg isPolicyFunctionArgument_Arg +} + +type isPolicyFunctionArgument_Arg interface { + isPolicyFunctionArgument_Arg() +} + +// PolicyFunctionArgument_Arg_Column selects Column for PolicyFunctionArgument.Arg. +// A column reference. +type PolicyFunctionArgument_Arg_Column struct { + Column string +} + +func (*PolicyFunctionArgument_Arg_Column) isPolicyFunctionArgument_Arg() {} + +// PolicyFunctionArgument_Arg_Constant selects Constant for PolicyFunctionArgument.Arg. +// A constant literal. +type PolicyFunctionArgument_Arg_Constant struct { + Constant string +} + +func (*PolicyFunctionArgument_Arg_Constant) isPolicyFunctionArgument_Arg() {} + +type PrimaryKeyConstraint struct { + // The name of the constraint. + Name *string + // Column names for this constraint. + ChildColumns []string + // Column names that represent a timeseries. + TimeseriesColumns []string + // True if the constraint is RELY, false or unset if NORELY. + Rely *bool +} + +type RowFilter struct { + // The full name of the row filter SQL UDF. + FunctionName *string + // The list of table columns to be passed as input to the row filter function. + // The column types should match the types of the filter function arguments. + InputColumnNames []string + // The list of additional table columns or literals to be passed as additional + // arguments to a row filter function. This is the replacement of the deprecated + // input_column_names field and carries information about the types (alias or + // constant) of the arguments to the filter function. + InputArguments []PolicyFunctionArgument +} + +// Manifest of a specific securable kind.. +type SecurableKindManifest struct { + // Securable Type of the kind. + SecurableType SecurableType + // Securable kind to get manifest of. + SecurableKind SecurableKind + // Privileges that can be assigned to the securable. + AssignablePrivileges []string + // Detailed specs of allowed options. + Options []OptionSpec + // A list of capabilities in the securable kind. + Capabilities []string +} + +// Server-Side Encryption properties for clients communicating with AWS s3.. +type SseEncryptionDetails struct { + // Sets the value of the 'x-amz-server-side-encryption' header in S3 request. + Algorithm SseEncryptionAlgorithm + // Optional. The ARN of the SSE-KMS key used with the S3 location, when + // algorithm = "SSE-KMS". Sets the value of the + // 'x-amz-server-side-encryption-aws-kms-key-id' header. + AwsKmsKeyArn *string +} + +// A table constraint, as defined by *one* of the following fields being set: +// __primary_key_constraint__, __foreign_key_constraint__, +// __named_table_constraint__.. +type TableConstraint struct { + Constraint isTableConstraint_Constraint +} + +type isTableConstraint_Constraint interface { + isTableConstraint_Constraint() +} + +// TableConstraint_Constraint_PrimaryKeyConstraint selects PrimaryKeyConstraint for TableConstraint.Constraint. +type TableConstraint_Constraint_PrimaryKeyConstraint struct { + PrimaryKeyConstraint PrimaryKeyConstraint +} + +func (*TableConstraint_Constraint_PrimaryKeyConstraint) isTableConstraint_Constraint() {} + +// TableConstraint_Constraint_ForeignKeyConstraint selects ForeignKeyConstraint for TableConstraint.Constraint. +type TableConstraint_Constraint_ForeignKeyConstraint struct { + ForeignKeyConstraint ForeignKeyConstraint +} + +func (*TableConstraint_Constraint_ForeignKeyConstraint) isTableConstraint_Constraint() {} + +// TableConstraint_Constraint_NamedTableConstraint selects NamedTableConstraint for TableConstraint.Constraint. +type TableConstraint_Constraint_NamedTableConstraint struct { + NamedTableConstraint NamedTableConstraint +} + +func (*TableConstraint_Constraint_NamedTableConstraint) isTableConstraint_Constraint() {} + +// A table that is dependent on a SQL object.. +type TableDependency struct { + // Full name of the dependent table, in the form of + // __catalog_name__.__schema_name__.__table_name__. + TableFullName *string +} + +type TableExistsRequest struct { + // Full name of the table. + FullNameArg *string +} + +type TableExistsResponse struct { + // Whether the table exists or not. + TableExists *bool +} + +type TableInfo struct { + // Name of table, relative to parent schema. + Name *string + // Name of parent catalog. + CatalogName *string + // Name of parent schema relative to its parent catalog. + SchemaName *string + TableType TableType + DataSourceFormat DataSourceFormat + // Storage root URL for table (for **MANAGED**, **EXTERNAL** tables). + StorageLocation *string + // View definition SQL (when __table_type__ is **VIEW**, **MATERIALIZED_VIEW**, + // or **STREAMING_TABLE**) + ViewDefinition *string + // View dependencies (when table_type == **VIEW** or **MATERIALIZED_VIEW**, + // **STREAMING_TABLE**) - when DependencyList is None, the dependency is not + // provided; - when DependencyList is an empty list, the dependency is provided + // but is empty; - when DependencyList is not an empty list, dependencies are + // provided and recorded. Note: this field is not set in the output of the + // __listTables__ API. + ViewDependencies *DependencyList + // List of schemes whose objects can be referenced without qualification. + SqlPath *string + // Username of current owner of table. + Owner *string + // User-provided free-form text description. + Comment *string + // Name of the storage credential, when a storage credential is configured for + // use with this table. + StorageCredentialName *string + // List of table constraints. Note: this field is not set in the output of the + // __listTables__ API. + TableConstraints []TableConstraint + RowFilter *RowFilter + // The pipeline ID of the table. Applicable for tables created by pipelines + // (Materialized View, Streaming Table, etc.). + PipelineId *string + EnablePredictiveOptimization *string + // Unique identifier of parent metastore. + MetastoreId *string + // Full name of table, in form of + // __catalog_name__.__schema_name__.__table_name__ + FullName *string + // Unique ID of the Data Access Configuration to use with the table data. + DataAccessConfigurationId *string + // Time at which this table was created, in epoch milliseconds. + CreatedAt *int64 + // Username of table creator. + CreatedBy *string + // Time at which this table was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the table. + UpdatedBy *string + // The unique identifier of the table. + TableId *string + // Information pertaining to current state of the delta table. + DeltaRuntimePropertiesKvpairs *DeltaRuntimePropertiesKvPairs + // Time at which this table was deleted, in epoch milliseconds. Field is omitted + // if table is not deleted. + DeletedAt *int64 + EffectivePredictiveOptimizationFlag *EffectivePredictiveOptimizationFlag + // The AWS access point to use when accesing s3 for this external location. + AccessPoint *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + EncryptionDetails *EncryptionDetails + // SecurableKindManifest of table, including capabilities the table has. + SecurableKindManifest *SecurableKindManifest + // The array of __ColumnInfo__ definitions of the table's columns. + Columns []ColumnInfo + // A map of key-value properties attached to the securable. + Properties map[string]string +} + +type TableSummary struct { + // The full name of the table. + FullName *string + TableType TableType + // SecurableKindManifest of table, including capabilities the table has. + SecurableKindManifest *SecurableKindManifest +} + +type UpdateTableRequest struct { + // Full name of the table. + FullNameArg *string + // Name of table, relative to parent schema. + Name *string + // Name of parent catalog. + CatalogName *string + // Name of parent schema relative to its parent catalog. + SchemaName *string + TableType TableType + DataSourceFormat DataSourceFormat + // Storage root URL for table (for **MANAGED**, **EXTERNAL** tables). + StorageLocation *string + // View definition SQL (when __table_type__ is **VIEW**, **MATERIALIZED_VIEW**, + // or **STREAMING_TABLE**) + ViewDefinition *string + // View dependencies (when table_type == **VIEW** or **MATERIALIZED_VIEW**, + // **STREAMING_TABLE**) - when DependencyList is None, the dependency is not + // provided; - when DependencyList is an empty list, the dependency is provided + // but is empty; - when DependencyList is not an empty list, dependencies are + // provided and recorded. Note: this field is not set in the output of the + // __listTables__ API. + ViewDependencies *DependencyList + // List of schemes whose objects can be referenced without qualification. + SqlPath *string + // Username of current owner of table. + Owner *string + // User-provided free-form text description. + Comment *string + // Name of the storage credential, when a storage credential is configured for + // use with this table. + StorageCredentialName *string + // List of table constraints. Note: this field is not set in the output of the + // __listTables__ API. + TableConstraints []TableConstraint + RowFilter *RowFilter + // The pipeline ID of the table. Applicable for tables created by pipelines + // (Materialized View, Streaming Table, etc.). + PipelineId *string + EnablePredictiveOptimization *string + // Unique identifier of parent metastore. + MetastoreId *string + // Full name of table, in form of + // __catalog_name__.__schema_name__.__table_name__ + FullName *string + // Unique ID of the Data Access Configuration to use with the table data. + DataAccessConfigurationId *string + // Time at which this table was created, in epoch milliseconds. + CreatedAt *int64 + // Username of table creator. + CreatedBy *string + // Time at which this table was last modified, in epoch milliseconds. + UpdatedAt *int64 + // Username of user who last modified the table. + UpdatedBy *string + // The unique identifier of the table. + TableId *string + // Information pertaining to current state of the delta table. + DeltaRuntimePropertiesKvpairs *DeltaRuntimePropertiesKvPairs + // Time at which this table was deleted, in epoch milliseconds. Field is omitted + // if table is not deleted. + DeletedAt *int64 + EffectivePredictiveOptimizationFlag *EffectivePredictiveOptimizationFlag + // The AWS access point to use when accesing s3 for this external location. + AccessPoint *string + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool + EncryptionDetails *EncryptionDetails + // SecurableKindManifest of table, including capabilities the table has. + SecurableKindManifest *SecurableKindManifest + // The array of __ColumnInfo__ definitions of the table's columns. + Columns []ColumnInfo + // A map of key-value properties attached to the securable. + Properties map[string]string +} + +type UpdateTableResponse struct { +} diff --git a/uc/tables/v1/wire.go b/uc/tables/v1/wire.go new file mode 100755 index 0000000..05ed2a2 --- /dev/null +++ b/uc/tables/v1/wire.go @@ -0,0 +1,1360 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package tables + +import ( + "fmt" +) + +type columnInfoWire struct { + Name *string `json:"name,omitempty"` + TypeText *string `json:"type_text,omitempty"` + TypeName ColumnTypeName `json:"type_name,omitempty"` + Position *int `json:"position,omitempty"` + TypePrecision *int `json:"type_precision,omitempty"` + TypeScale *int `json:"type_scale,omitempty"` + TypeIntervalType *string `json:"type_interval_type,omitempty"` + TypeJson *string `json:"type_json,omitempty"` + Comment *string `json:"comment,omitempty"` + Nullable *bool `json:"nullable,omitempty"` + PartitionIndex *int `json:"partition_index,omitempty"` + Mask *columnMaskWire `json:"mask,omitempty"` +} + +func columnInfoToWire(v *ColumnInfo) (*columnInfoWire, error) { + if v == nil { + return nil, nil + } + maskWireValue, err := columnMaskToWire(v.Mask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnInfo.Mask", err) + } + return &columnInfoWire{ + Name: v.Name, + TypeText: v.TypeText, + TypeName: v.TypeName, + Position: v.Position, + TypePrecision: v.TypePrecision, + TypeScale: v.TypeScale, + TypeIntervalType: v.TypeIntervalType, + TypeJson: v.TypeJson, + Comment: v.Comment, + Nullable: v.Nullable, + PartitionIndex: v.PartitionIndex, + Mask: maskWireValue, + }, nil +} + +func columnInfoFromWire(w *columnInfoWire) (*ColumnInfo, error) { + if w == nil { + return nil, nil + } + maskPublicValue, err := columnMaskFromWire(w.Mask) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnInfo.Mask", err) + } + return &ColumnInfo{ + Name: w.Name, + TypeText: w.TypeText, + TypeName: w.TypeName, + Position: w.Position, + TypePrecision: w.TypePrecision, + TypeScale: w.TypeScale, + TypeIntervalType: w.TypeIntervalType, + TypeJson: w.TypeJson, + Comment: w.Comment, + Nullable: w.Nullable, + PartitionIndex: w.PartitionIndex, + Mask: maskPublicValue, + }, nil +} + +type columnMaskWire struct { + FunctionName *string `json:"function_name,omitempty"` + UsingColumnNames []string `json:"using_column_names,omitempty"` + UsingArguments []policyFunctionArgumentWire `json:"using_arguments,omitempty"` +} + +func columnMaskToWire(v *ColumnMask) (*columnMaskWire, error) { + if v == nil { + return nil, nil + } + usingArgumentsWireValue, err := convertSlice(v.UsingArguments, policyFunctionArgumentToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnMask.UsingArguments", err) + } + return &columnMaskWire{ + FunctionName: v.FunctionName, + UsingColumnNames: v.UsingColumnNames, + UsingArguments: usingArgumentsWireValue, + }, nil +} + +func columnMaskFromWire(w *columnMaskWire) (*ColumnMask, error) { + if w == nil { + return nil, nil + } + usingArgumentsPublicValue, err := convertSlice(w.UsingArguments, policyFunctionArgumentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ColumnMask.UsingArguments", err) + } + return &ColumnMask{ + FunctionName: w.FunctionName, + UsingColumnNames: w.UsingColumnNames, + UsingArguments: usingArgumentsPublicValue, + }, nil +} + +type connectionDependencyWire struct { + ConnectionName *string `json:"connection_name,omitempty"` +} + +func connectionDependencyToWire(v *ConnectionDependency) (*connectionDependencyWire, error) { + if v == nil { + return nil, nil + } + return &connectionDependencyWire{ + ConnectionName: v.ConnectionName, + }, nil +} + +func connectionDependencyFromWire(w *connectionDependencyWire) (*ConnectionDependency, error) { + if w == nil { + return nil, nil + } + return &ConnectionDependency{ + ConnectionName: w.ConnectionName, + }, nil +} + +type createTableConstraintRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + Constraint *tableConstraintWire `json:"constraint,omitempty"` +} + +func createTableConstraintRequestToWire(v *CreateTableConstraintRequest) (*createTableConstraintRequestWire, error) { + if v == nil { + return nil, nil + } + constraintWireValue, err := tableConstraintToWire(v.Constraint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTableConstraintRequest.Constraint", err) + } + return &createTableConstraintRequestWire{ + FullNameArg: v.FullNameArg, + Constraint: constraintWireValue, + }, nil +} + +type createTableRequestWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + TableType TableType `json:"table_type,omitempty"` + DataSourceFormat DataSourceFormat `json:"data_source_format,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + ViewDefinition *string `json:"view_definition,omitempty"` + ViewDependencies *dependencyListWire `json:"view_dependencies,omitempty"` + SqlPath *string `json:"sql_path,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageCredentialName *string `json:"storage_credential_name,omitempty"` + TableConstraints []tableConstraintWire `json:"table_constraints,omitempty"` + RowFilter *rowFilterWire `json:"row_filter,omitempty"` + PipelineId *string `json:"pipeline_id,omitempty"` + EnablePredictiveOptimization *string `json:"enable_predictive_optimization,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + DataAccessConfigurationId *string `json:"data_access_configuration_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + TableId *string `json:"table_id,omitempty"` + DeltaRuntimePropertiesKvpairs *deltaRuntimePropertiesKvPairsWire `json:"delta_runtime_properties_kvpairs,omitempty"` + DeletedAt *int64 `json:"deleted_at,omitempty"` + EffectivePredictiveOptimizationFlag *effectivePredictiveOptimizationFlagWire `json:"effective_predictive_optimization_flag,omitempty"` + AccessPoint *string `json:"access_point,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + EncryptionDetails *encryptionDetailsWire `json:"encryption_details,omitempty"` + SecurableKindManifest *securableKindManifestWire `json:"securable_kind_manifest,omitempty"` + Columns []columnInfoWire `json:"columns,omitempty"` + Properties map[string]string `json:"properties,omitempty"` +} + +func createTableRequestToWire(v *CreateTableRequest) (*createTableRequestWire, error) { + if v == nil { + return nil, nil + } + viewDependenciesWireValue, err := dependencyListToWire(v.ViewDependencies) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTableRequest.ViewDependencies", err) + } + tableConstraintsWireValue, err := convertSlice(v.TableConstraints, tableConstraintToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTableRequest.TableConstraints", err) + } + rowFilterWireValue, err := rowFilterToWire(v.RowFilter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTableRequest.RowFilter", err) + } + deltaRuntimePropertiesKvpairsWireValue, err := deltaRuntimePropertiesKvPairsToWire(v.DeltaRuntimePropertiesKvpairs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTableRequest.DeltaRuntimePropertiesKvpairs", err) + } + effectivePredictiveOptimizationFlagWireValue, err := effectivePredictiveOptimizationFlagToWire(v.EffectivePredictiveOptimizationFlag) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTableRequest.EffectivePredictiveOptimizationFlag", err) + } + encryptionDetailsWireValue, err := encryptionDetailsToWire(v.EncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTableRequest.EncryptionDetails", err) + } + securableKindManifestWireValue, err := securableKindManifestToWire(v.SecurableKindManifest) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTableRequest.SecurableKindManifest", err) + } + columnsWireValue, err := convertSlice(v.Columns, columnInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateTableRequest.Columns", err) + } + return &createTableRequestWire{ + Name: v.Name, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + TableType: v.TableType, + DataSourceFormat: v.DataSourceFormat, + StorageLocation: v.StorageLocation, + ViewDefinition: v.ViewDefinition, + ViewDependencies: viewDependenciesWireValue, + SqlPath: v.SqlPath, + Owner: v.Owner, + Comment: v.Comment, + StorageCredentialName: v.StorageCredentialName, + TableConstraints: tableConstraintsWireValue, + RowFilter: rowFilterWireValue, + PipelineId: v.PipelineId, + EnablePredictiveOptimization: v.EnablePredictiveOptimization, + MetastoreId: v.MetastoreId, + FullName: v.FullName, + DataAccessConfigurationId: v.DataAccessConfigurationId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + TableId: v.TableId, + DeltaRuntimePropertiesKvpairs: deltaRuntimePropertiesKvpairsWireValue, + DeletedAt: v.DeletedAt, + EffectivePredictiveOptimizationFlag: effectivePredictiveOptimizationFlagWireValue, + AccessPoint: v.AccessPoint, + BrowseOnly: v.BrowseOnly, + EncryptionDetails: encryptionDetailsWireValue, + SecurableKindManifest: securableKindManifestWireValue, + Columns: columnsWireValue, + Properties: v.Properties, + }, nil +} + +type credentialDependencyWire struct { + CredentialName *string `json:"credential_name,omitempty"` +} + +func credentialDependencyToWire(v *CredentialDependency) (*credentialDependencyWire, error) { + if v == nil { + return nil, nil + } + return &credentialDependencyWire{ + CredentialName: v.CredentialName, + }, nil +} + +func credentialDependencyFromWire(w *credentialDependencyWire) (*CredentialDependency, error) { + if w == nil { + return nil, nil + } + return &CredentialDependency{ + CredentialName: w.CredentialName, + }, nil +} + +type deleteTableConstraintRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + ConstraintName *string `json:"constraint_name,omitempty"` + Cascade *bool `json:"cascade,omitempty"` +} + +func deleteTableConstraintRequestToWire(v *DeleteTableConstraintRequest) (*deleteTableConstraintRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteTableConstraintRequestWire{ + FullNameArg: v.FullNameArg, + ConstraintName: v.ConstraintName, + Cascade: v.Cascade, + }, nil +} + +type deltaRuntimePropertiesKvPairsWire struct { + DeltaRuntimeProperties map[string]string `json:"delta_runtime_properties,omitempty"` +} + +func deltaRuntimePropertiesKvPairsToWire(v *DeltaRuntimePropertiesKvPairs) (*deltaRuntimePropertiesKvPairsWire, error) { + if v == nil { + return nil, nil + } + return &deltaRuntimePropertiesKvPairsWire{ + DeltaRuntimeProperties: v.DeltaRuntimeProperties, + }, nil +} + +func deltaRuntimePropertiesKvPairsFromWire(w *deltaRuntimePropertiesKvPairsWire) (*DeltaRuntimePropertiesKvPairs, error) { + if w == nil { + return nil, nil + } + return &DeltaRuntimePropertiesKvPairs{ + DeltaRuntimeProperties: w.DeltaRuntimeProperties, + }, nil +} + +type dependencyWire struct { + Table *tableDependencyWire `json:"table,omitempty"` + Function *functionDependencyWire `json:"function,omitempty"` + Connection *connectionDependencyWire `json:"connection,omitempty"` + Credential *credentialDependencyWire `json:"credential,omitempty"` +} + +func dependencyToWire(v *Dependency) (*dependencyWire, error) { + if v == nil { + return nil, nil + } + var valueTableWire *tableDependencyWire + var valueFunctionWire *functionDependencyWire + var valueConnectionWire *connectionDependencyWire + var valueCredentialWire *credentialDependencyWire + switch value := v.Value.(type) { + case nil: + case *Dependency_Value_Table: + if value != nil { + valueTableConverted, err := tableDependencyToWire(&value.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Table", err) + } + valueTableWire = valueTableConverted + } + case *Dependency_Value_Function: + if value != nil { + valueFunctionConverted, err := functionDependencyToWire(&value.Function) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Function", err) + } + valueFunctionWire = valueFunctionConverted + } + case *Dependency_Value_Connection: + if value != nil { + valueConnectionConverted, err := connectionDependencyToWire(&value.Connection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Connection", err) + } + valueConnectionWire = valueConnectionConverted + } + case *Dependency_Value_Credential: + if value != nil { + valueCredentialConverted, err := credentialDependencyToWire(&value.Credential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Credential", err) + } + valueCredentialWire = valueCredentialConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Dependency.Value", value) + } + return &dependencyWire{ + Table: valueTableWire, + Function: valueFunctionWire, + Connection: valueConnectionWire, + Credential: valueCredentialWire, + }, nil +} + +func dependencyFromWire(w *dependencyWire) (*Dependency, error) { + if w == nil { + return nil, nil + } + valueMembers := 0 + if w.Table != nil { + valueMembers++ + } + if w.Function != nil { + valueMembers++ + } + if w.Connection != nil { + valueMembers++ + } + if w.Credential != nil { + valueMembers++ + } + if valueMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Dependency.Value") + } + var valueSelection isDependency_Value + switch { + case w.Table != nil: + valueTableConverted, err := tableDependencyFromWire(w.Table) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Table", err) + } + valueSelection = &Dependency_Value_Table{Table: *valueTableConverted} + case w.Function != nil: + valueFunctionConverted, err := functionDependencyFromWire(w.Function) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Function", err) + } + valueSelection = &Dependency_Value_Function{Function: *valueFunctionConverted} + case w.Connection != nil: + valueConnectionConverted, err := connectionDependencyFromWire(w.Connection) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Connection", err) + } + valueSelection = &Dependency_Value_Connection{Connection: *valueConnectionConverted} + case w.Credential != nil: + valueCredentialConverted, err := credentialDependencyFromWire(w.Credential) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Dependency.Value.Credential", err) + } + valueSelection = &Dependency_Value_Credential{Credential: *valueCredentialConverted} + } + return &Dependency{ + Value: valueSelection, + }, nil +} + +type dependencyListWire struct { + Dependencies []dependencyWire `json:"dependencies,omitempty"` +} + +func dependencyListToWire(v *DependencyList) (*dependencyListWire, error) { + if v == nil { + return nil, nil + } + dependenciesWireValue, err := convertSlice(v.Dependencies, dependencyToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DependencyList.Dependencies", err) + } + return &dependencyListWire{ + Dependencies: dependenciesWireValue, + }, nil +} + +func dependencyListFromWire(w *dependencyListWire) (*DependencyList, error) { + if w == nil { + return nil, nil + } + dependenciesPublicValue, err := convertSlice(w.Dependencies, dependencyFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DependencyList.Dependencies", err) + } + return &DependencyList{ + Dependencies: dependenciesPublicValue, + }, nil +} + +type effectivePredictiveOptimizationFlagWire struct { + Value *string `json:"value,omitempty"` + InheritedFromType *string `json:"inherited_from_type,omitempty"` + InheritedFromName *string `json:"inherited_from_name,omitempty"` +} + +func effectivePredictiveOptimizationFlagToWire(v *EffectivePredictiveOptimizationFlag) (*effectivePredictiveOptimizationFlagWire, error) { + if v == nil { + return nil, nil + } + return &effectivePredictiveOptimizationFlagWire{ + Value: v.Value, + InheritedFromType: v.InheritedFromType, + InheritedFromName: v.InheritedFromName, + }, nil +} + +func effectivePredictiveOptimizationFlagFromWire(w *effectivePredictiveOptimizationFlagWire) (*EffectivePredictiveOptimizationFlag, error) { + if w == nil { + return nil, nil + } + return &EffectivePredictiveOptimizationFlag{ + Value: w.Value, + InheritedFromType: w.InheritedFromType, + InheritedFromName: w.InheritedFromName, + }, nil +} + +type encryptionDetailsWire struct { + SseEncryptionDetails *sseEncryptionDetailsWire `json:"sse_encryption_details,omitempty"` +} + +func encryptionDetailsToWire(v *EncryptionDetails) (*encryptionDetailsWire, error) { + if v == nil { + return nil, nil + } + var encryptionDetailsTypeSseEncryptionDetailsWire *sseEncryptionDetailsWire + switch value := v.EncryptionDetailsType.(type) { + case nil: + case *EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails: + if value != nil { + encryptionDetailsTypeSseEncryptionDetailsConverted, err := sseEncryptionDetailsToWire(&value.SseEncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EncryptionDetails.EncryptionDetailsType.SseEncryptionDetails", err) + } + encryptionDetailsTypeSseEncryptionDetailsWire = encryptionDetailsTypeSseEncryptionDetailsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "EncryptionDetails.EncryptionDetailsType", value) + } + return &encryptionDetailsWire{ + SseEncryptionDetails: encryptionDetailsTypeSseEncryptionDetailsWire, + }, nil +} + +func encryptionDetailsFromWire(w *encryptionDetailsWire) (*EncryptionDetails, error) { + if w == nil { + return nil, nil + } + encryptionDetailsTypeMembers := 0 + if w.SseEncryptionDetails != nil { + encryptionDetailsTypeMembers++ + } + if encryptionDetailsTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "EncryptionDetails.EncryptionDetailsType") + } + var encryptionDetailsTypeSelection isEncryptionDetails_EncryptionDetailsType + switch { + case w.SseEncryptionDetails != nil: + encryptionDetailsTypeSseEncryptionDetailsConverted, err := sseEncryptionDetailsFromWire(w.SseEncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EncryptionDetails.EncryptionDetailsType.SseEncryptionDetails", err) + } + encryptionDetailsTypeSelection = &EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails{SseEncryptionDetails: *encryptionDetailsTypeSseEncryptionDetailsConverted} + } + return &EncryptionDetails{ + EncryptionDetailsType: encryptionDetailsTypeSelection, + }, nil +} + +type foreignKeyConstraintWire struct { + Name *string `json:"name,omitempty"` + ChildColumns []string `json:"child_columns,omitempty"` + ParentTable *string `json:"parent_table,omitempty"` + ParentColumns []string `json:"parent_columns,omitempty"` + Rely *bool `json:"rely,omitempty"` +} + +func foreignKeyConstraintToWire(v *ForeignKeyConstraint) (*foreignKeyConstraintWire, error) { + if v == nil { + return nil, nil + } + return &foreignKeyConstraintWire{ + Name: v.Name, + ChildColumns: v.ChildColumns, + ParentTable: v.ParentTable, + ParentColumns: v.ParentColumns, + Rely: v.Rely, + }, nil +} + +func foreignKeyConstraintFromWire(w *foreignKeyConstraintWire) (*ForeignKeyConstraint, error) { + if w == nil { + return nil, nil + } + return &ForeignKeyConstraint{ + Name: w.Name, + ChildColumns: w.ChildColumns, + ParentTable: w.ParentTable, + ParentColumns: w.ParentColumns, + Rely: w.Rely, + }, nil +} + +type functionDependencyWire struct { + FunctionFullName *string `json:"function_full_name,omitempty"` +} + +func functionDependencyToWire(v *FunctionDependency) (*functionDependencyWire, error) { + if v == nil { + return nil, nil + } + return &functionDependencyWire{ + FunctionFullName: v.FunctionFullName, + }, nil +} + +func functionDependencyFromWire(w *functionDependencyWire) (*FunctionDependency, error) { + if w == nil { + return nil, nil + } + return &FunctionDependency{ + FunctionFullName: w.FunctionFullName, + }, nil +} + +type getTableRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + IncludeDeltaMetadata *bool `json:"include_delta_metadata,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` + IncludeManifestCapabilities *bool `json:"include_manifest_capabilities,omitempty"` +} + +func getTableRequestToWire(v *GetTableRequest) (*getTableRequestWire, error) { + if v == nil { + return nil, nil + } + return &getTableRequestWire{ + FullNameArg: v.FullNameArg, + IncludeDeltaMetadata: v.IncludeDeltaMetadata, + IncludeBrowse: v.IncludeBrowse, + IncludeManifestCapabilities: v.IncludeManifestCapabilities, + }, nil +} + +type listTableSummariesRequestWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaNamePattern *string `json:"schema_name_pattern,omitempty"` + TableNamePattern *string `json:"table_name_pattern,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` + IncludeManifestCapabilities *bool `json:"include_manifest_capabilities,omitempty"` +} + +func listTableSummariesRequestToWire(v *ListTableSummariesRequest) (*listTableSummariesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listTableSummariesRequestWire{ + CatalogName: v.CatalogName, + SchemaNamePattern: v.SchemaNamePattern, + TableNamePattern: v.TableNamePattern, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + IncludeManifestCapabilities: v.IncludeManifestCapabilities, + }, nil +} + +type listTableSummariesResponseWire struct { + Tables []tableSummaryWire `json:"tables,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listTableSummariesResponseFromWire(w *listTableSummariesResponseWire) (*ListTableSummariesResponse, error) { + if w == nil { + return nil, nil + } + tablesPublicValue, err := convertSlice(w.Tables, tableSummaryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListTableSummariesResponse.Tables", err) + } + return &ListTableSummariesResponse{ + Tables: tablesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listTablesRequestWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` + OmitColumns *bool `json:"omit_columns,omitempty"` + OmitProperties *bool `json:"omit_properties,omitempty"` + OmitUsername *bool `json:"omit_username,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` + IncludeManifestCapabilities *bool `json:"include_manifest_capabilities,omitempty"` +} + +func listTablesRequestToWire(v *ListTablesRequest) (*listTablesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listTablesRequestWire{ + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + OmitColumns: v.OmitColumns, + OmitProperties: v.OmitProperties, + OmitUsername: v.OmitUsername, + IncludeBrowse: v.IncludeBrowse, + IncludeManifestCapabilities: v.IncludeManifestCapabilities, + }, nil +} + +type listTablesResponseWire struct { + Tables []tableInfoWire `json:"tables,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listTablesResponseFromWire(w *listTablesResponseWire) (*ListTablesResponse, error) { + if w == nil { + return nil, nil + } + tablesPublicValue, err := convertSlice(w.Tables, tableInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListTablesResponse.Tables", err) + } + return &ListTablesResponse{ + Tables: tablesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type namedTableConstraintWire struct { + Name *string `json:"name,omitempty"` +} + +func namedTableConstraintToWire(v *NamedTableConstraint) (*namedTableConstraintWire, error) { + if v == nil { + return nil, nil + } + return &namedTableConstraintWire{ + Name: v.Name, + }, nil +} + +func namedTableConstraintFromWire(w *namedTableConstraintWire) (*NamedTableConstraint, error) { + if w == nil { + return nil, nil + } + return &NamedTableConstraint{ + Name: w.Name, + }, nil +} + +type optionSpecWire struct { + Name *string `json:"name,omitempty"` + Type OptionSpec_OptionType `json:"type,omitempty"` + DefaultValue *string `json:"default_value,omitempty"` + AllowedValues []string `json:"allowed_values,omitempty"` + Hint *string `json:"hint,omitempty"` + Description *string `json:"description,omitempty"` + IsRequired *bool `json:"is_required,omitempty"` + IsSecret *bool `json:"is_secret,omitempty"` + IsHidden *bool `json:"is_hidden,omitempty"` + IsUpdatable *bool `json:"is_updatable,omitempty"` + OauthStage OptionSpec_OauthStage `json:"oauth_stage,omitempty"` + IsLoggable *bool `json:"is_loggable,omitempty"` + IsCreatable *bool `json:"is_creatable,omitempty"` + IsCopiable *bool `json:"is_copiable,omitempty"` +} + +func optionSpecToWire(v *OptionSpec) (*optionSpecWire, error) { + if v == nil { + return nil, nil + } + return &optionSpecWire{ + Name: v.Name, + Type: v.Type, + DefaultValue: v.DefaultValue, + AllowedValues: v.AllowedValues, + Hint: v.Hint, + Description: v.Description, + IsRequired: v.IsRequired, + IsSecret: v.IsSecret, + IsHidden: v.IsHidden, + IsUpdatable: v.IsUpdatable, + OauthStage: v.OauthStage, + IsLoggable: v.IsLoggable, + IsCreatable: v.IsCreatable, + IsCopiable: v.IsCopiable, + }, nil +} + +func optionSpecFromWire(w *optionSpecWire) (*OptionSpec, error) { + if w == nil { + return nil, nil + } + return &OptionSpec{ + Name: w.Name, + Type: w.Type, + DefaultValue: w.DefaultValue, + AllowedValues: w.AllowedValues, + Hint: w.Hint, + Description: w.Description, + IsRequired: w.IsRequired, + IsSecret: w.IsSecret, + IsHidden: w.IsHidden, + IsUpdatable: w.IsUpdatable, + OauthStage: w.OauthStage, + IsLoggable: w.IsLoggable, + IsCreatable: w.IsCreatable, + IsCopiable: w.IsCopiable, + }, nil +} + +type policyFunctionArgumentWire struct { + Column *string `json:"column,omitempty"` + Constant *string `json:"constant,omitempty"` +} + +func policyFunctionArgumentToWire(v *PolicyFunctionArgument) (*policyFunctionArgumentWire, error) { + if v == nil { + return nil, nil + } + var argColumnWire *string + var argConstantWire *string + switch value := v.Arg.(type) { + case nil: + case *PolicyFunctionArgument_Arg_Column: + if value != nil { + argColumnWire = new(value.Column) + } + case *PolicyFunctionArgument_Arg_Constant: + if value != nil { + argConstantWire = new(value.Constant) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "PolicyFunctionArgument.Arg", value) + } + return &policyFunctionArgumentWire{ + Column: argColumnWire, + Constant: argConstantWire, + }, nil +} + +func policyFunctionArgumentFromWire(w *policyFunctionArgumentWire) (*PolicyFunctionArgument, error) { + if w == nil { + return nil, nil + } + argMembers := 0 + if w.Column != nil { + argMembers++ + } + if w.Constant != nil { + argMembers++ + } + if argMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "PolicyFunctionArgument.Arg") + } + var argSelection isPolicyFunctionArgument_Arg + switch { + case w.Column != nil: + argSelection = &PolicyFunctionArgument_Arg_Column{Column: *w.Column} + case w.Constant != nil: + argSelection = &PolicyFunctionArgument_Arg_Constant{Constant: *w.Constant} + } + return &PolicyFunctionArgument{ + Arg: argSelection, + }, nil +} + +type primaryKeyConstraintWire struct { + Name *string `json:"name,omitempty"` + ChildColumns []string `json:"child_columns,omitempty"` + TimeseriesColumns []string `json:"timeseries_columns,omitempty"` + Rely *bool `json:"rely,omitempty"` +} + +func primaryKeyConstraintToWire(v *PrimaryKeyConstraint) (*primaryKeyConstraintWire, error) { + if v == nil { + return nil, nil + } + return &primaryKeyConstraintWire{ + Name: v.Name, + ChildColumns: v.ChildColumns, + TimeseriesColumns: v.TimeseriesColumns, + Rely: v.Rely, + }, nil +} + +func primaryKeyConstraintFromWire(w *primaryKeyConstraintWire) (*PrimaryKeyConstraint, error) { + if w == nil { + return nil, nil + } + return &PrimaryKeyConstraint{ + Name: w.Name, + ChildColumns: w.ChildColumns, + TimeseriesColumns: w.TimeseriesColumns, + Rely: w.Rely, + }, nil +} + +type rowFilterWire struct { + FunctionName *string `json:"function_name,omitempty"` + InputColumnNames []string `json:"input_column_names,omitempty"` + InputArguments []policyFunctionArgumentWire `json:"input_arguments,omitempty"` +} + +func rowFilterToWire(v *RowFilter) (*rowFilterWire, error) { + if v == nil { + return nil, nil + } + inputArgumentsWireValue, err := convertSlice(v.InputArguments, policyFunctionArgumentToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RowFilter.InputArguments", err) + } + return &rowFilterWire{ + FunctionName: v.FunctionName, + InputColumnNames: v.InputColumnNames, + InputArguments: inputArgumentsWireValue, + }, nil +} + +func rowFilterFromWire(w *rowFilterWire) (*RowFilter, error) { + if w == nil { + return nil, nil + } + inputArgumentsPublicValue, err := convertSlice(w.InputArguments, policyFunctionArgumentFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RowFilter.InputArguments", err) + } + return &RowFilter{ + FunctionName: w.FunctionName, + InputColumnNames: w.InputColumnNames, + InputArguments: inputArgumentsPublicValue, + }, nil +} + +type securableKindManifestWire struct { + SecurableType SecurableType `json:"securable_type,omitempty"` + SecurableKind SecurableKind `json:"securable_kind,omitempty"` + AssignablePrivileges []string `json:"assignable_privileges,omitempty"` + Options []optionSpecWire `json:"options,omitempty"` + Capabilities []string `json:"capabilities,omitempty"` +} + +func securableKindManifestToWire(v *SecurableKindManifest) (*securableKindManifestWire, error) { + if v == nil { + return nil, nil + } + optionsWireValue, err := convertSlice(v.Options, optionSpecToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SecurableKindManifest.Options", err) + } + return &securableKindManifestWire{ + SecurableType: v.SecurableType, + SecurableKind: v.SecurableKind, + AssignablePrivileges: v.AssignablePrivileges, + Options: optionsWireValue, + Capabilities: v.Capabilities, + }, nil +} + +func securableKindManifestFromWire(w *securableKindManifestWire) (*SecurableKindManifest, error) { + if w == nil { + return nil, nil + } + optionsPublicValue, err := convertSlice(w.Options, optionSpecFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SecurableKindManifest.Options", err) + } + return &SecurableKindManifest{ + SecurableType: w.SecurableType, + SecurableKind: w.SecurableKind, + AssignablePrivileges: w.AssignablePrivileges, + Options: optionsPublicValue, + Capabilities: w.Capabilities, + }, nil +} + +type sseEncryptionDetailsWire struct { + Algorithm SseEncryptionAlgorithm `json:"algorithm,omitempty"` + AwsKmsKeyArn *string `json:"aws_kms_key_arn,omitempty"` +} + +func sseEncryptionDetailsToWire(v *SseEncryptionDetails) (*sseEncryptionDetailsWire, error) { + if v == nil { + return nil, nil + } + return &sseEncryptionDetailsWire{ + Algorithm: v.Algorithm, + AwsKmsKeyArn: v.AwsKmsKeyArn, + }, nil +} + +func sseEncryptionDetailsFromWire(w *sseEncryptionDetailsWire) (*SseEncryptionDetails, error) { + if w == nil { + return nil, nil + } + return &SseEncryptionDetails{ + Algorithm: w.Algorithm, + AwsKmsKeyArn: w.AwsKmsKeyArn, + }, nil +} + +type tableConstraintWire struct { + PrimaryKeyConstraint *primaryKeyConstraintWire `json:"primary_key_constraint,omitempty"` + ForeignKeyConstraint *foreignKeyConstraintWire `json:"foreign_key_constraint,omitempty"` + NamedTableConstraint *namedTableConstraintWire `json:"named_table_constraint,omitempty"` +} + +func tableConstraintToWire(v *TableConstraint) (*tableConstraintWire, error) { + if v == nil { + return nil, nil + } + var constraintPrimaryKeyConstraintWire *primaryKeyConstraintWire + var constraintForeignKeyConstraintWire *foreignKeyConstraintWire + var constraintNamedTableConstraintWire *namedTableConstraintWire + switch value := v.Constraint.(type) { + case nil: + case *TableConstraint_Constraint_PrimaryKeyConstraint: + if value != nil { + constraintPrimaryKeyConstraintConverted, err := primaryKeyConstraintToWire(&value.PrimaryKeyConstraint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableConstraint.Constraint.PrimaryKeyConstraint", err) + } + constraintPrimaryKeyConstraintWire = constraintPrimaryKeyConstraintConverted + } + case *TableConstraint_Constraint_ForeignKeyConstraint: + if value != nil { + constraintForeignKeyConstraintConverted, err := foreignKeyConstraintToWire(&value.ForeignKeyConstraint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableConstraint.Constraint.ForeignKeyConstraint", err) + } + constraintForeignKeyConstraintWire = constraintForeignKeyConstraintConverted + } + case *TableConstraint_Constraint_NamedTableConstraint: + if value != nil { + constraintNamedTableConstraintConverted, err := namedTableConstraintToWire(&value.NamedTableConstraint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableConstraint.Constraint.NamedTableConstraint", err) + } + constraintNamedTableConstraintWire = constraintNamedTableConstraintConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "TableConstraint.Constraint", value) + } + return &tableConstraintWire{ + PrimaryKeyConstraint: constraintPrimaryKeyConstraintWire, + ForeignKeyConstraint: constraintForeignKeyConstraintWire, + NamedTableConstraint: constraintNamedTableConstraintWire, + }, nil +} + +func tableConstraintFromWire(w *tableConstraintWire) (*TableConstraint, error) { + if w == nil { + return nil, nil + } + constraintMembers := 0 + if w.PrimaryKeyConstraint != nil { + constraintMembers++ + } + if w.ForeignKeyConstraint != nil { + constraintMembers++ + } + if w.NamedTableConstraint != nil { + constraintMembers++ + } + if constraintMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "TableConstraint.Constraint") + } + var constraintSelection isTableConstraint_Constraint + switch { + case w.PrimaryKeyConstraint != nil: + constraintPrimaryKeyConstraintConverted, err := primaryKeyConstraintFromWire(w.PrimaryKeyConstraint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableConstraint.Constraint.PrimaryKeyConstraint", err) + } + constraintSelection = &TableConstraint_Constraint_PrimaryKeyConstraint{PrimaryKeyConstraint: *constraintPrimaryKeyConstraintConverted} + case w.ForeignKeyConstraint != nil: + constraintForeignKeyConstraintConverted, err := foreignKeyConstraintFromWire(w.ForeignKeyConstraint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableConstraint.Constraint.ForeignKeyConstraint", err) + } + constraintSelection = &TableConstraint_Constraint_ForeignKeyConstraint{ForeignKeyConstraint: *constraintForeignKeyConstraintConverted} + case w.NamedTableConstraint != nil: + constraintNamedTableConstraintConverted, err := namedTableConstraintFromWire(w.NamedTableConstraint) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableConstraint.Constraint.NamedTableConstraint", err) + } + constraintSelection = &TableConstraint_Constraint_NamedTableConstraint{NamedTableConstraint: *constraintNamedTableConstraintConverted} + } + return &TableConstraint{ + Constraint: constraintSelection, + }, nil +} + +type tableDependencyWire struct { + TableFullName *string `json:"table_full_name,omitempty"` +} + +func tableDependencyToWire(v *TableDependency) (*tableDependencyWire, error) { + if v == nil { + return nil, nil + } + return &tableDependencyWire{ + TableFullName: v.TableFullName, + }, nil +} + +func tableDependencyFromWire(w *tableDependencyWire) (*TableDependency, error) { + if w == nil { + return nil, nil + } + return &TableDependency{ + TableFullName: w.TableFullName, + }, nil +} + +type tableExistsResponseWire struct { + TableExists *bool `json:"table_exists,omitempty"` +} + +func tableExistsResponseFromWire(w *tableExistsResponseWire) (*TableExistsResponse, error) { + if w == nil { + return nil, nil + } + return &TableExistsResponse{ + TableExists: w.TableExists, + }, nil +} + +type tableInfoWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + TableType TableType `json:"table_type,omitempty"` + DataSourceFormat DataSourceFormat `json:"data_source_format,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + ViewDefinition *string `json:"view_definition,omitempty"` + ViewDependencies *dependencyListWire `json:"view_dependencies,omitempty"` + SqlPath *string `json:"sql_path,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageCredentialName *string `json:"storage_credential_name,omitempty"` + TableConstraints []tableConstraintWire `json:"table_constraints,omitempty"` + RowFilter *rowFilterWire `json:"row_filter,omitempty"` + PipelineId *string `json:"pipeline_id,omitempty"` + EnablePredictiveOptimization *string `json:"enable_predictive_optimization,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + DataAccessConfigurationId *string `json:"data_access_configuration_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + TableId *string `json:"table_id,omitempty"` + DeltaRuntimePropertiesKvpairs *deltaRuntimePropertiesKvPairsWire `json:"delta_runtime_properties_kvpairs,omitempty"` + DeletedAt *int64 `json:"deleted_at,omitempty"` + EffectivePredictiveOptimizationFlag *effectivePredictiveOptimizationFlagWire `json:"effective_predictive_optimization_flag,omitempty"` + AccessPoint *string `json:"access_point,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + EncryptionDetails *encryptionDetailsWire `json:"encryption_details,omitempty"` + SecurableKindManifest *securableKindManifestWire `json:"securable_kind_manifest,omitempty"` + Columns []columnInfoWire `json:"columns,omitempty"` + Properties map[string]string `json:"properties,omitempty"` +} + +func tableInfoFromWire(w *tableInfoWire) (*TableInfo, error) { + if w == nil { + return nil, nil + } + viewDependenciesPublicValue, err := dependencyListFromWire(w.ViewDependencies) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableInfo.ViewDependencies", err) + } + tableConstraintsPublicValue, err := convertSlice(w.TableConstraints, tableConstraintFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableInfo.TableConstraints", err) + } + rowFilterPublicValue, err := rowFilterFromWire(w.RowFilter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableInfo.RowFilter", err) + } + deltaRuntimePropertiesKvpairsPublicValue, err := deltaRuntimePropertiesKvPairsFromWire(w.DeltaRuntimePropertiesKvpairs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableInfo.DeltaRuntimePropertiesKvpairs", err) + } + effectivePredictiveOptimizationFlagPublicValue, err := effectivePredictiveOptimizationFlagFromWire(w.EffectivePredictiveOptimizationFlag) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableInfo.EffectivePredictiveOptimizationFlag", err) + } + encryptionDetailsPublicValue, err := encryptionDetailsFromWire(w.EncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableInfo.EncryptionDetails", err) + } + securableKindManifestPublicValue, err := securableKindManifestFromWire(w.SecurableKindManifest) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableInfo.SecurableKindManifest", err) + } + columnsPublicValue, err := convertSlice(w.Columns, columnInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableInfo.Columns", err) + } + return &TableInfo{ + Name: w.Name, + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + TableType: w.TableType, + DataSourceFormat: w.DataSourceFormat, + StorageLocation: w.StorageLocation, + ViewDefinition: w.ViewDefinition, + ViewDependencies: viewDependenciesPublicValue, + SqlPath: w.SqlPath, + Owner: w.Owner, + Comment: w.Comment, + StorageCredentialName: w.StorageCredentialName, + TableConstraints: tableConstraintsPublicValue, + RowFilter: rowFilterPublicValue, + PipelineId: w.PipelineId, + EnablePredictiveOptimization: w.EnablePredictiveOptimization, + MetastoreId: w.MetastoreId, + FullName: w.FullName, + DataAccessConfigurationId: w.DataAccessConfigurationId, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + TableId: w.TableId, + DeltaRuntimePropertiesKvpairs: deltaRuntimePropertiesKvpairsPublicValue, + DeletedAt: w.DeletedAt, + EffectivePredictiveOptimizationFlag: effectivePredictiveOptimizationFlagPublicValue, + AccessPoint: w.AccessPoint, + BrowseOnly: w.BrowseOnly, + EncryptionDetails: encryptionDetailsPublicValue, + SecurableKindManifest: securableKindManifestPublicValue, + Columns: columnsPublicValue, + Properties: w.Properties, + }, nil +} + +type tableSummaryWire struct { + FullName *string `json:"full_name,omitempty"` + TableType TableType `json:"table_type,omitempty"` + SecurableKindManifest *securableKindManifestWire `json:"securable_kind_manifest,omitempty"` +} + +func tableSummaryFromWire(w *tableSummaryWire) (*TableSummary, error) { + if w == nil { + return nil, nil + } + securableKindManifestPublicValue, err := securableKindManifestFromWire(w.SecurableKindManifest) + if err != nil { + return nil, fmt.Errorf("%s: %w", "TableSummary.SecurableKindManifest", err) + } + return &TableSummary{ + FullName: w.FullName, + TableType: w.TableType, + SecurableKindManifest: securableKindManifestPublicValue, + }, nil +} + +type updateTableRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + TableType TableType `json:"table_type,omitempty"` + DataSourceFormat DataSourceFormat `json:"data_source_format,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + ViewDefinition *string `json:"view_definition,omitempty"` + ViewDependencies *dependencyListWire `json:"view_dependencies,omitempty"` + SqlPath *string `json:"sql_path,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + StorageCredentialName *string `json:"storage_credential_name,omitempty"` + TableConstraints []tableConstraintWire `json:"table_constraints,omitempty"` + RowFilter *rowFilterWire `json:"row_filter,omitempty"` + PipelineId *string `json:"pipeline_id,omitempty"` + EnablePredictiveOptimization *string `json:"enable_predictive_optimization,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + FullName *string `json:"full_name,omitempty"` + DataAccessConfigurationId *string `json:"data_access_configuration_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + TableId *string `json:"table_id,omitempty"` + DeltaRuntimePropertiesKvpairs *deltaRuntimePropertiesKvPairsWire `json:"delta_runtime_properties_kvpairs,omitempty"` + DeletedAt *int64 `json:"deleted_at,omitempty"` + EffectivePredictiveOptimizationFlag *effectivePredictiveOptimizationFlagWire `json:"effective_predictive_optimization_flag,omitempty"` + AccessPoint *string `json:"access_point,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` + EncryptionDetails *encryptionDetailsWire `json:"encryption_details,omitempty"` + SecurableKindManifest *securableKindManifestWire `json:"securable_kind_manifest,omitempty"` + Columns []columnInfoWire `json:"columns,omitempty"` + Properties map[string]string `json:"properties,omitempty"` +} + +func updateTableRequestToWire(v *UpdateTableRequest) (*updateTableRequestWire, error) { + if v == nil { + return nil, nil + } + viewDependenciesWireValue, err := dependencyListToWire(v.ViewDependencies) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTableRequest.ViewDependencies", err) + } + tableConstraintsWireValue, err := convertSlice(v.TableConstraints, tableConstraintToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTableRequest.TableConstraints", err) + } + rowFilterWireValue, err := rowFilterToWire(v.RowFilter) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTableRequest.RowFilter", err) + } + deltaRuntimePropertiesKvpairsWireValue, err := deltaRuntimePropertiesKvPairsToWire(v.DeltaRuntimePropertiesKvpairs) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTableRequest.DeltaRuntimePropertiesKvpairs", err) + } + effectivePredictiveOptimizationFlagWireValue, err := effectivePredictiveOptimizationFlagToWire(v.EffectivePredictiveOptimizationFlag) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTableRequest.EffectivePredictiveOptimizationFlag", err) + } + encryptionDetailsWireValue, err := encryptionDetailsToWire(v.EncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTableRequest.EncryptionDetails", err) + } + securableKindManifestWireValue, err := securableKindManifestToWire(v.SecurableKindManifest) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTableRequest.SecurableKindManifest", err) + } + columnsWireValue, err := convertSlice(v.Columns, columnInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateTableRequest.Columns", err) + } + return &updateTableRequestWire{ + FullNameArg: v.FullNameArg, + Name: v.Name, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + TableType: v.TableType, + DataSourceFormat: v.DataSourceFormat, + StorageLocation: v.StorageLocation, + ViewDefinition: v.ViewDefinition, + ViewDependencies: viewDependenciesWireValue, + SqlPath: v.SqlPath, + Owner: v.Owner, + Comment: v.Comment, + StorageCredentialName: v.StorageCredentialName, + TableConstraints: tableConstraintsWireValue, + RowFilter: rowFilterWireValue, + PipelineId: v.PipelineId, + EnablePredictiveOptimization: v.EnablePredictiveOptimization, + MetastoreId: v.MetastoreId, + FullName: v.FullName, + DataAccessConfigurationId: v.DataAccessConfigurationId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + TableId: v.TableId, + DeltaRuntimePropertiesKvpairs: deltaRuntimePropertiesKvpairsWireValue, + DeletedAt: v.DeletedAt, + EffectivePredictiveOptimizationFlag: effectivePredictiveOptimizationFlagWireValue, + AccessPoint: v.AccessPoint, + BrowseOnly: v.BrowseOnly, + EncryptionDetails: encryptionDetailsWireValue, + SecurableKindManifest: securableKindManifestWireValue, + Columns: columnsWireValue, + Properties: v.Properties, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/volumes/.package.json b/uc/volumes/.package.json new file mode 100644 index 0000000..ac2270c --- /dev/null +++ b/uc/volumes/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/volumes" +} diff --git a/uc/volumes/CHANGELOG.md b/uc/volumes/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/volumes/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/volumes/README.md b/uc/volumes/README.md new file mode 100644 index 0000000..aa1c4e4 --- /dev/null +++ b/uc/volumes/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/volumes + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/volumes@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/volumes/v1" + +client, err := volumes.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/volumes/go.mod b/uc/volumes/go.mod new file mode 100644 index 0000000..a71ddb5 --- /dev/null +++ b/uc/volumes/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/volumes + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/volumes/internal/version.go b/uc/volumes/internal/version.go new file mode 100644 index 0000000..79f1552 --- /dev/null +++ b/uc/volumes/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-volumes" + +const Version = "0.0.1-dev.1" diff --git a/uc/volumes/v1/client.go b/uc/volumes/v1/client.go new file mode 100755 index 0000000..89333dc --- /dev/null +++ b/uc/volumes/v1/client.go @@ -0,0 +1,501 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package volumes + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/volumes/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new volume. +// +// The user could create either an external volume or a managed volume. An +// external volume will be created in the specified external location, while a +// managed volume will be located in the default location which is specified by +// the parent schema, or the parent catalog, or the Metastore. +// +// For the volume creation to succeed, the user must satisfy following +// conditions: - The caller must be a metastore admin, or be the owner of the +// parent catalog and schema, or have the **USE_CATALOG** privilege on the +// parent catalog and the **USE_SCHEMA** privilege on the parent schema. - The +// caller must have **CREATE VOLUME** privilege on the parent schema. +// +// For an external volume, following conditions also need to satisfy - The +// caller must have **CREATE EXTERNAL VOLUME** privilege on the external +// location. - There are no other tables, nor volumes existing in the specified +// storage location. - The specified storage location is not under the location +// of other tables, nor volumes, or catalogs or schemas. +func (c *internalClient) CreateVolume(ctx context.Context, req *CreateVolumeRequest, opts ...call.Option) (*VolumeInfo, error) { + wireReq, err := createVolumeRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/volumes" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *VolumeInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp volumeInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = volumeInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Deletes a volume from the specified parent catalog and schema. +// +// The caller must be a metastore admin or an owner of the volume. For the +// latter case, the caller must also be the owner or have the **USE_CATALOG** +// privilege on the parent catalog and the **USE_SCHEMA** privilege on the +// parent schema. +func (c *internalClient) DeleteVolume(ctx context.Context, req *DeleteVolumeRequest, opts ...call.Option) (*DeleteVolumeResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/volumes/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteVolumeResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteVolumeResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets a volume from the metastore for a specific catalog and schema. +// +// The caller must be a metastore admin or an owner of (or have the **READ +// VOLUME** privilege on) the volume. For the latter case, the caller must also +// be the owner or have the **USE_CATALOG** privilege on the parent catalog and +// the **USE_SCHEMA** privilege on the parent schema. +func (c *internalClient) GetVolume(ctx context.Context, req *GetVolumeRequest, opts ...call.Option) (*VolumeInfo, error) { + wireReq, err := getVolumeRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/volumes/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *VolumeInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp volumeInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = volumeInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets an array of volumes for the current metastore under the parent catalog +// and schema. +// +// The returned volumes are filtered based on the privileges of the calling +// user. For example, the metastore admin is able to list all the volumes. A +// regular user needs to be the owner or have the **READ VOLUME** privilege on +// the volume to receive the volumes in the response. For the latter case, the +// caller must also be the owner or have the **USE_CATALOG** privilege on the +// parent catalog and the **USE_SCHEMA** privilege on the parent schema. +// +// There is no guarantee of a specific ordering of the elements in the array. +// +// PAGINATION BEHAVIOR: The API is by default paginated, a page may contain zero +// results while still providing a next_page_token. Clients must continue +// reading pages until next_page_token is absent, which is the only indication +// that the end of results has been reached. +func (c *internalClient) ListVolumes(ctx context.Context, req *ListVolumesRequest, opts ...call.Option) (*ListVolumesResponse, error) { + wireReq, err := listVolumesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.1/unity-catalog/volumes" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "catalog_name", wireReq.CatalogName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "schema_name", wireReq.SchemaName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "include_browse", wireReq.IncludeBrowse); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListVolumesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listVolumesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listVolumesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListVolumesIter returns an iterator that iterates +// over the results of ListVolumes. +// +// For example: +// +// for item, err := range c.ListVolumesIter(ctx, &ListVolumesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListVolumes call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListVolumes directly. +func (c *internalClient) ListVolumesIter(ctx context.Context, req *ListVolumesRequest, opts ...call.Option) iter.Seq2[*VolumeInfo, error] { + return func(yield func(*VolumeInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListVolumesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListVolumes(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Volumes { + if !yield(&resp.Volumes[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates the specified volume under the specified parent catalog and schema. +// +// The caller must be a metastore admin or an owner of the volume. For the +// latter case, the caller must also be the owner or have the **USE_CATALOG** +// privilege on the parent catalog and the **USE_SCHEMA** privilege on the +// parent schema. +// +// Currently only the name, the owner or the comment of the volume could be +// updated. +func (c *internalClient) UpdateVolume(ctx context.Context, req *UpdateVolumeRequest, opts ...call.Option) (*VolumeInfo, error) { + wireReq, err := updateVolumeRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/volumes/") + pb.singleSegment(*req.FullNameArg) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *VolumeInfo + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp volumeInfoWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = volumeInfoFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/volumes/v1/genhelper.go b/uc/volumes/v1/genhelper.go new file mode 100755 index 0000000..9529a5e --- /dev/null +++ b/uc/volumes/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package volumes + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/volumes/v1/model.go b/uc/volumes/v1/model.go new file mode 100755 index 0000000..e8a0af5 --- /dev/null +++ b/uc/volumes/v1/model.go @@ -0,0 +1,224 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package volumes + +type SseEncryptionAlgorithm string + +const ( + SseEncryptionAlgorithm_Unspecified SseEncryptionAlgorithm = "" + SseEncryptionAlgorithm_AwsSseS3 SseEncryptionAlgorithm = "AWS_SSE_S3" + SseEncryptionAlgorithm_AwsSseKms SseEncryptionAlgorithm = "AWS_SSE_KMS" +) + +type VolumeType string + +const ( + VolumeType_Unspecified VolumeType = "" + VolumeType_Managed VolumeType = "MANAGED" + VolumeType_External VolumeType = "EXTERNAL" +) + +type CreateVolumeRequest struct { + // The name of the volume + Name *string + // The name of the catalog where the schema and the volume are + CatalogName *string + // The name of the schema where the volume is + SchemaName *string + // The type of the volume. An external volume is located in the specified + // external location. A managed volume is located in the default location which + // is specified by the parent schema, or the parent catalog, or the Metastore. + // [Learn more] + // + // [Learn more]: https://docs.databricks.com/aws/en/volumes/managed-vs-external + VolumeType VolumeType + // The storage location on the cloud + StorageLocation *string + // The identifier of the user who owns the volume + Owner *string + // The comment attached to the volume + Comment *string + // The three-level (fully qualified) name of the volume + FullName *string + // The unique identifier of the volume + VolumeId *string + // The unique identifier of the metastore + MetastoreId *string + CreatedAt *int64 + // The identifier of the user who created the volume + CreatedBy *string + UpdatedAt *int64 + // The identifier of the user who updated the volume last time + UpdatedBy *string + // The AWS access point to use when accesing s3 for this external location. + AccessPoint *string + EncryptionDetails *EncryptionDetails + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool +} + +type DeleteVolumeRequest struct { + // The three-level (fully qualified) name of the volume + FullNameArg *string +} + +type DeleteVolumeResponse struct { +} + +// Encryption options that apply to clients connecting to cloud storage.. +type EncryptionDetails struct { + EncryptionDetailsType isEncryptionDetails_EncryptionDetailsType +} + +type isEncryptionDetails_EncryptionDetailsType interface { + isEncryptionDetails_EncryptionDetailsType() +} + +// EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails selects SseEncryptionDetails for EncryptionDetails.EncryptionDetailsType. +// Server-Side Encryption properties for clients communicating with AWS s3. +type EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails struct { + SseEncryptionDetails SseEncryptionDetails +} + +func (*EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails) isEncryptionDetails_EncryptionDetailsType() { +} + +type GetVolumeRequest struct { + // The three-level (fully qualified) name of the volume + FullNameArg *string + // Whether to include volumes in the response for which the principal can only + // access selective metadata for + IncludeBrowse *bool +} + +type ListVolumesRequest struct { + // The identifier of the catalog + CatalogName *string + // The identifier of the schema + SchemaName *string + // Whether to include volumes in the response for which the principal can only + // access selective metadata for + IncludeBrowse *bool + // Maximum number of volumes to return (page length). + // + // If not set, the page length is set to a server configured value (10000, as of + // 1/29/2024). - when set to a value greater than 0, the page length is the + // minimum of this value and a server configured value (10000, as of 1/29/2024); + // - when set to 0, the page length is set to a server configured value (10000, + // as of 1/29/2024) (recommended); - when set to a value less than 0, an invalid + // parameter error is returned; + // + // Note: this parameter controls only the maximum number of volumes to return. + // The actual number of volumes returned in a page may be smaller than this + // value, including 0, even if there are more pages. + MaxResults *int + // Opaque token returned by a previous request. It must be included in the + // request to retrieve the next page of results (pagination). + PageToken *string +} + +type ListVolumesResponse struct { + Volumes []VolumeInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // to retrieve the next page of results. + NextPageToken *string +} + +// Server-Side Encryption properties for clients communicating with AWS s3.. +type SseEncryptionDetails struct { + // Sets the value of the 'x-amz-server-side-encryption' header in S3 request. + Algorithm SseEncryptionAlgorithm + // Optional. The ARN of the SSE-KMS key used with the S3 location, when + // algorithm = "SSE-KMS". Sets the value of the + // 'x-amz-server-side-encryption-aws-kms-key-id' header. + AwsKmsKeyArn *string +} + +type UpdateVolumeRequest struct { + // The three-level (fully qualified) name of the volume + FullNameArg *string + // New name for the volume. + NewName *string + // The name of the volume + Name *string + // The name of the catalog where the schema and the volume are + CatalogName *string + // The name of the schema where the volume is + SchemaName *string + // The type of the volume. An external volume is located in the specified + // external location. A managed volume is located in the default location which + // is specified by the parent schema, or the parent catalog, or the Metastore. + // [Learn more] + // + // [Learn more]: https://docs.databricks.com/aws/en/volumes/managed-vs-external + VolumeType VolumeType + // The storage location on the cloud + StorageLocation *string + // The identifier of the user who owns the volume + Owner *string + // The comment attached to the volume + Comment *string + // The three-level (fully qualified) name of the volume + FullName *string + // The unique identifier of the volume + VolumeId *string + // The unique identifier of the metastore + MetastoreId *string + CreatedAt *int64 + // The identifier of the user who created the volume + CreatedBy *string + UpdatedAt *int64 + // The identifier of the user who updated the volume last time + UpdatedBy *string + // The AWS access point to use when accesing s3 for this external location. + AccessPoint *string + EncryptionDetails *EncryptionDetails + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool +} + +type VolumeInfo struct { + // The name of the volume + Name *string + // The name of the catalog where the schema and the volume are + CatalogName *string + // The name of the schema where the volume is + SchemaName *string + // The type of the volume. An external volume is located in the specified + // external location. A managed volume is located in the default location which + // is specified by the parent schema, or the parent catalog, or the Metastore. + // [Learn more] + // + // [Learn more]: https://docs.databricks.com/aws/en/volumes/managed-vs-external + VolumeType VolumeType + // The storage location on the cloud + StorageLocation *string + // The identifier of the user who owns the volume + Owner *string + // The comment attached to the volume + Comment *string + // The three-level (fully qualified) name of the volume + FullName *string + // The unique identifier of the volume + VolumeId *string + // The unique identifier of the metastore + MetastoreId *string + CreatedAt *int64 + // The identifier of the user who created the volume + CreatedBy *string + UpdatedAt *int64 + // The identifier of the user who updated the volume last time + UpdatedBy *string + // The AWS access point to use when accesing s3 for this external location. + AccessPoint *string + EncryptionDetails *EncryptionDetails + // Indicates whether the principal is limited to retrieving metadata for the + // associated object through the BROWSE privilege when include_browse is enabled + // in the request. + BrowseOnly *bool +} diff --git a/uc/volumes/v1/wire.go b/uc/volumes/v1/wire.go new file mode 100755 index 0000000..8d12990 --- /dev/null +++ b/uc/volumes/v1/wire.go @@ -0,0 +1,305 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package volumes + +import ( + "fmt" +) + +type createVolumeRequestWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + VolumeType VolumeType `json:"volume_type,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + FullName *string `json:"full_name,omitempty"` + VolumeId *string `json:"volume_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + AccessPoint *string `json:"access_point,omitempty"` + EncryptionDetails *encryptionDetailsWire `json:"encryption_details,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` +} + +func createVolumeRequestToWire(v *CreateVolumeRequest) (*createVolumeRequestWire, error) { + if v == nil { + return nil, nil + } + encryptionDetailsWireValue, err := encryptionDetailsToWire(v.EncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateVolumeRequest.EncryptionDetails", err) + } + return &createVolumeRequestWire{ + Name: v.Name, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + VolumeType: v.VolumeType, + StorageLocation: v.StorageLocation, + Owner: v.Owner, + Comment: v.Comment, + FullName: v.FullName, + VolumeId: v.VolumeId, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + AccessPoint: v.AccessPoint, + EncryptionDetails: encryptionDetailsWireValue, + BrowseOnly: v.BrowseOnly, + }, nil +} + +type encryptionDetailsWire struct { + SseEncryptionDetails *sseEncryptionDetailsWire `json:"sse_encryption_details,omitempty"` +} + +func encryptionDetailsToWire(v *EncryptionDetails) (*encryptionDetailsWire, error) { + if v == nil { + return nil, nil + } + var encryptionDetailsTypeSseEncryptionDetailsWire *sseEncryptionDetailsWire + switch value := v.EncryptionDetailsType.(type) { + case nil: + case *EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails: + if value != nil { + encryptionDetailsTypeSseEncryptionDetailsConverted, err := sseEncryptionDetailsToWire(&value.SseEncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EncryptionDetails.EncryptionDetailsType.SseEncryptionDetails", err) + } + encryptionDetailsTypeSseEncryptionDetailsWire = encryptionDetailsTypeSseEncryptionDetailsConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "EncryptionDetails.EncryptionDetailsType", value) + } + return &encryptionDetailsWire{ + SseEncryptionDetails: encryptionDetailsTypeSseEncryptionDetailsWire, + }, nil +} + +func encryptionDetailsFromWire(w *encryptionDetailsWire) (*EncryptionDetails, error) { + if w == nil { + return nil, nil + } + encryptionDetailsTypeMembers := 0 + if w.SseEncryptionDetails != nil { + encryptionDetailsTypeMembers++ + } + if encryptionDetailsTypeMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "EncryptionDetails.EncryptionDetailsType") + } + var encryptionDetailsTypeSelection isEncryptionDetails_EncryptionDetailsType + switch { + case w.SseEncryptionDetails != nil: + encryptionDetailsTypeSseEncryptionDetailsConverted, err := sseEncryptionDetailsFromWire(w.SseEncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EncryptionDetails.EncryptionDetailsType.SseEncryptionDetails", err) + } + encryptionDetailsTypeSelection = &EncryptionDetails_EncryptionDetailsType_SseEncryptionDetails{SseEncryptionDetails: *encryptionDetailsTypeSseEncryptionDetailsConverted} + } + return &EncryptionDetails{ + EncryptionDetailsType: encryptionDetailsTypeSelection, + }, nil +} + +type getVolumeRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` +} + +func getVolumeRequestToWire(v *GetVolumeRequest) (*getVolumeRequestWire, error) { + if v == nil { + return nil, nil + } + return &getVolumeRequestWire{ + FullNameArg: v.FullNameArg, + IncludeBrowse: v.IncludeBrowse, + }, nil +} + +type listVolumesRequestWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + IncludeBrowse *bool `json:"include_browse,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listVolumesRequestToWire(v *ListVolumesRequest) (*listVolumesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listVolumesRequestWire{ + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + IncludeBrowse: v.IncludeBrowse, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type listVolumesResponseWire struct { + Volumes []volumeInfoWire `json:"volumes,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listVolumesResponseFromWire(w *listVolumesResponseWire) (*ListVolumesResponse, error) { + if w == nil { + return nil, nil + } + volumesPublicValue, err := convertSlice(w.Volumes, volumeInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListVolumesResponse.Volumes", err) + } + return &ListVolumesResponse{ + Volumes: volumesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type sseEncryptionDetailsWire struct { + Algorithm SseEncryptionAlgorithm `json:"algorithm,omitempty"` + AwsKmsKeyArn *string `json:"aws_kms_key_arn,omitempty"` +} + +func sseEncryptionDetailsToWire(v *SseEncryptionDetails) (*sseEncryptionDetailsWire, error) { + if v == nil { + return nil, nil + } + return &sseEncryptionDetailsWire{ + Algorithm: v.Algorithm, + AwsKmsKeyArn: v.AwsKmsKeyArn, + }, nil +} + +func sseEncryptionDetailsFromWire(w *sseEncryptionDetailsWire) (*SseEncryptionDetails, error) { + if w == nil { + return nil, nil + } + return &SseEncryptionDetails{ + Algorithm: w.Algorithm, + AwsKmsKeyArn: w.AwsKmsKeyArn, + }, nil +} + +type updateVolumeRequestWire struct { + FullNameArg *string `json:"full_name_arg,omitempty"` + NewName *string `json:"new_name,omitempty"` + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + VolumeType VolumeType `json:"volume_type,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + FullName *string `json:"full_name,omitempty"` + VolumeId *string `json:"volume_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + AccessPoint *string `json:"access_point,omitempty"` + EncryptionDetails *encryptionDetailsWire `json:"encryption_details,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` +} + +func updateVolumeRequestToWire(v *UpdateVolumeRequest) (*updateVolumeRequestWire, error) { + if v == nil { + return nil, nil + } + encryptionDetailsWireValue, err := encryptionDetailsToWire(v.EncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateVolumeRequest.EncryptionDetails", err) + } + return &updateVolumeRequestWire{ + FullNameArg: v.FullNameArg, + NewName: v.NewName, + Name: v.Name, + CatalogName: v.CatalogName, + SchemaName: v.SchemaName, + VolumeType: v.VolumeType, + StorageLocation: v.StorageLocation, + Owner: v.Owner, + Comment: v.Comment, + FullName: v.FullName, + VolumeId: v.VolumeId, + MetastoreId: v.MetastoreId, + CreatedAt: v.CreatedAt, + CreatedBy: v.CreatedBy, + UpdatedAt: v.UpdatedAt, + UpdatedBy: v.UpdatedBy, + AccessPoint: v.AccessPoint, + EncryptionDetails: encryptionDetailsWireValue, + BrowseOnly: v.BrowseOnly, + }, nil +} + +type volumeInfoWire struct { + Name *string `json:"name,omitempty"` + CatalogName *string `json:"catalog_name,omitempty"` + SchemaName *string `json:"schema_name,omitempty"` + VolumeType VolumeType `json:"volume_type,omitempty"` + StorageLocation *string `json:"storage_location,omitempty"` + Owner *string `json:"owner,omitempty"` + Comment *string `json:"comment,omitempty"` + FullName *string `json:"full_name,omitempty"` + VolumeId *string `json:"volume_id,omitempty"` + MetastoreId *string `json:"metastore_id,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + AccessPoint *string `json:"access_point,omitempty"` + EncryptionDetails *encryptionDetailsWire `json:"encryption_details,omitempty"` + BrowseOnly *bool `json:"browse_only,omitempty"` +} + +func volumeInfoFromWire(w *volumeInfoWire) (*VolumeInfo, error) { + if w == nil { + return nil, nil + } + encryptionDetailsPublicValue, err := encryptionDetailsFromWire(w.EncryptionDetails) + if err != nil { + return nil, fmt.Errorf("%s: %w", "VolumeInfo.EncryptionDetails", err) + } + return &VolumeInfo{ + Name: w.Name, + CatalogName: w.CatalogName, + SchemaName: w.SchemaName, + VolumeType: w.VolumeType, + StorageLocation: w.StorageLocation, + Owner: w.Owner, + Comment: w.Comment, + FullName: w.FullName, + VolumeId: w.VolumeId, + MetastoreId: w.MetastoreId, + CreatedAt: w.CreatedAt, + CreatedBy: w.CreatedBy, + UpdatedAt: w.UpdatedAt, + UpdatedBy: w.UpdatedBy, + AccessPoint: w.AccessPoint, + EncryptionDetails: encryptionDetailsPublicValue, + BrowseOnly: w.BrowseOnly, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/uc/workspacebindings/.package.json b/uc/workspacebindings/.package.json new file mode 100644 index 0000000..b13562c --- /dev/null +++ b/uc/workspacebindings/.package.json @@ -0,0 +1,3 @@ +{ + "package": "uc/workspacebindings" +} diff --git a/uc/workspacebindings/CHANGELOG.md b/uc/workspacebindings/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/uc/workspacebindings/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/uc/workspacebindings/README.md b/uc/workspacebindings/README.md new file mode 100644 index 0000000..7723991 --- /dev/null +++ b/uc/workspacebindings/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/uc/workspacebindings + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/uc/workspacebindings@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/uc/workspacebindings/v1" + +client, err := workspacebindings.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../../README.md). diff --git a/uc/workspacebindings/go.mod b/uc/workspacebindings/go.mod new file mode 100644 index 0000000..5b829fe --- /dev/null +++ b/uc/workspacebindings/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/uc/workspacebindings + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../../auth + +replace github.com/databricks/sdk-go/core => ../../core + +replace github.com/databricks/sdk-go/options => ../../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/uc/workspacebindings/internal/version.go b/uc/workspacebindings/internal/version.go new file mode 100644 index 0000000..23f2d8d --- /dev/null +++ b/uc/workspacebindings/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-uc-workspacebindings" + +const Version = "0.0.1-dev.1" diff --git a/uc/workspacebindings/v1/client.go b/uc/workspacebindings/v1/client.go new file mode 100755 index 0000000..1c0aa53 --- /dev/null +++ b/uc/workspacebindings/v1/client.go @@ -0,0 +1,403 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package workspacebindings + +import ( + "bytes" + "context" + "encoding/json" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/uc/workspacebindings/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Gets workspace bindings of the catalog. The caller must be a metastore admin +// or an owner of the catalog. +func (c *internalClient) GetCatalogWorkspaceBindings(ctx context.Context, req *GetCatalogWorkspaceBindingsRequest, opts ...call.Option) (*GetCatalogWorkspaceBindingsResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/workspace-bindings/catalogs/") + pb.singleSegment(*req.CatalogName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetCatalogWorkspaceBindingsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getCatalogWorkspaceBindingsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getCatalogWorkspaceBindingsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets workspace bindings of the securable. The caller must be a metastore +// admin or an owner of the securable. +// +// NOTE: we recommend using max_results=0 to use the paginated version of this +// API. Unpaginated calls will be deprecated soon. +// +// PAGINATION BEHAVIOR: When using pagination (max_results >= 0), a page may +// contain zero results while still providing a next_page_token. Clients must +// continue reading pages until next_page_token is absent, which is the only +// indication that the end of results has been reached. +func (c *internalClient) GetWorkspaceBindings(ctx context.Context, req *GetWorkspaceBindingsRequest, opts ...call.Option) (*GetWorkspaceBindingsResponse, error) { + wireReq, err := getWorkspaceBindingsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/bindings/") + pb.singleSegment(*req.SecurableType) + pb.literal("/") + pb.singleSegment(*req.SecurableFullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "max_results", wireReq.MaxResults); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetWorkspaceBindingsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getWorkspaceBindingsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getWorkspaceBindingsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// GetWorkspaceBindingsIter returns an iterator that iterates +// over the results of GetWorkspaceBindings. +// +// For example: +// +// for item, err := range c.GetWorkspaceBindingsIter(ctx, &GetWorkspaceBindingsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each GetWorkspaceBindings call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// GetWorkspaceBindings directly. +func (c *internalClient) GetWorkspaceBindingsIter(ctx context.Context, req *GetWorkspaceBindingsRequest, opts ...call.Option) iter.Seq2[*WorkspaceBindingInfo, error] { + return func(yield func(*WorkspaceBindingInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := GetWorkspaceBindingsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.GetWorkspaceBindings(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Bindings { + if !yield(&resp.Bindings[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Updates workspace bindings of the catalog. The caller must be a metastore +// admin or an owner of the catalog. +func (c *internalClient) UpdateCatalogWorkspaceBindings(ctx context.Context, req *UpdateCatalogWorkspaceBindingsRequest, opts ...call.Option) (*UpdateCatalogWorkspaceBindingsResponse, error) { + wireReq, err := updateCatalogWorkspaceBindingsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/workspace-bindings/catalogs/") + pb.singleSegment(*req.CatalogName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateCatalogWorkspaceBindingsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateCatalogWorkspaceBindingsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateCatalogWorkspaceBindingsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates workspace bindings of the securable. The caller must be a metastore +// admin or an owner of the securable. +func (c *internalClient) UpdateWorkspaceBindings(ctx context.Context, req *UpdateWorkspaceBindingsRequest, opts ...call.Option) (*UpdateWorkspaceBindingsResponse, error) { + wireReq, err := updateWorkspaceBindingsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.1/unity-catalog/bindings/") + pb.singleSegment(*req.SecurableType) + pb.literal("/") + pb.singleSegment(*req.SecurableFullName) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateWorkspaceBindingsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateWorkspaceBindingsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateWorkspaceBindingsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/uc/workspacebindings/v1/genhelper.go b/uc/workspacebindings/v1/genhelper.go new file mode 100755 index 0000000..0a7689b --- /dev/null +++ b/uc/workspacebindings/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package workspacebindings + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/uc/workspacebindings/v1/model.go b/uc/workspacebindings/v1/model.go new file mode 100755 index 0000000..965f69b --- /dev/null +++ b/uc/workspacebindings/v1/model.go @@ -0,0 +1,90 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package workspacebindings + +// Using `BINDING_TYPE_` prefix here to avoid conflict with `TableOperation` +// enum in `credentials_common.proto`. +type BindingType string + +const ( + BindingType_Unspecified BindingType = "" + BindingType_BindingTypeReadWrite BindingType = "BINDING_TYPE_READ_WRITE" + BindingType_BindingTypeReadOnly BindingType = "BINDING_TYPE_READ_ONLY" +) + +type GetCatalogWorkspaceBindingsRequest struct { + // The name of the catalog. + CatalogName *string +} + +type GetCatalogWorkspaceBindingsResponse struct { + // A list of workspace IDs + Workspaces []int64 +} + +type GetWorkspaceBindingsRequest struct { + // The type of the securable to bind to a workspace (catalog, + // storage_credential, credential, or external_location). + SecurableType *string + // The name of the securable. + SecurableFullName *string + // Maximum number of workspace bindings to return. - When set to 0, the page + // length is set to a server configured value (recommended); - When set to a + // value greater than 0, the page length is the minimum of this value and a + // server configured value; - When set to a value less than 0, an invalid + // parameter error is returned; - If not set, all the workspace bindings are + // returned (not recommended). + MaxResults *int + // Opaque pagination token to go to next page based on previous query. + PageToken *string +} + +type GetWorkspaceBindingsResponse struct { + // List of workspace bindings + Bindings []WorkspaceBindingInfo + // Opaque token to retrieve the next page of results. Absent if there are no + // more pages. __page_token__ should be set to this value for the next request + // (for the next page of results). + NextPageToken *string +} + +type UpdateCatalogWorkspaceBindingsRequest struct { + // The name of the catalog. + CatalogName *string + // A list of workspace IDs. + AssignWorkspaces []int64 + // A list of workspace IDs. + UnassignWorkspaces []int64 +} + +type UpdateCatalogWorkspaceBindingsResponse struct { + // A list of workspace IDs + Workspaces []int64 +} + +type UpdateWorkspaceBindingsRequest struct { + // The type of the securable to bind to a workspace (catalog, + // storage_credential, credential, or external_location). + SecurableType *string + // The name of the securable. + SecurableFullName *string + // List of workspace bindings to add. If a binding for the workspace already + // exists with a different binding_type, adding it again with a new binding_type + // will update the existing binding (e.g., from READ_WRITE to READ_ONLY). + Add []WorkspaceBindingInfo + // List of workspace bindings to remove. + Remove []WorkspaceBindingInfo +} + +// A list of workspace IDs that are bound to the securable. +type UpdateWorkspaceBindingsResponse struct { + // List of workspace bindings. + Bindings []WorkspaceBindingInfo +} + +type WorkspaceBindingInfo struct { + // Required + WorkspaceId *int64 + // One of READ_WRITE/READ_ONLY. Default is READ_WRITE. + BindingType BindingType +} diff --git a/uc/workspacebindings/v1/wire.go b/uc/workspacebindings/v1/wire.go new file mode 100755 index 0000000..362e5dd --- /dev/null +++ b/uc/workspacebindings/v1/wire.go @@ -0,0 +1,172 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package workspacebindings + +import ( + "fmt" +) + +type getCatalogWorkspaceBindingsResponseWire struct { + Workspaces []int64 `json:"workspaces,omitempty"` +} + +func getCatalogWorkspaceBindingsResponseFromWire(w *getCatalogWorkspaceBindingsResponseWire) (*GetCatalogWorkspaceBindingsResponse, error) { + if w == nil { + return nil, nil + } + return &GetCatalogWorkspaceBindingsResponse{ + Workspaces: w.Workspaces, + }, nil +} + +type getWorkspaceBindingsRequestWire struct { + SecurableType *string `json:"securable_type,omitempty"` + SecurableFullName *string `json:"securable_full_name,omitempty"` + MaxResults *int `json:"max_results,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func getWorkspaceBindingsRequestToWire(v *GetWorkspaceBindingsRequest) (*getWorkspaceBindingsRequestWire, error) { + if v == nil { + return nil, nil + } + return &getWorkspaceBindingsRequestWire{ + SecurableType: v.SecurableType, + SecurableFullName: v.SecurableFullName, + MaxResults: v.MaxResults, + PageToken: v.PageToken, + }, nil +} + +type getWorkspaceBindingsResponseWire struct { + Bindings []workspaceBindingInfoWire `json:"bindings,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func getWorkspaceBindingsResponseFromWire(w *getWorkspaceBindingsResponseWire) (*GetWorkspaceBindingsResponse, error) { + if w == nil { + return nil, nil + } + bindingsPublicValue, err := convertSlice(w.Bindings, workspaceBindingInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWorkspaceBindingsResponse.Bindings", err) + } + return &GetWorkspaceBindingsResponse{ + Bindings: bindingsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type updateCatalogWorkspaceBindingsRequestWire struct { + CatalogName *string `json:"catalog_name,omitempty"` + AssignWorkspaces []int64 `json:"assign_workspaces,omitempty"` + UnassignWorkspaces []int64 `json:"unassign_workspaces,omitempty"` +} + +func updateCatalogWorkspaceBindingsRequestToWire(v *UpdateCatalogWorkspaceBindingsRequest) (*updateCatalogWorkspaceBindingsRequestWire, error) { + if v == nil { + return nil, nil + } + return &updateCatalogWorkspaceBindingsRequestWire{ + CatalogName: v.CatalogName, + AssignWorkspaces: v.AssignWorkspaces, + UnassignWorkspaces: v.UnassignWorkspaces, + }, nil +} + +type updateCatalogWorkspaceBindingsResponseWire struct { + Workspaces []int64 `json:"workspaces,omitempty"` +} + +func updateCatalogWorkspaceBindingsResponseFromWire(w *updateCatalogWorkspaceBindingsResponseWire) (*UpdateCatalogWorkspaceBindingsResponse, error) { + if w == nil { + return nil, nil + } + return &UpdateCatalogWorkspaceBindingsResponse{ + Workspaces: w.Workspaces, + }, nil +} + +type updateWorkspaceBindingsRequestWire struct { + SecurableType *string `json:"securable_type,omitempty"` + SecurableFullName *string `json:"securable_full_name,omitempty"` + Add []workspaceBindingInfoWire `json:"add,omitempty"` + Remove []workspaceBindingInfoWire `json:"remove,omitempty"` +} + +func updateWorkspaceBindingsRequestToWire(v *UpdateWorkspaceBindingsRequest) (*updateWorkspaceBindingsRequestWire, error) { + if v == nil { + return nil, nil + } + addWireValue, err := convertSlice(v.Add, workspaceBindingInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateWorkspaceBindingsRequest.Add", err) + } + removeWireValue, err := convertSlice(v.Remove, workspaceBindingInfoToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateWorkspaceBindingsRequest.Remove", err) + } + return &updateWorkspaceBindingsRequestWire{ + SecurableType: v.SecurableType, + SecurableFullName: v.SecurableFullName, + Add: addWireValue, + Remove: removeWireValue, + }, nil +} + +type updateWorkspaceBindingsResponseWire struct { + Bindings []workspaceBindingInfoWire `json:"bindings,omitempty"` +} + +func updateWorkspaceBindingsResponseFromWire(w *updateWorkspaceBindingsResponseWire) (*UpdateWorkspaceBindingsResponse, error) { + if w == nil { + return nil, nil + } + bindingsPublicValue, err := convertSlice(w.Bindings, workspaceBindingInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateWorkspaceBindingsResponse.Bindings", err) + } + return &UpdateWorkspaceBindingsResponse{ + Bindings: bindingsPublicValue, + }, nil +} + +type workspaceBindingInfoWire struct { + WorkspaceId *int64 `json:"workspace_id,omitempty"` + BindingType BindingType `json:"binding_type,omitempty"` +} + +func workspaceBindingInfoToWire(v *WorkspaceBindingInfo) (*workspaceBindingInfoWire, error) { + if v == nil { + return nil, nil + } + return &workspaceBindingInfoWire{ + WorkspaceId: v.WorkspaceId, + BindingType: v.BindingType, + }, nil +} + +func workspaceBindingInfoFromWire(w *workspaceBindingInfoWire) (*WorkspaceBindingInfo, error) { + if w == nil { + return nil, nil + } + return &WorkspaceBindingInfo{ + WorkspaceId: w.WorkspaceId, + BindingType: w.BindingType, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/usagedashboards/.package.json b/usagedashboards/.package.json new file mode 100644 index 0000000..b2c02db --- /dev/null +++ b/usagedashboards/.package.json @@ -0,0 +1,3 @@ +{ + "package": "usagedashboards" +} diff --git a/usagedashboards/CHANGELOG.md b/usagedashboards/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/usagedashboards/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/usagedashboards/README.md b/usagedashboards/README.md new file mode 100644 index 0000000..31ce190 --- /dev/null +++ b/usagedashboards/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/usagedashboards + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/usagedashboards@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/usagedashboards/v1" + +client, err := usagedashboards.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/usagedashboards/go.mod b/usagedashboards/go.mod new file mode 100644 index 0000000..7780de1 --- /dev/null +++ b/usagedashboards/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/usagedashboards + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/usagedashboards/internal/version.go b/usagedashboards/internal/version.go new file mode 100644 index 0000000..d9f9448 --- /dev/null +++ b/usagedashboards/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-usagedashboards" + +const Version = "0.0.1-dev.1" diff --git a/usagedashboards/v1/client.go b/usagedashboards/v1/client.go new file mode 100755 index 0000000..cb1054f --- /dev/null +++ b/usagedashboards/v1/client.go @@ -0,0 +1,223 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package usagedashboards + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/usagedashboards/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a usage dashboard specified by workspaceId, accountId, and dashboard +// type. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) CreateBillingUsageDashboard(ctx context.Context, req *CreateBillingUsageDashboardRequest, opts ...call.Option) (*CreateBillingUsageDashboardResponse, error) { + wireReq, err := createBillingUsageDashboardRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/dashboard") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateBillingUsageDashboardResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createBillingUsageDashboardResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createBillingUsageDashboardResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get a usage dashboard specified by workspaceId, accountId, and dashboard +// type. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetBillingUsageDashboard(ctx context.Context, req *GetBillingUsageDashboardRequest, opts ...call.Option) (*GetBillingUsageDashboardResponse, error) { + wireReq, err := getBillingUsageDashboardRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/dashboard") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "workspace_id", wireReq.WorkspaceId); err != nil { + return nil, err + } + if wireReq.DashboardType != "" { + if err := addQueryValue(queryParams, "dashboard_type", wireReq.DashboardType); err != nil { + return nil, err + } + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetBillingUsageDashboardResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getBillingUsageDashboardResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getBillingUsageDashboardResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/usagedashboards/v1/genhelper.go b/usagedashboards/v1/genhelper.go new file mode 100755 index 0000000..036e82d --- /dev/null +++ b/usagedashboards/v1/genhelper.go @@ -0,0 +1,222 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package usagedashboards + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/usagedashboards/v1/model.go b/usagedashboards/v1/model.go new file mode 100755 index 0000000..76fbb33 --- /dev/null +++ b/usagedashboards/v1/model.go @@ -0,0 +1,56 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package usagedashboards + +type UsageDashboardMajorVersion string + +const ( + UsageDashboardMajorVersion_Unspecified UsageDashboardMajorVersion = "" + UsageDashboardMajorVersion_UsageDashboardMajorVersion1 UsageDashboardMajorVersion = "USAGE_DASHBOARD_MAJOR_VERSION_1" + UsageDashboardMajorVersion_UsageDashboardMajorVersion2 UsageDashboardMajorVersion = "USAGE_DASHBOARD_MAJOR_VERSION_2" +) + +type UsageDashboardType string + +const ( + UsageDashboardType_Unspecified UsageDashboardType = "" + UsageDashboardType_UsageDashboardTypeWorkspace UsageDashboardType = "USAGE_DASHBOARD_TYPE_WORKSPACE" + UsageDashboardType_UsageDashboardTypeGlobal UsageDashboardType = "USAGE_DASHBOARD_TYPE_GLOBAL" +) + +type CreateBillingUsageDashboardRequest struct { + // The workspace ID of the workspace in which the usage dashboard is created. + WorkspaceId *int64 + // account ID. + AccountId *string + // Workspace level usage dashboard shows usage data for the specified workspace + // ID. Global level usage dashboard shows usage data for all workspaces in the + // account. + DashboardType UsageDashboardType + // The major version of the usage dashboard template to use. Defaults to + // VERSION_1. + MajorVersion UsageDashboardMajorVersion +} + +type CreateBillingUsageDashboardResponse struct { + // The unique id of the usage dashboard. + DashboardId *string +} + +type GetBillingUsageDashboardRequest struct { + // The workspace ID of the workspace in which the usage dashboard is created. + WorkspaceId *int64 + // account ID. + AccountId *string + // Workspace level usage dashboard shows usage data for the specified workspace + // ID. Global level usage dashboard shows usage data for all workspaces in the + // account. + DashboardType UsageDashboardType +} + +type GetBillingUsageDashboardResponse struct { + // The unique id of the usage dashboard. + DashboardId *string + // The URL of the usage dashboard. + DashboardUrl *string +} diff --git a/usagedashboards/v1/wire.go b/usagedashboards/v1/wire.go new file mode 100755 index 0000000..9da6bca --- /dev/null +++ b/usagedashboards/v1/wire.go @@ -0,0 +1,67 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package usagedashboards + +type createBillingUsageDashboardRequestWire struct { + WorkspaceId *int64 `json:"workspace_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + DashboardType UsageDashboardType `json:"dashboard_type,omitempty"` + MajorVersion UsageDashboardMajorVersion `json:"major_version,omitempty"` +} + +func createBillingUsageDashboardRequestToWire(v *CreateBillingUsageDashboardRequest) (*createBillingUsageDashboardRequestWire, error) { + if v == nil { + return nil, nil + } + return &createBillingUsageDashboardRequestWire{ + WorkspaceId: v.WorkspaceId, + AccountId: v.AccountId, + DashboardType: v.DashboardType, + MajorVersion: v.MajorVersion, + }, nil +} + +type createBillingUsageDashboardResponseWire struct { + DashboardId *string `json:"dashboard_id,omitempty"` +} + +func createBillingUsageDashboardResponseFromWire(w *createBillingUsageDashboardResponseWire) (*CreateBillingUsageDashboardResponse, error) { + if w == nil { + return nil, nil + } + return &CreateBillingUsageDashboardResponse{ + DashboardId: w.DashboardId, + }, nil +} + +type getBillingUsageDashboardRequestWire struct { + WorkspaceId *int64 `json:"workspace_id,omitempty"` + AccountId *string `json:"account_id,omitempty"` + DashboardType UsageDashboardType `json:"dashboard_type,omitempty"` +} + +func getBillingUsageDashboardRequestToWire(v *GetBillingUsageDashboardRequest) (*getBillingUsageDashboardRequestWire, error) { + if v == nil { + return nil, nil + } + return &getBillingUsageDashboardRequestWire{ + WorkspaceId: v.WorkspaceId, + AccountId: v.AccountId, + DashboardType: v.DashboardType, + }, nil +} + +type getBillingUsageDashboardResponseWire struct { + DashboardId *string `json:"dashboard_id,omitempty"` + DashboardUrl *string `json:"dashboard_url,omitempty"` +} + +func getBillingUsageDashboardResponseFromWire(w *getBillingUsageDashboardResponseWire) (*GetBillingUsageDashboardResponse, error) { + if w == nil { + return nil, nil + } + return &GetBillingUsageDashboardResponse{ + DashboardId: w.DashboardId, + DashboardUrl: w.DashboardUrl, + }, nil +} diff --git a/vectorsearch/.package.json b/vectorsearch/.package.json new file mode 100644 index 0000000..fbfb7cd --- /dev/null +++ b/vectorsearch/.package.json @@ -0,0 +1,3 @@ +{ + "package": "vectorsearch" +} diff --git a/vectorsearch/CHANGELOG.md b/vectorsearch/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/vectorsearch/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/vectorsearch/README.md b/vectorsearch/README.md new file mode 100644 index 0000000..cfc6b1f --- /dev/null +++ b/vectorsearch/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/vectorsearch + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/vectorsearch@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/vectorsearch/v1" + +client, err := vectorsearch.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/vectorsearch/go.mod b/vectorsearch/go.mod new file mode 100644 index 0000000..46fd746 --- /dev/null +++ b/vectorsearch/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/vectorsearch + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/vectorsearch/internal/version.go b/vectorsearch/internal/version.go new file mode 100644 index 0000000..6e161cb --- /dev/null +++ b/vectorsearch/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-vectorsearch" + +const Version = "0.0.1-dev.1" diff --git a/vectorsearch/v1/client.go b/vectorsearch/v1/client.go new file mode 100755 index 0000000..30c7cd5 --- /dev/null +++ b/vectorsearch/v1/client.go @@ -0,0 +1,1443 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package vectorsearch + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" + "github.com/databricks/sdk-go/vectorsearch/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Create a new endpoint. +func (c *internalClient) createEndpointBase(ctx context.Context, req *CreateEndpointRequest, opts ...call.Option) (*Endpoint, error) { + wireReq, err := createEndpointRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/vector-search/endpoints" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Endpoint + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp endpointWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = endpointFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Create a new endpoint. +func (c *internalClient) CreateEndpoint(ctx context.Context, req *CreateEndpointRequest, opts ...call.Option) (*CreateEndpointWaiter, error) { + resp, err := c.createEndpointBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.Name == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "Name") + } + return &CreateEndpointWaiter{ + poll: c.GetEndpoint, + name: *resp.Name, + }, nil +} + +// CreateEndpointWaiter tracks the state of the operation started by CreateEndpoint. +type CreateEndpointWaiter struct { + poll func(context.Context, *GetEndpointRequest, ...call.Option) (*Endpoint, error) + name string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateEndpointWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetEndpointRequest{ + Name: &w.name, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + if pollResp.EndpointStatus == nil { + return false, fmt.Errorf("response field %q required for polling is missing", "EndpointStatus") + } + status := pollResp.EndpointStatus.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case EndpointStatus_State_Online, EndpointStatus_State_Offline: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateEndpointWaiter) Wait(ctx context.Context, opts ...lro.Option) (*Endpoint, error) { + var result *Endpoint + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetEndpointRequest{ + Name: &w.name, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + if pollResp.EndpointStatus == nil { + return fmt.Errorf("response field %q required for polling is missing", "EndpointStatus") + } + status := pollResp.EndpointStatus.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case EndpointStatus_State_Online: + result = pollResp + return nil + case EndpointStatus_State_Offline: + message := "(no message)" + if pollResp.EndpointStatus != nil && pollResp.EndpointStatus.Message != nil { + message = fmt.Sprintf("%v", *pollResp.EndpointStatus.Message) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Create a new index. +func (c *internalClient) CreateVectorIndex(ctx context.Context, req *CreateVectorIndexRequest, opts ...call.Option) (*VectorIndex, error) { + wireReq, err := createVectorIndexRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/vector-search/indexes" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *VectorIndex + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp vectorIndexWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = vectorIndexFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Handles the deletion of data from a specified vector index. +func (c *internalClient) DeleteDataVectorIndex(ctx context.Context, req *DeleteDataVectorIndexRequest, opts ...call.Option) (*DeleteDataVectorIndexResponse, error) { + wireReq, err := deleteDataVectorIndexRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/indexes/") + pb.singleSegment(*req.Name) + pb.literal("/delete-data") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "primary_keys", wireReq.PrimaryKeys); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteDataVectorIndexResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp deleteDataVectorIndexResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = deleteDataVectorIndexResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete an AI Search endpoint. +func (c *internalClient) DeleteEndpoint(ctx context.Context, req *DeleteEndpointRequest, opts ...call.Option) (*DeleteEndpointResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/endpoints/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteEndpointResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteEndpointResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Delete an index. +func (c *internalClient) DeleteVectorIndex(ctx context.Context, req *DeleteVectorIndexRequest, opts ...call.Option) (*DeleteVectorIndexResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/indexes/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteVectorIndexResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteVectorIndexResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get details for a single AI Search endpoint. +func (c *internalClient) GetEndpoint(ctx context.Context, req *GetEndpointRequest, opts ...call.Option) (*Endpoint, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/endpoints/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Endpoint + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp endpointWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = endpointFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Get an index. +func (c *internalClient) GetVectorIndex(ctx context.Context, req *GetVectorIndexRequest, opts ...call.Option) (*VectorIndex, error) { + wireReq, err := getVectorIndexRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/indexes/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "ensure_reranker_compatible", wireReq.EnsureRerankerCompatible); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *VectorIndex + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp vectorIndexWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = vectorIndexFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// List all AI Search endpoints in the workspace. +func (c *internalClient) ListEndpoints(ctx context.Context, req *ListEndpointsRequest, opts ...call.Option) (*ListEndpointResponse, error) { + wireReq, err := listEndpointsRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/vector-search/endpoints" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListEndpointResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listEndpointResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listEndpointResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListEndpointsIter returns an iterator that iterates +// over the results of ListEndpoints. +// +// For example: +// +// for item, err := range c.ListEndpointsIter(ctx, &ListEndpointsRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListEndpoints call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListEndpoints directly. +func (c *internalClient) ListEndpointsIter(ctx context.Context, req *ListEndpointsRequest, opts ...call.Option) iter.Seq2[*Endpoint, error] { + return func(yield func(*Endpoint, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListEndpointsRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListEndpoints(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Endpoints { + if !yield(&resp.Endpoints[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// List all indexes in the given endpoint. +func (c *internalClient) ListVectorIndex(ctx context.Context, req *ListVectorIndexRequest, opts ...call.Option) (*ListVectorIndexResponse, error) { + wireReq, err := listVectorIndexRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/vector-search/indexes" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "endpoint_name", wireReq.EndpointName); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListVectorIndexResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listVectorIndexResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listVectorIndexResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListVectorIndexIter returns an iterator that iterates +// over the results of ListVectorIndex. +// +// For example: +// +// for item, err := range c.ListVectorIndexIter(ctx, &ListVectorIndexRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListVectorIndex call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListVectorIndex directly. +func (c *internalClient) ListVectorIndexIter(ctx context.Context, req *ListVectorIndexRequest, opts ...call.Option) iter.Seq2[*MiniVectorIndex, error] { + return func(yield func(*MiniVectorIndex, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListVectorIndexRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListVectorIndex(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.VectorIndexes { + if !yield(&resp.VectorIndexes[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Update an endpoint +func (c *internalClient) PatchEndpoint(ctx context.Context, req *PatchEndpointRequest, opts ...call.Option) (*Endpoint, error) { + wireReq, err := patchEndpointRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/endpoints/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Endpoint + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp endpointWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = endpointFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update the budget policy of an endpoint +func (c *internalClient) PatchEndpointBudgetPolicy(ctx context.Context, req *PatchEndpointBudgetPolicyRequest, opts ...call.Option) (*PatchEndpointBudgetPolicyResponse, error) { + wireReq, err := patchEndpointBudgetPolicyRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/budget-policy") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *PatchEndpointBudgetPolicyResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp patchEndpointBudgetPolicyResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = patchEndpointBudgetPolicyResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Query the specified vector index. +func (c *internalClient) QueryVectorIndex(ctx context.Context, req *QueryVectorIndexRequest, opts ...call.Option) (*QueryVectorIndexResponse, error) { + wireReq, err := queryVectorIndexRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/indexes/") + pb.singleSegment(*req.Name) + pb.literal("/query") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *QueryVectorIndexResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp queryVectorIndexResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = queryVectorIndexResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Use `next_page_token` returned from previous `QueryVectorIndex` or +// `QueryVectorIndexNextPage` request to fetch next page of results. +func (c *internalClient) QueryVectorIndexNextPage(ctx context.Context, req *QueryVectorIndexNextPageRequest, opts ...call.Option) (*QueryVectorIndexResponse, error) { + wireReq, err := queryVectorIndexNextPageRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/indexes/") + pb.singleSegment(*req.Name) + pb.literal("/query-next-page") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *QueryVectorIndexResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp queryVectorIndexResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = queryVectorIndexResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Retrieve user-visible metrics for an endpoint +func (c *internalClient) RetrieveUserVisibleMetrics(ctx context.Context, req *RetrieveUserVisibleMetricsRequest, opts ...call.Option) (*RetrieveUserVisibleMetricsResponse, error) { + wireReq, err := retrieveUserVisibleMetricsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/metrics") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *RetrieveUserVisibleMetricsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp retrieveUserVisibleMetricsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = retrieveUserVisibleMetricsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Scan the specified vector index and return the first `num_results` entries +// after the exclusive `primary_key`. +func (c *internalClient) ScanVectorIndex(ctx context.Context, req *ScanVectorIndexRequest, opts ...call.Option) (*ScanVectorIndexResponse, error) { + wireReq, err := scanVectorIndexRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/indexes/") + pb.singleSegment(*req.Name) + pb.literal("/scan") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ScanVectorIndexResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp scanVectorIndexResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = scanVectorIndexResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Triggers a synchronization process for a specified vector index. +func (c *internalClient) SyncVectorIndex(ctx context.Context, req *SyncVectorIndexRequest, opts ...call.Option) (*SyncVectorIndexResponse, error) { + wireReq, err := syncVectorIndexRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/indexes/") + pb.singleSegment(*req.Name) + pb.literal("/sync") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SyncVectorIndexResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &SyncVectorIndexResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Update the custom tags of an endpoint. +func (c *internalClient) UpdateEndpointCustomTags(ctx context.Context, req *UpdateEndpointCustomTagsRequest, opts ...call.Option) (*UpdateEndpointCustomTagsResponse, error) { + wireReq, err := updateEndpointCustomTagsRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/endpoints/") + pb.singleSegment(*req.Name) + pb.literal("/tags") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpdateEndpointCustomTagsResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp updateEndpointCustomTagsResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = updateEndpointCustomTagsResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Handles the upserting of data into a specified vector index. +func (c *internalClient) UpsertDataVectorIndex(ctx context.Context, req *UpsertDataVectorIndexRequest, opts ...call.Option) (*UpsertDataVectorIndexResponse, error) { + wireReq, err := upsertDataVectorIndexRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/vector-search/indexes/") + pb.singleSegment(*req.Name) + pb.literal("/upsert-data") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *UpsertDataVectorIndexResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp upsertDataVectorIndexResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = upsertDataVectorIndexResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/vectorsearch/v1/genhelper.go b/vectorsearch/v1/genhelper.go new file mode 100755 index 0000000..db6b94f --- /dev/null +++ b/vectorsearch/v1/genhelper.go @@ -0,0 +1,243 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package vectorsearch + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/vectorsearch/v1/model.go b/vectorsearch/v1/model.go new file mode 100755 index 0000000..80b09c2 --- /dev/null +++ b/vectorsearch/v1/model.go @@ -0,0 +1,787 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package vectorsearch + +import ( + "encoding/json" + + "github.com/databricks/sdk-go/core/types" +) + +// Type of endpoint. +type EndpointType string + +const ( + EndpointType_Unspecified EndpointType = "" + EndpointType_StorageOptimized EndpointType = "STORAGE_OPTIMIZED" + EndpointType_Standard EndpointType = "STANDARD" +) + +// The subtype of the AI Search index, determining the indexing and retrieval +// strategy. - `VECTOR`: Not supported. Use `HYBRID` instead. - `FULL_TEXT`: An +// index that uses full-text search without vector embeddings. - `HYBRID`: An +// index that uses vector embeddings for similarity search and hybrid search. +type IndexSubtype string + +const ( + IndexSubtype_Unspecified IndexSubtype = "" + IndexSubtype_FullText IndexSubtype = "FULL_TEXT" + IndexSubtype_Hybrid IndexSubtype = "HYBRID" +) + +// Pipeline execution mode. - `TRIGGERED`: If the pipeline uses the triggered +// execution mode, the system stops processing after successfully refreshing the +// source table in the pipeline once, ensuring the table is updated based on the +// data available when the update started. - `CONTINUOUS`: If the pipeline uses +// continuous execution, the pipeline processes new data as it arrives in the +// source table to keep vector index fresh. +type PipelineType string + +const ( + PipelineType_Unspecified PipelineType = "" + PipelineType_Continuous PipelineType = "CONTINUOUS" +) + +type ScalingChangeState string + +const ( + ScalingChangeState_Unspecified ScalingChangeState = "" + ScalingChangeState_ScalingChangeApplied ScalingChangeState = "SCALING_CHANGE_APPLIED" + ScalingChangeState_ScalingChangeInProgress ScalingChangeState = "SCALING_CHANGE_IN_PROGRESS" +) + +type UpsertDeleteDataStatus string + +const ( + UpsertDeleteDataStatus_Unspecified UpsertDeleteDataStatus = "" + UpsertDeleteDataStatus_PartialSuccess UpsertDeleteDataStatus = "PARTIAL_SUCCESS" + UpsertDeleteDataStatus_Failure UpsertDeleteDataStatus = "FAILURE" +) + +// There are 2 types of AI Search indexes: - `DELTA_SYNC`: An index that +// automatically syncs with a source Delta Table, automatically and +// incrementally updating the index as the underlying data in the Delta Table +// changes. - `DIRECT_ACCESS`: An index that supports direct read and write of +// vectors and metadata through our REST and SDK APIs. With this model, the user +// manages index updates. +type VectorIndexType string + +const ( + VectorIndexType_Unspecified VectorIndexType = "" + VectorIndexType_DirectAccess VectorIndexType = "DIRECT_ACCESS" +) + +// Current state of the endpoint +type EndpointStatus_State string + +const ( + EndpointStatus_State_Unspecified EndpointStatus_State = "" + EndpointStatus_State_Online EndpointStatus_State = "ONLINE" + EndpointStatus_State_Offline EndpointStatus_State = "OFFLINE" + // After the endpoint is ready, it can be in one of the following states: - + // RED_STATE: The endpoint is unhealthy and needs to be investigated. - + // YELLOW_STATE: The endpoint is healthy but needs to be monitored. - ONLINE: + // The endpoint is healthy and ready to serve traffic. + EndpointStatus_State_RedState EndpointStatus_State = "RED_STATE" + EndpointStatus_State_YellowState EndpointStatus_State = "YELLOW_STATE" + // The endpoint is being deleted or has been deleted. Associated resources are + // being cleaned up; once cleanup completes the endpoint will no longer be + // retrievable. + EndpointStatus_State_Deleted EndpointStatus_State = "DELETED" +) + +type ColumnInfo struct { + // Name of the column. + Name *string + // Data type of the column (e.g., "string", "int", "array") + TypeText *string +} + +type CreateEndpointRequest struct { + // Name of the AI Search endpoint + Name *string + // Type of endpoint + EndpointType EndpointType + // The budget policy id to be applied + BudgetPolicyId *string + // The usage policy id to be applied once we've migrated to usage policies + UsagePolicyId *string + // Target QPS for the endpoint. Mutually exclusive with num_replicas. The actual + // replica count is calculated at index creation/sync time based on this value. + // Best-effort target; the system does not guarantee this QPS will be achieved. + TargetQps *int64 +} + +type CreateVectorIndexRequest struct { + // Name of the index + Name *string + // Name of the endpoint to be used for serving the index + EndpointName *string + // Primary key of the index + PrimaryKey *string + IndexType VectorIndexType + IndexSpec isCreateVectorIndexRequest_IndexSpec + // The subtype of the index. Use `HYBRID` or `FULL_TEXT`. `VECTOR` is not + // supported. + IndexSubtype IndexSubtype +} + +type isCreateVectorIndexRequest_IndexSpec interface { + isCreateVectorIndexRequest_IndexSpec() +} + +// CreateVectorIndexRequest_IndexSpec_DirectAccessIndexSpec selects DirectAccessIndexSpec for CreateVectorIndexRequest.IndexSpec. +// Specification for Direct Vector Access Index. Required if `index_type` is +// `DIRECT_ACCESS`. +type CreateVectorIndexRequest_IndexSpec_DirectAccessIndexSpec struct { + DirectAccessIndexSpec DirectAccessVectorIndexSpec +} + +func (*CreateVectorIndexRequest_IndexSpec_DirectAccessIndexSpec) isCreateVectorIndexRequest_IndexSpec() { +} + +// CreateVectorIndexRequest_IndexSpec_DeltaSyncIndexSpec selects DeltaSyncIndexSpec for CreateVectorIndexRequest.IndexSpec. +// Specification for Delta Sync Index. Required if `index_type` is `DELTA_SYNC`. +type CreateVectorIndexRequest_IndexSpec_DeltaSyncIndexSpec struct { + DeltaSyncIndexSpec DeltaSyncVectorIndexSpecRequest +} + +func (*CreateVectorIndexRequest_IndexSpec_DeltaSyncIndexSpec) isCreateVectorIndexRequest_IndexSpec() { +} + +type CustomTag struct { + // Key field for an AI Search endpoint tag. + Key *string + // [Optional] Value field for an AI Search endpoint tag. + Value *string +} + +// Request payload for deleting data from a vector index.. +type DeleteDataVectorIndexRequest struct { + // Name of the vector index where data is to be deleted. Must be a Direct Vector + // Access Index. + Name *string + // List of primary keys for the data to be deleted. + PrimaryKeys []string +} + +type DeleteDataVectorIndexResponse struct { + // Status of the delete operation. + Status UpsertDeleteDataStatus + // Result of the upsert or delete operation. + Result *UpsertDeleteDataResult +} + +type DeleteEndpointRequest struct { + // Name of the AI Search endpoint + Name *string +} + +type DeleteEndpointResponse struct { +} + +type DeleteVectorIndexRequest struct { + // Name of the index + Name *string +} + +type DeleteVectorIndexResponse struct { +} + +type DeltaSyncVectorIndexSpec struct { + // The name of the source table. + SourceTable *string + // The columns that contain the embedding source. + EmbeddingSourceColumns []EmbeddingSourceColumn + // The columns that contain the embedding vectors. + EmbeddingVectorColumns []EmbeddingVectorColumn + // Pipeline execution mode. - `TRIGGERED`: If the pipeline uses the triggered + // execution mode, the system stops processing after successfully refreshing the + // source table in the pipeline once, ensuring the table is updated based on the + // data available when the update started. - `CONTINUOUS`: If the pipeline uses + // continuous execution, the pipeline processes new data as it arrives in the + // source table to keep vector index fresh. + PipelineType PipelineType + // The ID of the pipeline that is used to sync the index. + PipelineId *string + // [Optional] Name of the Delta table to sync the vector index contents and + // computed embeddings to. + EmbeddingWritebackTable *string + // [Optional] Select the columns to sync with the vector index. If you leave + // this field blank, all columns from the source table are synced with the + // index. The primary key column and embedding source column or embedding vector + // column are always synced. + ColumnsToSync []string + // [Optional] Alias for columns_to_sync. Select the columns to include in the + // vector index. If you leave this field blank, all columns from the source + // table are included. The primary key column and embedding source column or + // embedding vector column are always included. Only one of columns_to_sync or + // columns_to_index may be specified. + ColumnsToIndex []string +} + +type DeltaSyncVectorIndexSpecRequest struct { + // The name of the source table. + SourceTable *string + // The columns that contain the embedding source. + EmbeddingSourceColumns []EmbeddingSourceColumn + // The columns that contain the embedding vectors. + EmbeddingVectorColumns []EmbeddingVectorColumn + // Pipeline execution mode. - `TRIGGERED`: If the pipeline uses the triggered + // execution mode, the system stops processing after successfully refreshing the + // source table in the pipeline once, ensuring the table is updated based on the + // data available when the update started. - `CONTINUOUS`: If the pipeline uses + // continuous execution, the pipeline processes new data as it arrives in the + // source table to keep vector index fresh. + PipelineType PipelineType + // The ID of the pipeline that is used to sync the index. + PipelineId *string + // [Optional] Name of the Delta table to sync the vector index contents and + // computed embeddings to. + EmbeddingWritebackTable *string + // [Optional] Select the columns to sync with the vector index. If you leave + // this field blank, all columns from the source table are synced with the + // index. The primary key column and embedding source column or embedding vector + // column are always synced. + ColumnsToSync []string + // [Optional] Alias for columns_to_sync. Select the columns to include in the + // vector index. If you leave this field blank, all columns from the source + // table are included. The primary key column and embedding source column or + // embedding vector column are always included. Only one of columns_to_sync or + // columns_to_index may be specified. + ColumnsToIndex []string +} + +type DirectAccessVectorIndexSpec struct { + // The columns that contain the embedding vectors. The format should be + // array[double]. + EmbeddingVectorColumns []EmbeddingVectorColumn + // The schema of the index in JSON format. Supported types are `integer`, + // `long`, `float`, `double`, `boolean`, `string`, `date`, `timestamp`. + // Supported types for vector column: `array`, `array`,`. + SchemaJson *string + // The columns that contain the embedding source. The format should be + // array[double]. + EmbeddingSourceColumns []EmbeddingSourceColumn +} + +type EmbeddingSourceColumn struct { + // Name of the column + Name *string + // TODO: clean up ai gateway related code. It's deprecated on ModelServing side. + EmbeddingConfig isEmbeddingSourceColumn_EmbeddingConfig + // Name of the embedding model endpoint which, if specified, is used for + // querying (not ingestion). + ModelEndpointNameForQuery *string +} + +type isEmbeddingSourceColumn_EmbeddingConfig interface { + isEmbeddingSourceColumn_EmbeddingConfig() +} + +// EmbeddingSourceColumn_EmbeddingConfig_EmbeddingModelEndpointName selects EmbeddingModelEndpointName for EmbeddingSourceColumn.EmbeddingConfig. +// Name of the embedding model endpoint, used by default for both ingestion and +// querying. +type EmbeddingSourceColumn_EmbeddingConfig_EmbeddingModelEndpointName struct { + EmbeddingModelEndpointName string +} + +func (*EmbeddingSourceColumn_EmbeddingConfig_EmbeddingModelEndpointName) isEmbeddingSourceColumn_EmbeddingConfig() { +} + +type EmbeddingVectorColumn struct { + // Name of the column + Name *string + // Dimension of the embedding vector + EmbeddingDimension *int +} + +type Endpoint struct { + // Name of the AI Search endpoint + Name *string + // Creator of the endpoint + Creator *string + // Timestamp of endpoint creation + CreationTimestamp *int64 + // Timestamp of last update to the endpoint + LastUpdatedTimestamp *int64 + // Type of endpoint + EndpointType EndpointType + // User who last updated the endpoint + LastUpdatedUser *string + // Unique identifier of the endpoint + Id *string + // Current status of the endpoint + EndpointStatus *EndpointStatus + // Number of indexes on the endpoint + NumIndexes *int + // The user-selected budget policy id for the endpoint. + BudgetPolicyId *string + // The budget policy id applied to the endpoint + EffectiveBudgetPolicyId *string + // The custom tags assigned to the endpoint + CustomTags []CustomTag + // Scaling information for the endpoint + ScalingInfo *EndpointScalingInfo +} + +type EndpointScalingInfo struct { + // The current state of the scaling change request. + State ScalingChangeState + // The requested QPS target for the endpoint. Best-effort; the system does not + // guarantee this QPS will be achieved. + RequestedTargetQps *int64 +} + +// Status information of an endpoint. +type EndpointStatus struct { + // Current state of the endpoint + State EndpointStatus_State + // Additional status message + Message *string +} + +// Facet aggregation rows returned by a query.. +type FacetResultData struct { + // Number of facet rows returned. + FacetRowCount *int + // Facet rows. Each row is `[facet_column_name, value_or_range, count]`. + FacetArray [][]json.RawMessage +} + +type GetEndpointRequest struct { + // Name of the endpoint + Name *string +} + +type GetVectorIndexRequest struct { + // Name of the index + Name *string + // If true, the URL returned for the index is guaranteed to be compatible with + // the reranker. Currently this means we return the CP URL regardless of how the + // index is being accessed. If not set or set to false, the URL may still be + // compatible with the reranker depending on what URL we return. + EnsureRerankerCompatible *bool +} + +type ListEndpointResponse struct { + // An array of Endpoint objects + Endpoints []Endpoint + // A token that can be used to get the next page of results. If not present, + // there are no more results to show. + NextPageToken *string +} + +type ListEndpointsRequest struct { + // Token for pagination + PageToken *string +} + +type ListValue struct { + // Repeated field of dynamically typed values. + Values []Value +} + +type ListVectorIndexRequest struct { + // Name of the endpoint + EndpointName *string + // Token for pagination + PageToken *string +} + +type ListVectorIndexResponse struct { + VectorIndexes []MiniVectorIndex + // A token that can be used to get the next page of results. If not present, + // there are no more results to show. + NextPageToken *string +} + +// Key-value pair.. +type MapStringValueEntry struct { + // Column name. + Key *string + // Column value, nullable. + Value *Value +} + +// Metric specification. +type Metric struct { + // Metric name + Name *string + // Metric labels + Labels []MetricLabel + // Percentile for the metric + Percentile *float64 +} + +// Label for a metric. +type MetricLabel struct { + // Label name + Name *string + // Label value + Value *string +} + +// Single metric value at a specific timestamp. +type MetricValue struct { + // Timestamp of the metric value (milliseconds since epoch) + Timestamp *int64 + // Metric value + Value *float64 +} + +// Collection of metric values for a specific metric. +type MetricValues struct { + // Metric specification + Metric *Metric + // Time series of metric values + Values []MetricValue +} + +type MiniVectorIndex struct { + // Name of the index + Name *string + // Name of the endpoint associated with the index + EndpointName *string + // Primary key of the index + PrimaryKey *string + IndexType VectorIndexType + IndexSpec isMiniVectorIndex_IndexSpec + Status *VectorIndexStatus + // The user who created the index. + Creator *string + // The subtype of the index. + IndexSubtype IndexSubtype + // ID of the endpoint associated with the index. + EndpointId *string +} + +type isMiniVectorIndex_IndexSpec interface { + isMiniVectorIndex_IndexSpec() +} + +// MiniVectorIndex_IndexSpec_DirectAccessIndexSpec selects DirectAccessIndexSpec for MiniVectorIndex.IndexSpec. +type MiniVectorIndex_IndexSpec_DirectAccessIndexSpec struct { + DirectAccessIndexSpec DirectAccessVectorIndexSpec +} + +func (*MiniVectorIndex_IndexSpec_DirectAccessIndexSpec) isMiniVectorIndex_IndexSpec() {} + +// MiniVectorIndex_IndexSpec_DeltaSyncIndexSpec selects DeltaSyncIndexSpec for MiniVectorIndex.IndexSpec. +type MiniVectorIndex_IndexSpec_DeltaSyncIndexSpec struct { + DeltaSyncIndexSpec DeltaSyncVectorIndexSpec +} + +func (*MiniVectorIndex_IndexSpec_DeltaSyncIndexSpec) isMiniVectorIndex_IndexSpec() {} + +type PatchEndpointBudgetPolicyRequest struct { + // Name of the AI Search endpoint + Name *string + // The budget policy id to be applied + BudgetPolicyId *string +} + +type PatchEndpointBudgetPolicyResponse struct { + BudgetPolicyId *string + // The budget policy applied to the AI Search endpoint. + EffectiveBudgetPolicyId *string +} + +type PatchEndpointRequest struct { + // Name of the AI Search endpoint + Name *string + // Target QPS for the endpoint. Best-effort; the system does not guarantee this + // QPS will be achieved. + TargetQps *int64 +} + +// Request payload for getting next page of results.. +type QueryVectorIndexNextPageRequest struct { + // Name of the vector index to query. + Name *string + // Name of the endpoint. + EndpointName *string + // Page token returned from previous `QueryVectorIndex` or + // `QueryVectorIndexNextPage` API. + PageToken *string +} + +type QueryVectorIndexRequest struct { + // Name of the vector index to query. + Name *string + // Number of results to return. Defaults to 10. + NumResults *int + // List of column names to include in the response. + Columns []string + // JSON string representing query filters. + // + // Example filters: + // + // - `{"id <": 5}`: Filter for id less than 5. - `{"id >": 5}`: Filter for id + // greater than 5. - `{"id <=": 5}`: Filter for id less than equal to 5. - `{"id + // >=": 5}`: Filter for id greater than equal to 5. - `{"id": 5}`: Filter for id + // equal to 5. + FiltersJson *string + // Query vector. Required for Direct Vector Access Index and Delta Sync Index + // using self-managed vectors. + QueryVector []float32 + // Query text. Required for Delta Sync Index using model endpoint. + QueryText *string + // Threshold for the approximate nearest neighbor search. Defaults to 0.0. + ScoreThreshold *float32 + // The query type to use. Choices are `ANN` and `HYBRID` and `FULL_TEXT`. + // Defaults to `ANN`. + QueryType *string + // Column names used to retrieve data to send to the reranker. + ColumnsToRerank []string + // If set, the top 50 results are reranked with the Databricks Reranker model + // before returning the `num_results` results to the user. The setting + // `columns_to_rerank` selects which columns are used for reranking. For each + // datapoint, the columns selected are concatenated before being sent to the + // reranking model. See + // https://docs.databricks.com/aws/en/vector-search/query-vector-search#rerank + // for more information. + Reranker *RerankerConfig + // Text columns to search for `query_text`. When empty, all text columns are + // searched. + QueryColumns []string + // Sort results by column values instead of the default relevance ordering. Each + // clause has the form `" ASC"` or `" DESC"`, for example + // `["rating DESC", "price ASC"]`. + SortColumns []string + // Facets to compute over the matched results. Each entry has one of these + // forms: `""` - top 10 distinct values by count `" TOP "` - + // top n distinct values, where n > 0 `" BUCKETS [[from,to],...]"` - + // inclusive numeric ranges `TOP` and `BUCKETS` are case-insensitive. A column + // may appear at most once. + Facets []string +} + +type QueryVectorIndexResponse struct { + // Metadata about the result set. + Manifest *ResultManifest + // Data returned in the query result. + Result *ResultData + // [Optional] Token that can be used in `QueryVectorIndexNextPage` API to get + // next page of results. If more than 1000 results satisfy the query, they are + // returned in groups of 1000. Empty value means no more results. The maximum + // number of results that can be returned is 10,000. + NextPageToken *string + // Facet aggregation rows returned by a query. + FacetResult *FacetResultData +} + +type RerankerConfig struct { + // Reranker identifier: - When model_type=BASE/UNSPECIFIED: must be + // "databricks_reranker". - When model_type=FINETUNED: the Model Serving + // endpoint name hosting a finetuned reranker. + Model *string + // Parameters that control how the reranker processes the query results. + Parameters *RerankerConfig_RerankerParameters +} + +type RerankerConfig_RerankerParameters struct { + ColumnsToRerank []string +} + +// Data returned in the query result.. +type ResultData struct { + // Number of rows in the result set. + RowCount *int + // Data rows returned in the query. + DataArray [][]json.RawMessage +} + +// Metadata about the result set.. +type ResultManifest struct { + // Number of columns in the result set. + ColumnCount *int + // Information about each column in the result set. + Columns []ColumnInfo + // Number of columns in `facet_result`. + FacetColumnCount *int + // Information about each column in `facet_result`. + FacetColumns []ColumnInfo +} + +// Request to retrieve user-visible metrics. +type RetrieveUserVisibleMetricsRequest struct { + // AI Search endpoint name + Name *string + // Start time for metrics query + StartTime *types.Time + // End time for metrics query + EndTime *types.Time + // Granularity in seconds + GranularityInSeconds *int + // List of metrics to retrieve + Metrics []Metric + // Token for pagination + PageToken *string +} + +// Response containing user-visible metrics. +type RetrieveUserVisibleMetricsResponse struct { + // Collection of metric values + MetricValues []MetricValues + // A token that can be used to get the next page of results. If not present, + // there are no more results to show. + NextPageToken *string +} + +type ScanVectorIndexRequest struct { + // Name of the vector index to scan. + Name *string + // Number of results to return. Defaults to 10. + NumResults *int + // Primary key of the last entry returned in the previous scan. + LastPrimaryKey *string +} + +// Response to a scan vector index request.. +type ScanVectorIndexResponse struct { + // List of data entries + Data []Struct + // Primary key of the last entry. + LastPrimaryKey *string +} + +type Struct struct { + // Data entry, corresponding to a row in a vector index. + Fields []MapStringValueEntry +} + +type SyncVectorIndexRequest struct { + // Name of the vector index to synchronize. Must be a Delta Sync Index. + Name *string +} + +type SyncVectorIndexResponse struct { +} + +type UpdateEndpointCustomTagsRequest struct { + // Name of the AI Search endpoint + Name *string + // The new custom tags for the AI Search endpoint + CustomTags []CustomTag +} + +type UpdateEndpointCustomTagsResponse struct { + // The name of the AI Search endpoint whose custom tags were updated. + Name *string + // All the custom tags that are applied to the AI Search endpoint. + CustomTags []CustomTag +} + +type UpsertDataVectorIndexRequest struct { + // Name of the vector index where data is to be upserted. Must be a Direct + // Vector Access Index. + Name *string + // JSON string representing the data to be upserted. + InputsJson *string +} + +type UpsertDataVectorIndexResponse struct { + // Status of the upsert operation. + Status UpsertDeleteDataStatus + // Result of the upsert or delete operation. + Result *UpsertDeleteDataResult +} + +type UpsertDeleteDataResult struct { + // Count of successfully processed rows. + SuccessRowCount *int64 + // List of primary keys for rows that failed to process. + FailedPrimaryKeys []string +} + +type Value struct { + // (--The kind of value.--) + Kind isValue_Kind +} + +type isValue_Kind interface { + isValue_Kind() +} + +// Value_Kind_NumberValue selects NumberValue for Value.Kind. +type Value_Kind_NumberValue struct { + NumberValue float64 +} + +func (*Value_Kind_NumberValue) isValue_Kind() {} + +// Value_Kind_StringValue selects StringValue for Value.Kind. +type Value_Kind_StringValue struct { + StringValue string +} + +func (*Value_Kind_StringValue) isValue_Kind() {} + +// Value_Kind_BoolValue selects BoolValue for Value.Kind. +type Value_Kind_BoolValue struct { + BoolValue bool +} + +func (*Value_Kind_BoolValue) isValue_Kind() {} + +// Value_Kind_StructValue selects StructValue for Value.Kind. +type Value_Kind_StructValue struct { + StructValue Struct +} + +func (*Value_Kind_StructValue) isValue_Kind() {} + +// Value_Kind_ListValue selects ListValue for Value.Kind. +type Value_Kind_ListValue struct { + ListValue ListValue +} + +func (*Value_Kind_ListValue) isValue_Kind() {} + +type VectorIndex struct { + // Name of the index + Name *string + // Name of the endpoint associated with the index + EndpointName *string + // Primary key of the index + PrimaryKey *string + IndexType VectorIndexType + IndexSpec isVectorIndex_IndexSpec + Status *VectorIndexStatus + // The user who created the index. + Creator *string + // The subtype of the index. + IndexSubtype IndexSubtype + // ID of the endpoint associated with the index. + EndpointId *string +} + +type isVectorIndex_IndexSpec interface { + isVectorIndex_IndexSpec() +} + +// VectorIndex_IndexSpec_DirectAccessIndexSpec selects DirectAccessIndexSpec for VectorIndex.IndexSpec. +type VectorIndex_IndexSpec_DirectAccessIndexSpec struct { + DirectAccessIndexSpec DirectAccessVectorIndexSpec +} + +func (*VectorIndex_IndexSpec_DirectAccessIndexSpec) isVectorIndex_IndexSpec() {} + +// VectorIndex_IndexSpec_DeltaSyncIndexSpec selects DeltaSyncIndexSpec for VectorIndex.IndexSpec. +type VectorIndex_IndexSpec_DeltaSyncIndexSpec struct { + DeltaSyncIndexSpec DeltaSyncVectorIndexSpec +} + +func (*VectorIndex_IndexSpec_DeltaSyncIndexSpec) isVectorIndex_IndexSpec() {} + +type VectorIndexStatus struct { + // Message associated with the index status + Message *string + // Number of rows indexed + IndexedRowCount *int64 + // Whether the index is ready for search + Ready *bool + // Index API Url to be used to perform operations on the index + IndexUrl *string +} diff --git a/vectorsearch/v1/wire.go b/vectorsearch/v1/wire.go new file mode 100755 index 0000000..125d5dd --- /dev/null +++ b/vectorsearch/v1/wire.go @@ -0,0 +1,1268 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package vectorsearch + +import ( + "encoding/json" + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +type columnInfoWire struct { + Name *string `json:"name,omitempty"` + TypeText *string `json:"type_text,omitempty"` +} + +func columnInfoFromWire(w *columnInfoWire) (*ColumnInfo, error) { + if w == nil { + return nil, nil + } + return &ColumnInfo{ + Name: w.Name, + TypeText: w.TypeText, + }, nil +} + +type createEndpointRequestWire struct { + Name *string `json:"name,omitempty"` + EndpointType EndpointType `json:"endpoint_type,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + UsagePolicyId *string `json:"usage_policy_id,omitempty"` + TargetQps *int64 `json:"target_qps,omitempty"` +} + +func createEndpointRequestToWire(v *CreateEndpointRequest) (*createEndpointRequestWire, error) { + if v == nil { + return nil, nil + } + return &createEndpointRequestWire{ + Name: v.Name, + EndpointType: v.EndpointType, + BudgetPolicyId: v.BudgetPolicyId, + UsagePolicyId: v.UsagePolicyId, + TargetQps: v.TargetQps, + }, nil +} + +type createVectorIndexRequestWire struct { + Name *string `json:"name,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + PrimaryKey *string `json:"primary_key,omitempty"` + IndexType VectorIndexType `json:"index_type,omitempty"` + DirectAccessIndexSpec *directAccessVectorIndexSpecWire `json:"direct_access_index_spec,omitempty"` + DeltaSyncIndexSpec *deltaSyncVectorIndexSpecRequestWire `json:"delta_sync_index_spec,omitempty"` + IndexSubtype IndexSubtype `json:"index_subtype,omitempty"` +} + +func createVectorIndexRequestToWire(v *CreateVectorIndexRequest) (*createVectorIndexRequestWire, error) { + if v == nil { + return nil, nil + } + var indexSpecDirectAccessIndexSpecWire *directAccessVectorIndexSpecWire + var indexSpecDeltaSyncIndexSpecWire *deltaSyncVectorIndexSpecRequestWire + switch value := v.IndexSpec.(type) { + case nil: + case *CreateVectorIndexRequest_IndexSpec_DirectAccessIndexSpec: + if value != nil { + indexSpecDirectAccessIndexSpecConverted, err := directAccessVectorIndexSpecToWire(&value.DirectAccessIndexSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateVectorIndexRequest.IndexSpec.DirectAccessIndexSpec", err) + } + indexSpecDirectAccessIndexSpecWire = indexSpecDirectAccessIndexSpecConverted + } + case *CreateVectorIndexRequest_IndexSpec_DeltaSyncIndexSpec: + if value != nil { + indexSpecDeltaSyncIndexSpecConverted, err := deltaSyncVectorIndexSpecRequestToWire(&value.DeltaSyncIndexSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateVectorIndexRequest.IndexSpec.DeltaSyncIndexSpec", err) + } + indexSpecDeltaSyncIndexSpecWire = indexSpecDeltaSyncIndexSpecConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CreateVectorIndexRequest.IndexSpec", value) + } + return &createVectorIndexRequestWire{ + Name: v.Name, + EndpointName: v.EndpointName, + PrimaryKey: v.PrimaryKey, + IndexType: v.IndexType, + DirectAccessIndexSpec: indexSpecDirectAccessIndexSpecWire, + DeltaSyncIndexSpec: indexSpecDeltaSyncIndexSpecWire, + IndexSubtype: v.IndexSubtype, + }, nil +} + +type customTagWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func customTagToWire(v *CustomTag) (*customTagWire, error) { + if v == nil { + return nil, nil + } + return &customTagWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func customTagFromWire(w *customTagWire) (*CustomTag, error) { + if w == nil { + return nil, nil + } + return &CustomTag{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type deleteDataVectorIndexRequestWire struct { + Name *string `json:"name,omitempty"` + PrimaryKeys []string `json:"primary_keys,omitempty"` +} + +func deleteDataVectorIndexRequestToWire(v *DeleteDataVectorIndexRequest) (*deleteDataVectorIndexRequestWire, error) { + if v == nil { + return nil, nil + } + return &deleteDataVectorIndexRequestWire{ + Name: v.Name, + PrimaryKeys: v.PrimaryKeys, + }, nil +} + +type deleteDataVectorIndexResponseWire struct { + Status UpsertDeleteDataStatus `json:"status,omitempty"` + Result *upsertDeleteDataResultWire `json:"result,omitempty"` +} + +func deleteDataVectorIndexResponseFromWire(w *deleteDataVectorIndexResponseWire) (*DeleteDataVectorIndexResponse, error) { + if w == nil { + return nil, nil + } + resultPublicValue, err := upsertDeleteDataResultFromWire(w.Result) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeleteDataVectorIndexResponse.Result", err) + } + return &DeleteDataVectorIndexResponse{ + Status: w.Status, + Result: resultPublicValue, + }, nil +} + +type deltaSyncVectorIndexSpecWire struct { + SourceTable *string `json:"source_table,omitempty"` + EmbeddingSourceColumns []embeddingSourceColumnWire `json:"embedding_source_columns,omitempty"` + EmbeddingVectorColumns []embeddingVectorColumnWire `json:"embedding_vector_columns,omitempty"` + PipelineType PipelineType `json:"pipeline_type,omitempty"` + PipelineId *string `json:"pipeline_id,omitempty"` + EmbeddingWritebackTable *string `json:"embedding_writeback_table,omitempty"` + ColumnsToSync []string `json:"columns_to_sync,omitempty"` + ColumnsToIndex []string `json:"columns_to_index,omitempty"` +} + +func deltaSyncVectorIndexSpecFromWire(w *deltaSyncVectorIndexSpecWire) (*DeltaSyncVectorIndexSpec, error) { + if w == nil { + return nil, nil + } + embeddingSourceColumnsPublicValue, err := convertSlice(w.EmbeddingSourceColumns, embeddingSourceColumnFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeltaSyncVectorIndexSpec.EmbeddingSourceColumns", err) + } + embeddingVectorColumnsPublicValue, err := convertSlice(w.EmbeddingVectorColumns, embeddingVectorColumnFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeltaSyncVectorIndexSpec.EmbeddingVectorColumns", err) + } + return &DeltaSyncVectorIndexSpec{ + SourceTable: w.SourceTable, + EmbeddingSourceColumns: embeddingSourceColumnsPublicValue, + EmbeddingVectorColumns: embeddingVectorColumnsPublicValue, + PipelineType: w.PipelineType, + PipelineId: w.PipelineId, + EmbeddingWritebackTable: w.EmbeddingWritebackTable, + ColumnsToSync: w.ColumnsToSync, + ColumnsToIndex: w.ColumnsToIndex, + }, nil +} + +type deltaSyncVectorIndexSpecRequestWire struct { + SourceTable *string `json:"source_table,omitempty"` + EmbeddingSourceColumns []embeddingSourceColumnWire `json:"embedding_source_columns,omitempty"` + EmbeddingVectorColumns []embeddingVectorColumnWire `json:"embedding_vector_columns,omitempty"` + PipelineType PipelineType `json:"pipeline_type,omitempty"` + PipelineId *string `json:"pipeline_id,omitempty"` + EmbeddingWritebackTable *string `json:"embedding_writeback_table,omitempty"` + ColumnsToSync []string `json:"columns_to_sync,omitempty"` + ColumnsToIndex []string `json:"columns_to_index,omitempty"` +} + +func deltaSyncVectorIndexSpecRequestToWire(v *DeltaSyncVectorIndexSpecRequest) (*deltaSyncVectorIndexSpecRequestWire, error) { + if v == nil { + return nil, nil + } + embeddingSourceColumnsWireValue, err := convertSlice(v.EmbeddingSourceColumns, embeddingSourceColumnToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeltaSyncVectorIndexSpecRequest.EmbeddingSourceColumns", err) + } + embeddingVectorColumnsWireValue, err := convertSlice(v.EmbeddingVectorColumns, embeddingVectorColumnToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DeltaSyncVectorIndexSpecRequest.EmbeddingVectorColumns", err) + } + return &deltaSyncVectorIndexSpecRequestWire{ + SourceTable: v.SourceTable, + EmbeddingSourceColumns: embeddingSourceColumnsWireValue, + EmbeddingVectorColumns: embeddingVectorColumnsWireValue, + PipelineType: v.PipelineType, + PipelineId: v.PipelineId, + EmbeddingWritebackTable: v.EmbeddingWritebackTable, + ColumnsToSync: v.ColumnsToSync, + ColumnsToIndex: v.ColumnsToIndex, + }, nil +} + +type directAccessVectorIndexSpecWire struct { + EmbeddingVectorColumns []embeddingVectorColumnWire `json:"embedding_vector_columns,omitempty"` + SchemaJson *string `json:"schema_json,omitempty"` + EmbeddingSourceColumns []embeddingSourceColumnWire `json:"embedding_source_columns,omitempty"` +} + +func directAccessVectorIndexSpecToWire(v *DirectAccessVectorIndexSpec) (*directAccessVectorIndexSpecWire, error) { + if v == nil { + return nil, nil + } + embeddingVectorColumnsWireValue, err := convertSlice(v.EmbeddingVectorColumns, embeddingVectorColumnToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DirectAccessVectorIndexSpec.EmbeddingVectorColumns", err) + } + embeddingSourceColumnsWireValue, err := convertSlice(v.EmbeddingSourceColumns, embeddingSourceColumnToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DirectAccessVectorIndexSpec.EmbeddingSourceColumns", err) + } + return &directAccessVectorIndexSpecWire{ + EmbeddingVectorColumns: embeddingVectorColumnsWireValue, + SchemaJson: v.SchemaJson, + EmbeddingSourceColumns: embeddingSourceColumnsWireValue, + }, nil +} + +func directAccessVectorIndexSpecFromWire(w *directAccessVectorIndexSpecWire) (*DirectAccessVectorIndexSpec, error) { + if w == nil { + return nil, nil + } + embeddingVectorColumnsPublicValue, err := convertSlice(w.EmbeddingVectorColumns, embeddingVectorColumnFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DirectAccessVectorIndexSpec.EmbeddingVectorColumns", err) + } + embeddingSourceColumnsPublicValue, err := convertSlice(w.EmbeddingSourceColumns, embeddingSourceColumnFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "DirectAccessVectorIndexSpec.EmbeddingSourceColumns", err) + } + return &DirectAccessVectorIndexSpec{ + EmbeddingVectorColumns: embeddingVectorColumnsPublicValue, + SchemaJson: w.SchemaJson, + EmbeddingSourceColumns: embeddingSourceColumnsPublicValue, + }, nil +} + +type embeddingSourceColumnWire struct { + Name *string `json:"name,omitempty"` + EmbeddingModelEndpointName *string `json:"embedding_model_endpoint_name,omitempty"` + ModelEndpointNameForQuery *string `json:"model_endpoint_name_for_query,omitempty"` +} + +func embeddingSourceColumnToWire(v *EmbeddingSourceColumn) (*embeddingSourceColumnWire, error) { + if v == nil { + return nil, nil + } + var embeddingConfigEmbeddingModelEndpointNameWire *string + switch value := v.EmbeddingConfig.(type) { + case nil: + case *EmbeddingSourceColumn_EmbeddingConfig_EmbeddingModelEndpointName: + if value != nil { + embeddingConfigEmbeddingModelEndpointNameWire = new(value.EmbeddingModelEndpointName) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "EmbeddingSourceColumn.EmbeddingConfig", value) + } + return &embeddingSourceColumnWire{ + Name: v.Name, + EmbeddingModelEndpointName: embeddingConfigEmbeddingModelEndpointNameWire, + ModelEndpointNameForQuery: v.ModelEndpointNameForQuery, + }, nil +} + +func embeddingSourceColumnFromWire(w *embeddingSourceColumnWire) (*EmbeddingSourceColumn, error) { + if w == nil { + return nil, nil + } + embeddingConfigMembers := 0 + if w.EmbeddingModelEndpointName != nil { + embeddingConfigMembers++ + } + if embeddingConfigMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "EmbeddingSourceColumn.EmbeddingConfig") + } + var embeddingConfigSelection isEmbeddingSourceColumn_EmbeddingConfig + switch { + case w.EmbeddingModelEndpointName != nil: + embeddingConfigSelection = &EmbeddingSourceColumn_EmbeddingConfig_EmbeddingModelEndpointName{EmbeddingModelEndpointName: *w.EmbeddingModelEndpointName} + } + return &EmbeddingSourceColumn{ + Name: w.Name, + ModelEndpointNameForQuery: w.ModelEndpointNameForQuery, + EmbeddingConfig: embeddingConfigSelection, + }, nil +} + +type embeddingVectorColumnWire struct { + Name *string `json:"name,omitempty"` + EmbeddingDimension *int `json:"embedding_dimension,omitempty"` +} + +func embeddingVectorColumnToWire(v *EmbeddingVectorColumn) (*embeddingVectorColumnWire, error) { + if v == nil { + return nil, nil + } + return &embeddingVectorColumnWire{ + Name: v.Name, + EmbeddingDimension: v.EmbeddingDimension, + }, nil +} + +func embeddingVectorColumnFromWire(w *embeddingVectorColumnWire) (*EmbeddingVectorColumn, error) { + if w == nil { + return nil, nil + } + return &EmbeddingVectorColumn{ + Name: w.Name, + EmbeddingDimension: w.EmbeddingDimension, + }, nil +} + +type endpointWire struct { + Name *string `json:"name,omitempty"` + Creator *string `json:"creator,omitempty"` + CreationTimestamp *int64 `json:"creation_timestamp,omitempty"` + LastUpdatedTimestamp *int64 `json:"last_updated_timestamp,omitempty"` + EndpointType EndpointType `json:"endpoint_type,omitempty"` + LastUpdatedUser *string `json:"last_updated_user,omitempty"` + Id *string `json:"id,omitempty"` + EndpointStatus *endpointStatusWire `json:"endpoint_status,omitempty"` + NumIndexes *int `json:"num_indexes,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + EffectiveBudgetPolicyId *string `json:"effective_budget_policy_id,omitempty"` + CustomTags []customTagWire `json:"custom_tags,omitempty"` + ScalingInfo *endpointScalingInfoWire `json:"scaling_info,omitempty"` +} + +func endpointFromWire(w *endpointWire) (*Endpoint, error) { + if w == nil { + return nil, nil + } + endpointStatusPublicValue, err := endpointStatusFromWire(w.EndpointStatus) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.EndpointStatus", err) + } + customTagsPublicValue, err := convertSlice(w.CustomTags, customTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.CustomTags", err) + } + scalingInfoPublicValue, err := endpointScalingInfoFromWire(w.ScalingInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Endpoint.ScalingInfo", err) + } + return &Endpoint{ + Name: w.Name, + Creator: w.Creator, + CreationTimestamp: w.CreationTimestamp, + LastUpdatedTimestamp: w.LastUpdatedTimestamp, + EndpointType: w.EndpointType, + LastUpdatedUser: w.LastUpdatedUser, + Id: w.Id, + EndpointStatus: endpointStatusPublicValue, + NumIndexes: w.NumIndexes, + BudgetPolicyId: w.BudgetPolicyId, + EffectiveBudgetPolicyId: w.EffectiveBudgetPolicyId, + CustomTags: customTagsPublicValue, + ScalingInfo: scalingInfoPublicValue, + }, nil +} + +type endpointScalingInfoWire struct { + State ScalingChangeState `json:"state,omitempty"` + RequestedTargetQps *int64 `json:"requested_target_qps,omitempty"` +} + +func endpointScalingInfoFromWire(w *endpointScalingInfoWire) (*EndpointScalingInfo, error) { + if w == nil { + return nil, nil + } + return &EndpointScalingInfo{ + State: w.State, + RequestedTargetQps: w.RequestedTargetQps, + }, nil +} + +type endpointStatusWire struct { + State EndpointStatus_State `json:"state,omitempty"` + Message *string `json:"message,omitempty"` +} + +func endpointStatusFromWire(w *endpointStatusWire) (*EndpointStatus, error) { + if w == nil { + return nil, nil + } + return &EndpointStatus{ + State: w.State, + Message: w.Message, + }, nil +} + +type facetResultDataWire struct { + FacetRowCount *int `json:"facet_row_count,omitempty"` + FacetArray [][]json.RawMessage `json:"facet_array,omitempty"` +} + +func facetResultDataFromWire(w *facetResultDataWire) (*FacetResultData, error) { + if w == nil { + return nil, nil + } + return &FacetResultData{ + FacetRowCount: w.FacetRowCount, + FacetArray: w.FacetArray, + }, nil +} + +type getVectorIndexRequestWire struct { + Name *string `json:"name,omitempty"` + EnsureRerankerCompatible *bool `json:"ensure_reranker_compatible,omitempty"` +} + +func getVectorIndexRequestToWire(v *GetVectorIndexRequest) (*getVectorIndexRequestWire, error) { + if v == nil { + return nil, nil + } + return &getVectorIndexRequestWire{ + Name: v.Name, + EnsureRerankerCompatible: v.EnsureRerankerCompatible, + }, nil +} + +type listEndpointResponseWire struct { + Endpoints []endpointWire `json:"endpoints,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listEndpointResponseFromWire(w *listEndpointResponseWire) (*ListEndpointResponse, error) { + if w == nil { + return nil, nil + } + endpointsPublicValue, err := convertSlice(w.Endpoints, endpointFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListEndpointResponse.Endpoints", err) + } + return &ListEndpointResponse{ + Endpoints: endpointsPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listEndpointsRequestWire struct { + PageToken *string `json:"page_token,omitempty"` +} + +func listEndpointsRequestToWire(v *ListEndpointsRequest) (*listEndpointsRequestWire, error) { + if v == nil { + return nil, nil + } + return &listEndpointsRequestWire{ + PageToken: v.PageToken, + }, nil +} + +type listValueWire struct { + Values []valueWire `json:"values,omitempty"` +} + +func listValueFromWire(w *listValueWire) (*ListValue, error) { + if w == nil { + return nil, nil + } + valuesPublicValue, err := convertSlice(w.Values, valueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListValue.Values", err) + } + return &ListValue{ + Values: valuesPublicValue, + }, nil +} + +type listVectorIndexRequestWire struct { + EndpointName *string `json:"endpoint_name,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listVectorIndexRequestToWire(v *ListVectorIndexRequest) (*listVectorIndexRequestWire, error) { + if v == nil { + return nil, nil + } + return &listVectorIndexRequestWire{ + EndpointName: v.EndpointName, + PageToken: v.PageToken, + }, nil +} + +type listVectorIndexResponseWire struct { + VectorIndexes []miniVectorIndexWire `json:"vector_indexes,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listVectorIndexResponseFromWire(w *listVectorIndexResponseWire) (*ListVectorIndexResponse, error) { + if w == nil { + return nil, nil + } + vectorIndexesPublicValue, err := convertSlice(w.VectorIndexes, miniVectorIndexFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListVectorIndexResponse.VectorIndexes", err) + } + return &ListVectorIndexResponse{ + VectorIndexes: vectorIndexesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type mapStringValueEntryWire struct { + Key *string `json:"key,omitempty"` + Value *valueWire `json:"value,omitempty"` +} + +func mapStringValueEntryFromWire(w *mapStringValueEntryWire) (*MapStringValueEntry, error) { + if w == nil { + return nil, nil + } + valuePublicValue, err := valueFromWire(w.Value) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MapStringValueEntry.Value", err) + } + return &MapStringValueEntry{ + Key: w.Key, + Value: valuePublicValue, + }, nil +} + +type metricWire struct { + Name *string `json:"name,omitempty"` + Labels []metricLabelWire `json:"labels,omitempty"` + Percentile *float64 `json:"percentile,omitempty"` +} + +func metricToWire(v *Metric) (*metricWire, error) { + if v == nil { + return nil, nil + } + labelsWireValue, err := convertSlice(v.Labels, metricLabelToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Metric.Labels", err) + } + return &metricWire{ + Name: v.Name, + Labels: labelsWireValue, + Percentile: v.Percentile, + }, nil +} + +func metricFromWire(w *metricWire) (*Metric, error) { + if w == nil { + return nil, nil + } + labelsPublicValue, err := convertSlice(w.Labels, metricLabelFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Metric.Labels", err) + } + return &Metric{ + Name: w.Name, + Labels: labelsPublicValue, + Percentile: w.Percentile, + }, nil +} + +type metricLabelWire struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` +} + +func metricLabelToWire(v *MetricLabel) (*metricLabelWire, error) { + if v == nil { + return nil, nil + } + return &metricLabelWire{ + Name: v.Name, + Value: v.Value, + }, nil +} + +func metricLabelFromWire(w *metricLabelWire) (*MetricLabel, error) { + if w == nil { + return nil, nil + } + return &MetricLabel{ + Name: w.Name, + Value: w.Value, + }, nil +} + +type metricValueWire struct { + Timestamp *int64 `json:"timestamp,omitempty"` + Value *float64 `json:"value,omitempty"` +} + +func metricValueFromWire(w *metricValueWire) (*MetricValue, error) { + if w == nil { + return nil, nil + } + return &MetricValue{ + Timestamp: w.Timestamp, + Value: w.Value, + }, nil +} + +type metricValuesWire struct { + Metric *metricWire `json:"metric,omitempty"` + Values []metricValueWire `json:"values,omitempty"` +} + +func metricValuesFromWire(w *metricValuesWire) (*MetricValues, error) { + if w == nil { + return nil, nil + } + metricPublicValue, err := metricFromWire(w.Metric) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MetricValues.Metric", err) + } + valuesPublicValue, err := convertSlice(w.Values, metricValueFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MetricValues.Values", err) + } + return &MetricValues{ + Metric: metricPublicValue, + Values: valuesPublicValue, + }, nil +} + +type miniVectorIndexWire struct { + Name *string `json:"name,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + PrimaryKey *string `json:"primary_key,omitempty"` + IndexType VectorIndexType `json:"index_type,omitempty"` + DirectAccessIndexSpec *directAccessVectorIndexSpecWire `json:"direct_access_index_spec,omitempty"` + DeltaSyncIndexSpec *deltaSyncVectorIndexSpecWire `json:"delta_sync_index_spec,omitempty"` + Status *vectorIndexStatusWire `json:"status,omitempty"` + Creator *string `json:"creator,omitempty"` + IndexSubtype IndexSubtype `json:"index_subtype,omitempty"` + EndpointId *string `json:"endpoint_id,omitempty"` +} + +func miniVectorIndexFromWire(w *miniVectorIndexWire) (*MiniVectorIndex, error) { + if w == nil { + return nil, nil + } + indexSpecMembers := 0 + if w.DirectAccessIndexSpec != nil { + indexSpecMembers++ + } + if w.DeltaSyncIndexSpec != nil { + indexSpecMembers++ + } + if indexSpecMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "MiniVectorIndex.IndexSpec") + } + statusPublicValue, err := vectorIndexStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MiniVectorIndex.Status", err) + } + var indexSpecSelection isMiniVectorIndex_IndexSpec + switch { + case w.DirectAccessIndexSpec != nil: + indexSpecDirectAccessIndexSpecConverted, err := directAccessVectorIndexSpecFromWire(w.DirectAccessIndexSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MiniVectorIndex.IndexSpec.DirectAccessIndexSpec", err) + } + indexSpecSelection = &MiniVectorIndex_IndexSpec_DirectAccessIndexSpec{DirectAccessIndexSpec: *indexSpecDirectAccessIndexSpecConverted} + case w.DeltaSyncIndexSpec != nil: + indexSpecDeltaSyncIndexSpecConverted, err := deltaSyncVectorIndexSpecFromWire(w.DeltaSyncIndexSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "MiniVectorIndex.IndexSpec.DeltaSyncIndexSpec", err) + } + indexSpecSelection = &MiniVectorIndex_IndexSpec_DeltaSyncIndexSpec{DeltaSyncIndexSpec: *indexSpecDeltaSyncIndexSpecConverted} + } + return &MiniVectorIndex{ + Name: w.Name, + EndpointName: w.EndpointName, + PrimaryKey: w.PrimaryKey, + IndexType: w.IndexType, + Status: statusPublicValue, + Creator: w.Creator, + IndexSubtype: w.IndexSubtype, + EndpointId: w.EndpointId, + IndexSpec: indexSpecSelection, + }, nil +} + +type patchEndpointBudgetPolicyRequestWire struct { + Name *string `json:"name,omitempty"` + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` +} + +func patchEndpointBudgetPolicyRequestToWire(v *PatchEndpointBudgetPolicyRequest) (*patchEndpointBudgetPolicyRequestWire, error) { + if v == nil { + return nil, nil + } + return &patchEndpointBudgetPolicyRequestWire{ + Name: v.Name, + BudgetPolicyId: v.BudgetPolicyId, + }, nil +} + +type patchEndpointBudgetPolicyResponseWire struct { + BudgetPolicyId *string `json:"budget_policy_id,omitempty"` + EffectiveBudgetPolicyId *string `json:"effective_budget_policy_id,omitempty"` +} + +func patchEndpointBudgetPolicyResponseFromWire(w *patchEndpointBudgetPolicyResponseWire) (*PatchEndpointBudgetPolicyResponse, error) { + if w == nil { + return nil, nil + } + return &PatchEndpointBudgetPolicyResponse{ + BudgetPolicyId: w.BudgetPolicyId, + EffectiveBudgetPolicyId: w.EffectiveBudgetPolicyId, + }, nil +} + +type patchEndpointRequestWire struct { + Name *string `json:"name,omitempty"` + TargetQps *int64 `json:"target_qps,omitempty"` +} + +func patchEndpointRequestToWire(v *PatchEndpointRequest) (*patchEndpointRequestWire, error) { + if v == nil { + return nil, nil + } + return &patchEndpointRequestWire{ + Name: v.Name, + TargetQps: v.TargetQps, + }, nil +} + +type queryVectorIndexNextPageRequestWire struct { + Name *string `json:"name,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func queryVectorIndexNextPageRequestToWire(v *QueryVectorIndexNextPageRequest) (*queryVectorIndexNextPageRequestWire, error) { + if v == nil { + return nil, nil + } + return &queryVectorIndexNextPageRequestWire{ + Name: v.Name, + EndpointName: v.EndpointName, + PageToken: v.PageToken, + }, nil +} + +type queryVectorIndexRequestWire struct { + Name *string `json:"name,omitempty"` + NumResults *int `json:"num_results,omitempty"` + Columns []string `json:"columns,omitempty"` + FiltersJson *string `json:"filters_json,omitempty"` + QueryVector []float32 `json:"query_vector,omitempty"` + QueryText *string `json:"query_text,omitempty"` + ScoreThreshold *float32 `json:"score_threshold,omitempty"` + QueryType *string `json:"query_type,omitempty"` + ColumnsToRerank []string `json:"columns_to_rerank,omitempty"` + Reranker *rerankerConfigWire `json:"reranker,omitempty"` + QueryColumns []string `json:"query_columns,omitempty"` + SortColumns []string `json:"sort_columns,omitempty"` + Facets []string `json:"facets,omitempty"` +} + +func queryVectorIndexRequestToWire(v *QueryVectorIndexRequest) (*queryVectorIndexRequestWire, error) { + if v == nil { + return nil, nil + } + rerankerWireValue, err := rerankerConfigToWire(v.Reranker) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryVectorIndexRequest.Reranker", err) + } + return &queryVectorIndexRequestWire{ + Name: v.Name, + NumResults: v.NumResults, + Columns: v.Columns, + FiltersJson: v.FiltersJson, + QueryVector: v.QueryVector, + QueryText: v.QueryText, + ScoreThreshold: v.ScoreThreshold, + QueryType: v.QueryType, + ColumnsToRerank: v.ColumnsToRerank, + Reranker: rerankerWireValue, + QueryColumns: v.QueryColumns, + SortColumns: v.SortColumns, + Facets: v.Facets, + }, nil +} + +type queryVectorIndexResponseWire struct { + Manifest *resultManifestWire `json:"manifest,omitempty"` + Result *resultDataWire `json:"result,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` + FacetResult *facetResultDataWire `json:"facet_result,omitempty"` +} + +func queryVectorIndexResponseFromWire(w *queryVectorIndexResponseWire) (*QueryVectorIndexResponse, error) { + if w == nil { + return nil, nil + } + manifestPublicValue, err := resultManifestFromWire(w.Manifest) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryVectorIndexResponse.Manifest", err) + } + resultPublicValue, err := resultDataFromWire(w.Result) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryVectorIndexResponse.Result", err) + } + facetResultPublicValue, err := facetResultDataFromWire(w.FacetResult) + if err != nil { + return nil, fmt.Errorf("%s: %w", "QueryVectorIndexResponse.FacetResult", err) + } + return &QueryVectorIndexResponse{ + Manifest: manifestPublicValue, + Result: resultPublicValue, + NextPageToken: w.NextPageToken, + FacetResult: facetResultPublicValue, + }, nil +} + +type rerankerConfigWire struct { + Model *string `json:"model,omitempty"` + Parameters *rerankerConfig_RerankerParametersWire `json:"parameters,omitempty"` +} + +func rerankerConfigToWire(v *RerankerConfig) (*rerankerConfigWire, error) { + if v == nil { + return nil, nil + } + parametersWireValue, err := rerankerConfig_RerankerParametersToWire(v.Parameters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RerankerConfig.Parameters", err) + } + return &rerankerConfigWire{ + Model: v.Model, + Parameters: parametersWireValue, + }, nil +} + +type rerankerConfig_RerankerParametersWire struct { + ColumnsToRerank []string `json:"columns_to_rerank,omitempty"` +} + +func rerankerConfig_RerankerParametersToWire(v *RerankerConfig_RerankerParameters) (*rerankerConfig_RerankerParametersWire, error) { + if v == nil { + return nil, nil + } + return &rerankerConfig_RerankerParametersWire{ + ColumnsToRerank: v.ColumnsToRerank, + }, nil +} + +type resultDataWire struct { + RowCount *int `json:"row_count,omitempty"` + DataArray [][]json.RawMessage `json:"data_array,omitempty"` +} + +func resultDataFromWire(w *resultDataWire) (*ResultData, error) { + if w == nil { + return nil, nil + } + return &ResultData{ + RowCount: w.RowCount, + DataArray: w.DataArray, + }, nil +} + +type resultManifestWire struct { + ColumnCount *int `json:"column_count,omitempty"` + Columns []columnInfoWire `json:"columns,omitempty"` + FacetColumnCount *int `json:"facet_column_count,omitempty"` + FacetColumns []columnInfoWire `json:"facet_columns,omitempty"` +} + +func resultManifestFromWire(w *resultManifestWire) (*ResultManifest, error) { + if w == nil { + return nil, nil + } + columnsPublicValue, err := convertSlice(w.Columns, columnInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResultManifest.Columns", err) + } + facetColumnsPublicValue, err := convertSlice(w.FacetColumns, columnInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ResultManifest.FacetColumns", err) + } + return &ResultManifest{ + ColumnCount: w.ColumnCount, + Columns: columnsPublicValue, + FacetColumnCount: w.FacetColumnCount, + FacetColumns: facetColumnsPublicValue, + }, nil +} + +type retrieveUserVisibleMetricsRequestWire struct { + Name *string `json:"name,omitempty"` + StartTime *types.Time `json:"start_time,omitempty"` + EndTime *types.Time `json:"end_time,omitempty"` + GranularityInSeconds *int `json:"granularity_in_seconds,omitempty"` + Metrics []metricWire `json:"metrics,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func retrieveUserVisibleMetricsRequestToWire(v *RetrieveUserVisibleMetricsRequest) (*retrieveUserVisibleMetricsRequestWire, error) { + if v == nil { + return nil, nil + } + metricsWireValue, err := convertSlice(v.Metrics, metricToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RetrieveUserVisibleMetricsRequest.Metrics", err) + } + return &retrieveUserVisibleMetricsRequestWire{ + Name: v.Name, + StartTime: v.StartTime, + EndTime: v.EndTime, + GranularityInSeconds: v.GranularityInSeconds, + Metrics: metricsWireValue, + PageToken: v.PageToken, + }, nil +} + +type retrieveUserVisibleMetricsResponseWire struct { + MetricValues []metricValuesWire `json:"metric_values,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func retrieveUserVisibleMetricsResponseFromWire(w *retrieveUserVisibleMetricsResponseWire) (*RetrieveUserVisibleMetricsResponse, error) { + if w == nil { + return nil, nil + } + metricValuesPublicValue, err := convertSlice(w.MetricValues, metricValuesFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RetrieveUserVisibleMetricsResponse.MetricValues", err) + } + return &RetrieveUserVisibleMetricsResponse{ + MetricValues: metricValuesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type scanVectorIndexRequestWire struct { + Name *string `json:"name,omitempty"` + NumResults *int `json:"num_results,omitempty"` + LastPrimaryKey *string `json:"last_primary_key,omitempty"` +} + +func scanVectorIndexRequestToWire(v *ScanVectorIndexRequest) (*scanVectorIndexRequestWire, error) { + if v == nil { + return nil, nil + } + return &scanVectorIndexRequestWire{ + Name: v.Name, + NumResults: v.NumResults, + LastPrimaryKey: v.LastPrimaryKey, + }, nil +} + +type scanVectorIndexResponseWire struct { + Data []structWire `json:"data,omitempty"` + LastPrimaryKey *string `json:"last_primary_key,omitempty"` +} + +func scanVectorIndexResponseFromWire(w *scanVectorIndexResponseWire) (*ScanVectorIndexResponse, error) { + if w == nil { + return nil, nil + } + dataPublicValue, err := convertSlice(w.Data, structFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ScanVectorIndexResponse.Data", err) + } + return &ScanVectorIndexResponse{ + Data: dataPublicValue, + LastPrimaryKey: w.LastPrimaryKey, + }, nil +} + +type structWire struct { + Fields []mapStringValueEntryWire `json:"fields,omitempty"` +} + +func structFromWire(w *structWire) (*Struct, error) { + if w == nil { + return nil, nil + } + fieldsPublicValue, err := convertSlice(w.Fields, mapStringValueEntryFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Struct.Fields", err) + } + return &Struct{ + Fields: fieldsPublicValue, + }, nil +} + +type syncVectorIndexRequestWire struct { + Name *string `json:"name,omitempty"` +} + +func syncVectorIndexRequestToWire(v *SyncVectorIndexRequest) (*syncVectorIndexRequestWire, error) { + if v == nil { + return nil, nil + } + return &syncVectorIndexRequestWire{ + Name: v.Name, + }, nil +} + +type updateEndpointCustomTagsRequestWire struct { + Name *string `json:"name,omitempty"` + CustomTags []customTagWire `json:"custom_tags,omitempty"` +} + +func updateEndpointCustomTagsRequestToWire(v *UpdateEndpointCustomTagsRequest) (*updateEndpointCustomTagsRequestWire, error) { + if v == nil { + return nil, nil + } + customTagsWireValue, err := convertSlice(v.CustomTags, customTagToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateEndpointCustomTagsRequest.CustomTags", err) + } + return &updateEndpointCustomTagsRequestWire{ + Name: v.Name, + CustomTags: customTagsWireValue, + }, nil +} + +type updateEndpointCustomTagsResponseWire struct { + Name *string `json:"name,omitempty"` + CustomTags []customTagWire `json:"custom_tags,omitempty"` +} + +func updateEndpointCustomTagsResponseFromWire(w *updateEndpointCustomTagsResponseWire) (*UpdateEndpointCustomTagsResponse, error) { + if w == nil { + return nil, nil + } + customTagsPublicValue, err := convertSlice(w.CustomTags, customTagFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateEndpointCustomTagsResponse.CustomTags", err) + } + return &UpdateEndpointCustomTagsResponse{ + Name: w.Name, + CustomTags: customTagsPublicValue, + }, nil +} + +type upsertDataVectorIndexRequestWire struct { + Name *string `json:"name,omitempty"` + InputsJson *string `json:"inputs_json,omitempty"` +} + +func upsertDataVectorIndexRequestToWire(v *UpsertDataVectorIndexRequest) (*upsertDataVectorIndexRequestWire, error) { + if v == nil { + return nil, nil + } + return &upsertDataVectorIndexRequestWire{ + Name: v.Name, + InputsJson: v.InputsJson, + }, nil +} + +type upsertDataVectorIndexResponseWire struct { + Status UpsertDeleteDataStatus `json:"status,omitempty"` + Result *upsertDeleteDataResultWire `json:"result,omitempty"` +} + +func upsertDataVectorIndexResponseFromWire(w *upsertDataVectorIndexResponseWire) (*UpsertDataVectorIndexResponse, error) { + if w == nil { + return nil, nil + } + resultPublicValue, err := upsertDeleteDataResultFromWire(w.Result) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpsertDataVectorIndexResponse.Result", err) + } + return &UpsertDataVectorIndexResponse{ + Status: w.Status, + Result: resultPublicValue, + }, nil +} + +type upsertDeleteDataResultWire struct { + SuccessRowCount *int64 `json:"success_row_count,omitempty"` + FailedPrimaryKeys []string `json:"failed_primary_keys,omitempty"` +} + +func upsertDeleteDataResultFromWire(w *upsertDeleteDataResultWire) (*UpsertDeleteDataResult, error) { + if w == nil { + return nil, nil + } + return &UpsertDeleteDataResult{ + SuccessRowCount: w.SuccessRowCount, + FailedPrimaryKeys: w.FailedPrimaryKeys, + }, nil +} + +type valueWire struct { + NumberValue *float64 `json:"number_value,omitempty"` + StringValue *string `json:"string_value,omitempty"` + BoolValue *bool `json:"bool_value,omitempty"` + StructValue *structWire `json:"struct_value,omitempty"` + ListValue *listValueWire `json:"list_value,omitempty"` +} + +func valueFromWire(w *valueWire) (*Value, error) { + if w == nil { + return nil, nil + } + kindMembers := 0 + if w.NumberValue != nil { + kindMembers++ + } + if w.StringValue != nil { + kindMembers++ + } + if w.BoolValue != nil { + kindMembers++ + } + if w.StructValue != nil { + kindMembers++ + } + if w.ListValue != nil { + kindMembers++ + } + if kindMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Value.Kind") + } + var kindSelection isValue_Kind + switch { + case w.NumberValue != nil: + kindSelection = &Value_Kind_NumberValue{NumberValue: *w.NumberValue} + case w.StringValue != nil: + kindSelection = &Value_Kind_StringValue{StringValue: *w.StringValue} + case w.BoolValue != nil: + kindSelection = &Value_Kind_BoolValue{BoolValue: *w.BoolValue} + case w.StructValue != nil: + kindStructValueConverted, err := structFromWire(w.StructValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Value.Kind.StructValue", err) + } + kindSelection = &Value_Kind_StructValue{StructValue: *kindStructValueConverted} + case w.ListValue != nil: + kindListValueConverted, err := listValueFromWire(w.ListValue) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Value.Kind.ListValue", err) + } + kindSelection = &Value_Kind_ListValue{ListValue: *kindListValueConverted} + } + return &Value{ + Kind: kindSelection, + }, nil +} + +type vectorIndexWire struct { + Name *string `json:"name,omitempty"` + EndpointName *string `json:"endpoint_name,omitempty"` + PrimaryKey *string `json:"primary_key,omitempty"` + IndexType VectorIndexType `json:"index_type,omitempty"` + DirectAccessIndexSpec *directAccessVectorIndexSpecWire `json:"direct_access_index_spec,omitempty"` + DeltaSyncIndexSpec *deltaSyncVectorIndexSpecWire `json:"delta_sync_index_spec,omitempty"` + Status *vectorIndexStatusWire `json:"status,omitempty"` + Creator *string `json:"creator,omitempty"` + IndexSubtype IndexSubtype `json:"index_subtype,omitempty"` + EndpointId *string `json:"endpoint_id,omitempty"` +} + +func vectorIndexFromWire(w *vectorIndexWire) (*VectorIndex, error) { + if w == nil { + return nil, nil + } + indexSpecMembers := 0 + if w.DirectAccessIndexSpec != nil { + indexSpecMembers++ + } + if w.DeltaSyncIndexSpec != nil { + indexSpecMembers++ + } + if indexSpecMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "VectorIndex.IndexSpec") + } + statusPublicValue, err := vectorIndexStatusFromWire(w.Status) + if err != nil { + return nil, fmt.Errorf("%s: %w", "VectorIndex.Status", err) + } + var indexSpecSelection isVectorIndex_IndexSpec + switch { + case w.DirectAccessIndexSpec != nil: + indexSpecDirectAccessIndexSpecConverted, err := directAccessVectorIndexSpecFromWire(w.DirectAccessIndexSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "VectorIndex.IndexSpec.DirectAccessIndexSpec", err) + } + indexSpecSelection = &VectorIndex_IndexSpec_DirectAccessIndexSpec{DirectAccessIndexSpec: *indexSpecDirectAccessIndexSpecConverted} + case w.DeltaSyncIndexSpec != nil: + indexSpecDeltaSyncIndexSpecConverted, err := deltaSyncVectorIndexSpecFromWire(w.DeltaSyncIndexSpec) + if err != nil { + return nil, fmt.Errorf("%s: %w", "VectorIndex.IndexSpec.DeltaSyncIndexSpec", err) + } + indexSpecSelection = &VectorIndex_IndexSpec_DeltaSyncIndexSpec{DeltaSyncIndexSpec: *indexSpecDeltaSyncIndexSpecConverted} + } + return &VectorIndex{ + Name: w.Name, + EndpointName: w.EndpointName, + PrimaryKey: w.PrimaryKey, + IndexType: w.IndexType, + Status: statusPublicValue, + Creator: w.Creator, + IndexSubtype: w.IndexSubtype, + EndpointId: w.EndpointId, + IndexSpec: indexSpecSelection, + }, nil +} + +type vectorIndexStatusWire struct { + Message *string `json:"message,omitempty"` + IndexedRowCount *int64 `json:"indexed_row_count,omitempty"` + Ready *bool `json:"ready,omitempty"` + IndexUrl *string `json:"index_url,omitempty"` +} + +func vectorIndexStatusFromWire(w *vectorIndexStatusWire) (*VectorIndexStatus, error) { + if w == nil { + return nil, nil + } + return &VectorIndexStatus{ + Message: w.Message, + IndexedRowCount: w.IndexedRowCount, + Ready: w.Ready, + IndexUrl: w.IndexUrl, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/warehouses/.package.json b/warehouses/.package.json new file mode 100644 index 0000000..a8b6e19 --- /dev/null +++ b/warehouses/.package.json @@ -0,0 +1,3 @@ +{ + "package": "warehouses" +} diff --git a/warehouses/CHANGELOG.md b/warehouses/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/warehouses/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/warehouses/README.md b/warehouses/README.md new file mode 100644 index 0000000..87e2ad0 --- /dev/null +++ b/warehouses/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/warehouses + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/warehouses@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/warehouses/v1" + +client, err := warehouses.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/warehouses/go.mod b/warehouses/go.mod new file mode 100644 index 0000000..1f48161 --- /dev/null +++ b/warehouses/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/warehouses + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/warehouses/internal/version.go b/warehouses/internal/version.go new file mode 100644 index 0000000..f1b7501 --- /dev/null +++ b/warehouses/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-warehouses" + +const Version = "0.0.1-dev.1" diff --git a/warehouses/v1/client.go b/warehouses/v1/client.go new file mode 100755 index 0000000..d9faf92 --- /dev/null +++ b/warehouses/v1/client.go @@ -0,0 +1,1376 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package warehouses + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "iter" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" + "github.com/databricks/sdk-go/warehouses/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new default warehouse override for a user. Users can create their +// own override. Admins can create overrides for any user. +func (c *internalClient) CreateDefaultWarehouseOverride(ctx context.Context, req *CreateDefaultWarehouseOverrideRequest, opts ...call.Option) (*DefaultWarehouseOverride, error) { + wireReq, err := createDefaultWarehouseOverrideRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.DefaultWarehouseOverride) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/warehouses/v1/default-warehouse-overrides" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "default_warehouse_override_id", wireReq.DefaultWarehouseOverrideId); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DefaultWarehouseOverride + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp defaultWarehouseOverrideWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = defaultWarehouseOverrideFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new SQL warehouse. +func (c *internalClient) createWarehouseBase(ctx context.Context, req *CreateWarehouseRequest, opts ...call.Option) (*CreateWarehouseResponse, error) { + wireReq, err := createWarehouseRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/sql/warehouses" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *CreateWarehouseResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp createWarehouseResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = createWarehouseResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new SQL warehouse. +func (c *internalClient) CreateWarehouse(ctx context.Context, req *CreateWarehouseRequest, opts ...call.Option) (*CreateWarehouseWaiter, error) { + resp, err := c.createWarehouseBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.Id == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "Id") + } + return &CreateWarehouseWaiter{ + poll: c.GetWarehouse, + id: *resp.Id, + }, nil +} + +// CreateWarehouseWaiter tracks the state of the operation started by CreateWarehouse. +type CreateWarehouseWaiter struct { + poll func(context.Context, *GetWarehouseRequest, ...call.Option) (*GetWarehouseResponse, error) + id string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateWarehouseWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetWarehouseRequest{ + Id: &w.id, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case EndpointState_Running, EndpointState_Stopped, EndpointState_Deleted: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateWarehouseWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetWarehouseResponse, error) { + var result *GetWarehouseResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetWarehouseRequest{ + Id: &w.id, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case EndpointState_Running: + result = pollResp + return nil + case EndpointState_Stopped, EndpointState_Deleted: + message := "(no message)" + if pollResp.Health != nil && pollResp.Health.Summary != nil { + message = fmt.Sprintf("%v", *pollResp.Health.Summary) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Deletes the default warehouse override for a user. Users can delete their own +// override. Admins can delete overrides for any user. After deletion, the +// workspace default warehouse will be used. +func (c *internalClient) DeleteDefaultWarehouseOverride(ctx context.Context, req *DeleteDefaultWarehouseOverrideRequest, opts ...call.Option) error { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return err + } + pb := pathBuilder{} + pb.literal("/api/warehouses/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return err + } + return nil +} + +// Deletes a SQL warehouse. +func (c *internalClient) DeleteWarehouse(ctx context.Context, req *DeleteWarehouseRequest, opts ...call.Option) (*DeleteWarehouseResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/warehouses/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DeleteWarehouseResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &DeleteWarehouseResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the configuration for a SQL warehouse. +func (c *internalClient) editWarehouseBase(ctx context.Context, req *EditWarehouseRequest, opts ...call.Option) (*EditWarehouseResponse, error) { + wireReq, err := editWarehouseRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/warehouses/") + pb.singleSegment(*req.Id) + pb.literal("/edit") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *EditWarehouseResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &EditWarehouseResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates the configuration for a SQL warehouse. +func (c *internalClient) EditWarehouse(ctx context.Context, req *EditWarehouseRequest, opts ...call.Option) (*EditWarehouseWaiter, error) { + if req.Id == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "Id") + } + capturedId := *req.Id + _, err := c.editWarehouseBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &EditWarehouseWaiter{ + poll: c.GetWarehouse, + id: capturedId, + }, nil +} + +// EditWarehouseWaiter tracks the state of the operation started by EditWarehouse. +type EditWarehouseWaiter struct { + poll func(context.Context, *GetWarehouseRequest, ...call.Option) (*GetWarehouseResponse, error) + id string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *EditWarehouseWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetWarehouseRequest{ + Id: &w.id, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case EndpointState_Running, EndpointState_Stopped, EndpointState_Deleted: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *EditWarehouseWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetWarehouseResponse, error) { + var result *GetWarehouseResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetWarehouseRequest{ + Id: &w.id, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case EndpointState_Running: + result = pollResp + return nil + case EndpointState_Stopped, EndpointState_Deleted: + message := "(no message)" + if pollResp.Health != nil && pollResp.Health.Summary != nil { + message = fmt.Sprintf("%v", *pollResp.Health.Summary) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Returns the default warehouse override for a user. Users can fetch their own +// override. Admins can fetch overrides for any user. If no override exists, the +// UI will fallback to the workspace default warehouse. +func (c *internalClient) GetDefaultWarehouseOverride(ctx context.Context, req *GetDefaultWarehouseOverrideRequest, opts ...call.Option) (*DefaultWarehouseOverride, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/warehouses/v1/") + pb.singleSegment(*req.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DefaultWarehouseOverride + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp defaultWarehouseOverrideWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = defaultWarehouseOverrideFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the information for a single SQL warehouse. +func (c *internalClient) GetWarehouse(ctx context.Context, req *GetWarehouseRequest, opts ...call.Option) (*GetWarehouseResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/warehouses/") + pb.singleSegment(*req.Id) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetWarehouseResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getWarehouseResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getWarehouseResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets the workspace level configuration that is shared by all SQL warehouses +// in a workspace. +func (c *internalClient) GetWorkspaceWarehouseConfig(ctx context.Context, req *GetWorkspaceWarehouseConfigRequest, opts ...call.Option) (*GetWorkspaceWarehouseConfigResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/sql/config/warehouses" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *GetWorkspaceWarehouseConfigResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp getWorkspaceWarehouseConfigResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = getWorkspaceWarehouseConfigResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists all default warehouse overrides in the workspace. Only workspace +// administrators can list all overrides. +func (c *internalClient) ListDefaultWarehouseOverrides(ctx context.Context, req *ListDefaultWarehouseOverridesRequest, opts ...call.Option) (*ListDefaultWarehouseOverridesResponse, error) { + wireReq, err := listDefaultWarehouseOverridesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/warehouses/v1/default-warehouse-overrides" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListDefaultWarehouseOverridesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listDefaultWarehouseOverridesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listDefaultWarehouseOverridesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListDefaultWarehouseOverridesIter returns an iterator that iterates +// over the results of ListDefaultWarehouseOverrides. +// +// For example: +// +// for item, err := range c.ListDefaultWarehouseOverridesIter(ctx, &ListDefaultWarehouseOverridesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListDefaultWarehouseOverrides call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListDefaultWarehouseOverrides directly. +func (c *internalClient) ListDefaultWarehouseOverridesIter(ctx context.Context, req *ListDefaultWarehouseOverridesRequest, opts ...call.Option) iter.Seq2[*DefaultWarehouseOverride, error] { + return func(yield func(*DefaultWarehouseOverride, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListDefaultWarehouseOverridesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListDefaultWarehouseOverrides(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.DefaultWarehouseOverrides { + if !yield(&resp.DefaultWarehouseOverrides[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Lists all SQL warehouses that a user has access to. +func (c *internalClient) ListWarehouses(ctx context.Context, req *ListWarehousesRequest, opts ...call.Option) (*ListWarehousesResponse, error) { + wireReq, err := listWarehousesRequestToWire(req) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/sql/warehouses" + queryParams := url.Values{} + if err := addQueryValue(queryParams, "run_as_user_id", wireReq.RunAsUserId); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_size", wireReq.PageSize); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "page_token", wireReq.PageToken); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListWarehousesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp listWarehousesResponseWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = listWarehousesResponseFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// ListWarehousesIter returns an iterator that iterates +// over the results of ListWarehouses. +// +// For example: +// +// for item, err := range c.ListWarehousesIter(ctx, &ListWarehousesRequest{}) { +// if err != nil { +// return err +// } +// fmt.Println(item) +// } +// +// Options opts are passed to each ListWarehouses call +// made by the iterator under the hood. +// +// Callers who need custom pagination logic should use +// ListWarehouses directly. +func (c *internalClient) ListWarehousesIter(ctx context.Context, req *ListWarehousesRequest, opts ...call.Option) iter.Seq2[*EndpointInfo, error] { + return func(yield func(*EndpointInfo, error) bool) { + // Copy the request so advancing the pagination field does not mutate the + // caller's struct. Other reference-bearing fields are shared and must remain read-only. + pageReq := ListWarehousesRequest{} + if req != nil { + pageReq = *req + } + for { + resp, err := c.ListWarehouses(ctx, &pageReq, opts...) + if err != nil { + yield(nil, err) + return + } + for i := range resp.Warehouses { + if !yield(&resp.Warehouses[i], nil) { + return + } + } + if resp.NextPageToken == nil || *resp.NextPageToken == "" { + return + } + pageReq.PageToken = resp.NextPageToken + } + } +} + +// Sets the workspace level configuration that is shared by all SQL warehouses +// in a workspace. +func (c *internalClient) SetWorkspaceWarehouseConfig(ctx context.Context, req *SetWorkspaceWarehouseConfigRequest, opts ...call.Option) (*SetWorkspaceWarehouseConfigResponse, error) { + wireReq, err := setWorkspaceWarehouseConfigRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + baseURL.Path = "/api/2.0/sql/config/warehouses" + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *SetWorkspaceWarehouseConfigResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PUT", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &SetWorkspaceWarehouseConfigResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Starts a SQL warehouse. +func (c *internalClient) startWarehouseBase(ctx context.Context, req *StartRequest, opts ...call.Option) (*StartResponse, error) { + wireReq, err := startRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/warehouses/") + pb.singleSegment(*req.Id) + pb.literal("/start") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StartResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &StartResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Starts a SQL warehouse. +func (c *internalClient) StartWarehouse(ctx context.Context, req *StartRequest, opts ...call.Option) (*StartWarehouseWaiter, error) { + if req.Id == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "Id") + } + capturedId := *req.Id + _, err := c.startWarehouseBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &StartWarehouseWaiter{ + poll: c.GetWarehouse, + id: capturedId, + }, nil +} + +// StartWarehouseWaiter tracks the state of the operation started by StartWarehouse. +type StartWarehouseWaiter struct { + poll func(context.Context, *GetWarehouseRequest, ...call.Option) (*GetWarehouseResponse, error) + id string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *StartWarehouseWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetWarehouseRequest{ + Id: &w.id, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case EndpointState_Running, EndpointState_Stopped, EndpointState_Deleted: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *StartWarehouseWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetWarehouseResponse, error) { + var result *GetWarehouseResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetWarehouseRequest{ + Id: &w.id, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case EndpointState_Running: + result = pollResp + return nil + case EndpointState_Stopped, EndpointState_Deleted: + message := "(no message)" + if pollResp.Health != nil && pollResp.Health.Summary != nil { + message = fmt.Sprintf("%v", *pollResp.Health.Summary) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Stops a SQL warehouse. +func (c *internalClient) stopWarehouseBase(ctx context.Context, req *StopRequest, opts ...call.Option) (*StopResponse, error) { + wireReq, err := stopRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/2.0/sql/warehouses/") + pb.singleSegment(*req.Id) + pb.literal("/stop") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *StopResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + _ = respBody + resp = &StopResponse{} + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Stops a SQL warehouse. +func (c *internalClient) StopWarehouse(ctx context.Context, req *StopRequest, opts ...call.Option) (*StopWarehouseWaiter, error) { + if req.Id == nil { + return nil, fmt.Errorf("request field %q required for polling is missing", "Id") + } + capturedId := *req.Id + _, err := c.stopWarehouseBase(ctx, req, opts...) + if err != nil { + return nil, err + } + return &StopWarehouseWaiter{ + poll: c.GetWarehouse, + id: capturedId, + }, nil +} + +// StopWarehouseWaiter tracks the state of the operation started by StopWarehouse. +type StopWarehouseWaiter struct { + poll func(context.Context, *GetWarehouseRequest, ...call.Option) (*GetWarehouseResponse, error) + id string +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *StopWarehouseWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetWarehouseRequest{ + Id: &w.id, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case EndpointState_Stopped: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *StopWarehouseWaiter) Wait(ctx context.Context, opts ...lro.Option) (*GetWarehouseResponse, error) { + var result *GetWarehouseResponse + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetWarehouseRequest{ + Id: &w.id, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.State + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case EndpointState_Stopped: + result = pollResp + return nil + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Updates an existing default warehouse override for a user. Users can update +// their own override. Admins can update overrides for any user. +func (c *internalClient) UpdateDefaultWarehouseOverride(ctx context.Context, req *UpdateDefaultWarehouseOverrideRequest, opts ...call.Option) (*DefaultWarehouseOverride, error) { + wireReq, err := updateDefaultWarehouseOverrideRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.DefaultWarehouseOverride) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + if c.workspaceID != "" { + headers.Set("X-Databricks-Workspace-Id", c.workspaceID) + } + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + pb := pathBuilder{} + pb.literal("/api/warehouses/v1/") + pb.singleSegment(*req.DefaultWarehouseOverride.Name) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + if err := addQueryValue(queryParams, "allow_missing", wireReq.AllowMissing); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *DefaultWarehouseOverride + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp defaultWarehouseOverrideWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = defaultWarehouseOverrideFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} diff --git a/warehouses/v1/genhelper.go b/warehouses/v1/genhelper.go new file mode 100755 index 0000000..2b74409 --- /dev/null +++ b/warehouses/v1/genhelper.go @@ -0,0 +1,243 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package warehouses + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/warehouses/v1/model.go b/warehouses/v1/model.go new file mode 100755 index 0000000..ac5e733 --- /dev/null +++ b/warehouses/v1/model.go @@ -0,0 +1,1212 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package warehouses + +import ( + "github.com/databricks/sdk-go/core/types" +) + +type ChannelName string + +const ( + ChannelName_Unspecified ChannelName = "" + ChannelName_ChannelNamePreview ChannelName = "CHANNEL_NAME_PREVIEW" + ChannelName_ChannelNameCurrent ChannelName = "CHANNEL_NAME_CURRENT" + ChannelName_ChannelNamePrevious ChannelName = "CHANNEL_NAME_PREVIOUS" + ChannelName_ChannelNameCustom ChannelName = "CHANNEL_NAME_CUSTOM" +) + +// Type of default warehouse override behavior. +type DefaultWarehouseOverrideType string + +const ( + DefaultWarehouseOverrideType_Unspecified DefaultWarehouseOverrideType = "" + // The user should remember their last-selected warehouse. + DefaultWarehouseOverrideType_LastSelected DefaultWarehouseOverrideType = "LAST_SELECTED" + // The user should use a specific warehouse. + DefaultWarehouseOverrideType_Custom DefaultWarehouseOverrideType = "CUSTOM" +) + +// Security policy to be used for warehouses +type EndpointSecurityPolicy string + +const ( + EndpointSecurityPolicy_Unspecified EndpointSecurityPolicy = "" + // No passthrough or Table ACLs support + EndpointSecurityPolicy_None EndpointSecurityPolicy = "NONE" + // Support only Table ACLs + EndpointSecurityPolicy_DataAccessControl EndpointSecurityPolicy = "DATA_ACCESS_CONTROL" + // Support only ADLS / IAM passthrough + EndpointSecurityPolicy_Passthrough EndpointSecurityPolicy = "PASSTHROUGH" +) + +// EndpointSpotInstancePolicy configures whether the endpoint should use spot +// instances. +// +// The breakdown of how the EndpointSpotInstancePolicy converts to per cloud +// configurations is: +// +// +-------+--------------------------------------+--------------------------------+ +// | Cloud | COST_OPTIMIZED | RELIABILITY_OPTIMIZED | +// +-------+--------------------------------------+--------------------------------+ +// | AWS | On Demand Driver with Spot Executors | On Demand Driver and Executors +// | | AZURE | On Demand Driver and Executors | On Demand Driver and Executors | +// +-------+--------------------------------------+--------------------------------+ +type EndpointSpotInstancePolicy string + +const ( + EndpointSpotInstancePolicy_Unspecified EndpointSpotInstancePolicy = "" + // COST_OPTIMIZED to prefer spot instance. + EndpointSpotInstancePolicy_CostOptimized EndpointSpotInstancePolicy = "COST_OPTIMIZED" + // RELIABILITY_OPTIMIZED to prefer on demand instance. + EndpointSpotInstancePolicy_ReliabilityOptimized EndpointSpotInstancePolicy = "RELIABILITY_OPTIMIZED" +) + +// * State of a warehouse. +type EndpointState string + +const ( + EndpointState_Unspecified EndpointState = "" + // Indicates that the endpoint is in the process of starting + EndpointState_Starting EndpointState = "STARTING" + // Indicates the starting process is done, and the endpoint is ready to use + EndpointState_Running EndpointState = "RUNNING" + // Indicates the endpoint is in the process of destroying + EndpointState_Stopping EndpointState = "STOPPING" + // Indicates the endpoint is stopped, but can be started by calling start + EndpointState_Stopped EndpointState = "STOPPED" + // Indicates the endpoint is in the process of destroying + EndpointState_Deleting EndpointState = "DELETING" + // Indicates an endpoint is deleted, and can not be recovered + EndpointState_Deleted EndpointState = "DELETED" +) + +// The status code indicating why the cluster was terminated +type TerminationCode string + +const ( + TerminationCode_Unspecified TerminationCode = "" + // A user terminated the cluster directly. Parameters should include a + // ``username`` field that indicates the specific user who terminated the + // cluster. + TerminationCode_UserRequest TerminationCode = "USER_REQUEST" + // This cluster was launched by a Job, and terminated when the Job completed. + TerminationCode_JobFinished TerminationCode = "JOB_FINISHED" + // This cluster was terminated since it was idle. + TerminationCode_Inactivity TerminationCode = "INACTIVITY" + // The instance that hosted the spark driver was terminated by the cloud + // provider. In AWS, for example, AWS may retire instances and directly shut + // them down. Parameters should include an ``aws_instance_state_reason`` field + // indicating the AWS-provided reason why the instance was terminated. + TerminationCode_CloudProviderShutdown TerminationCode = "CLOUD_PROVIDER_SHUTDOWN" + // Databricks may lose connection to services on the driver instance. One such + // case is when problems arise in cloud networking infrastructure, or when the + // instance itself becomes unhealthy. + TerminationCode_CommunicationLost TerminationCode = "COMMUNICATION_LOST" + // Databricks may hit cloud provider failures when requesting instances to + // launch clusters. For example, AWS limits the number of running instances and + // EBS volumes. If you ask Databricks to launch a cluster that requires + // instances or EBS volumes that exceed your AWS limit, the cluster will fail + // with this status code. Parameters should include one of + // ``aws_api_error_code``, ``aws_instance_state_reason``, or + // ``aws_spot_request_status`` to indicate the AWS-provided reason why + // Databricks could not request the required instances for the cluster. + TerminationCode_CloudProviderLaunchFailure TerminationCode = "CLOUD_PROVIDER_LAUNCH_FAILURE" + // Databricks cannot load and execute a cluster-scoped init script on one of the + // cluster's nodes, or the init script terminates with a non-zero exit code or + // there was a general failure during the loading/executing of init scripts that + // does not pertain to any specific script. + TerminationCode_InitScriptFailure TerminationCode = "INIT_SCRIPT_FAILURE" + // The Spark driver failed to start. Possible reasons may include incompatible + // libraries and initialization scripts that corrupted the Spark container. + TerminationCode_SparkStartupFailure TerminationCode = "SPARK_STARTUP_FAILURE" + // Cannot launch the cluster because the user specified an invalid argument. For + // example, the use might specify an invalid spark version for the cluster. + TerminationCode_InvalidArgument TerminationCode = "INVALID_ARGUMENT" + // While launching this cluster, Databricks failed to complete critical setup + // steps, terminating the cluster. + TerminationCode_UnexpectedLaunchFailure TerminationCode = "UNEXPECTED_LAUNCH_FAILURE" + // Databricks encountered an unexpected error which forced the running cluster + // to be terminated. Please contact Databricks support for additional details. + TerminationCode_InternalError TerminationCode = "INTERNAL_ERROR" + // Databricks was not able to access instances in order to start the cluster. + // This can be a transient networking issue. If the problem persists, this + // usually indicates a networking environment misconfiguration. + TerminationCode_InstanceUnreachable TerminationCode = "INSTANCE_UNREACHABLE" + // Blocked upsize requests for the workspace according to + // https://databricks.atlassian.net/wiki/spaces/UN/pages/934088320/Banning+Workspace+Upsize+Runbook + TerminationCode_RequestRejected TerminationCode = "REQUEST_REJECTED" + // The cluster was terminated because it was running in a trial workspace that + // expired. + TerminationCode_TrialExpired TerminationCode = "TRIAL_EXPIRED" + // The cluster was terminated because no response from the chauffeur could be + // received. We name this "DRIVER_" instead of "CHAUFFEUR_" since chauffeur is + // non-external terminology + TerminationCode_DriverUnreachable TerminationCode = "DRIVER_UNREACHABLE" + // Spark error on startup + TerminationCode_SparkError TerminationCode = "SPARK_ERROR" + // Driver unresponsive + TerminationCode_DriverUnresponsive TerminationCode = "DRIVER_UNRESPONSIVE" + // Metastore component unhealthy + TerminationCode_MetastoreComponentUnhealthy TerminationCode = "METASTORE_COMPONENT_UNHEALTHY" + // DBFS component unhealthy + TerminationCode_DbfsComponentUnhealthy TerminationCode = "DBFS_COMPONENT_UNHEALTHY" + // Execution component unhealthy + TerminationCode_ExecutionComponentUnhealthy TerminationCode = "EXECUTION_COMPONENT_UNHEALTHY" + // Databricks may hit the azure resource manager request limit. Which will keep + // the Azure SDK from issuing any read or write request to Azure resource + // manager. The request limit is applied to each subscription every hour, thus + // retry after an hour or changing to a smaller cluster size might help to + // resolve the issue. Please check the following link for more information: + // https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-request-limits + TerminationCode_AzureResourceManagerThrottling TerminationCode = "AZURE_RESOURCE_MANAGER_THROTTLING" + // Databricks may hit the azure resource provider request limit. Specifically, + // the API request rate to the specific resource type (Compute, Network, etc..) + // can't exceed the limit. Retry might help to resolve the issue. Please check + // the following link for more information: + // https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/ + // troubleshooting-throttling-errors + TerminationCode_AzureResourceProviderThrottling TerminationCode = "AZURE_RESOURCE_PROVIDER_THROTTLING" + // The cluster was terminated due to an error in the network configuration. + TerminationCode_NetworkConfigurationFailure TerminationCode = "NETWORK_CONFIGURATION_FAILURE" + // Databricks encountered an unexpected error while launching containers on + // worker nodes for the cluster, terminating the cluster. + TerminationCode_ContainerLaunchFailure TerminationCode = "CONTAINER_LAUNCH_FAILURE" + // Instance pool backed cluster specific failure + TerminationCode_InstancePoolClusterFailure TerminationCode = "INSTANCE_POOL_CLUSTER_FAILURE" + // Cluster start successfully completed but skipped some instances which were + // slow to launch + TerminationCode_SkippedSlowNodes TerminationCode = "SKIPPED_SLOW_NODES" + // Attach projects failure + TerminationCode_AttachProjectFailure TerminationCode = "ATTACH_PROJECT_FAILURE" + // Attach projects failure + TerminationCode_UpdateInstanceProfileFailure TerminationCode = "UPDATE_INSTANCE_PROFILE_FAILURE" + // Cluster terminated due to database failure + TerminationCode_DatabaseConnectionFailure TerminationCode = "DATABASE_CONNECTION_FAILURE" + // Databricks cannot handle the request at this moment. Please try again later + // and contact Databricks if the problem persists. + TerminationCode_RequestThrottled TerminationCode = "REQUEST_THROTTLED" + // SelfBootstrap failure. Either self-bootstrap fast fail or node daemon ping + // timeout + TerminationCode_SelfBootstrapFailure TerminationCode = "SELF_BOOTSTRAP_FAILURE" + // Databricks cannot load and execute a global init script on one of the + // cluster's nodes, or the init script terminates with a non-zero exit code. + TerminationCode_GlobalInitScriptFailure TerminationCode = "GLOBAL_INIT_SCRIPT_FAILURE" + // Container launch timed out downloading the spark image. This can happen if + // the customer has byo-vpc/vnet and the download of large files is being + // throttled. + TerminationCode_SlowImageDownload TerminationCode = "SLOW_IMAGE_DOWNLOAD" + // Container setup failed due to an invalid Spark image. + TerminationCode_InvalidSparkImage TerminationCode = "INVALID_SPARK_IMAGE" + // If the ngrok tunnel token provisioning fails for any reason, for example + // hitting the max capacity of allowed ngrok tokens. (ES-32083) + TerminationCode_NpipTunnelTokenFailure TerminationCode = "NPIP_TUNNEL_TOKEN_FAILURE" + // Hive Metastore provisioning failue in launch container step + TerminationCode_HiveMetastoreProvisioningFailure TerminationCode = "HIVE_METASTORE_PROVISIONING_FAILURE" + // Occurs when the deployment template we submit to Azure violates their + // requirements. Typical scenarios: - Wrong parameter key/value used - Exceed + // the limit for certain parameter + TerminationCode_AzureInvalidDeploymentTemplate TerminationCode = "AZURE_INVALID_DEPLOYMENT_TEMPLATE" + // The set of un-categorized failure responses from Azure when we launch + // instance resources using deployment template + TerminationCode_AzureUnexpectedDeploymentTemplateFailure TerminationCode = "AZURE_UNEXPECTED_DEPLOYMENT_TEMPLATE_FAILURE" + // Subnet (typically Azure vnet injected) has run out of ip addresses + TerminationCode_SubnetExhaustedFailure TerminationCode = "SUBNET_EXHAUSTED_FAILURE" + // Timeout to ping the nodeDaemon, possible reason: nodeDaemon didn't start + // (configuration issue), network connectivity issue + TerminationCode_BootstrapTimeout TerminationCode = "BOOTSTRAP_TIMEOUT" + // Bootstrap timeout due to script download failure + TerminationCode_StorageDownloadFailure TerminationCode = "STORAGE_DOWNLOAD_FAILURE" + // Bootstrap timeout due to get runbook failure + TerminationCode_ControlPlaneRequestFailure TerminationCode = "CONTROL_PLANE_REQUEST_FAILURE" + // Bootstrap timeout due to Azure Extension Service Failure + TerminationCode_BootstrapTimeoutCloudProviderException TerminationCode = "BOOTSTRAP_TIMEOUT_CLOUD_PROVIDER_EXCEPTION" + // Could not find enough of the requested instance type in the requested AZ. + // Often related to Auto AZ. + TerminationCode_AwsInsufficientInstanceCapacityFailure TerminationCode = "AWS_INSUFFICIENT_INSTANCE_CAPACITY_FAILURE" + // Container setup failure due to docker image pulling failure + TerminationCode_DockerImagePullFailure TerminationCode = "DOCKER_IMAGE_PULL_FAILURE" + // Failures during azure vnet configuration. For example, a workspace with VNet + // injection had incorrect DNS settings that blocked access to worker artifacts. + TerminationCode_AzureVnetConfigurationFailure TerminationCode = "AZURE_VNET_CONFIGURATION_FAILURE" + // Bootstrap failure due to Ngrok tunnel setup timeout or failure. For example, + // if the worker node is unable to reach the Ngrok tunnel domain. + TerminationCode_NpipTunnelSetupFailure TerminationCode = "NPIP_TUNNEL_SETUP_FAILURE" + // Lack authorization for cluster operation. For example, awsApiErrorCode: + // 'AccessDenied' or 'UnauthorizedOperation'. + TerminationCode_AwsAuthorizationFailure TerminationCode = "AWS_AUTHORIZATION_FAILURE" + // request comes form Nephos resource pool auto management + TerminationCode_NephosResourceManagement TerminationCode = "NEPHOS_RESOURCE_MANAGEMENT" + // Container setup failed during container registration to security daemon due + // to STS endpoint connection error. + TerminationCode_StsClientSetupFailure TerminationCode = "STS_CLIENT_SETUP_FAILURE" + // Container setup failed during registration to security daemon due to an + // unspecified error. + TerminationCode_SecurityDaemonRegistrationException TerminationCode = "SECURITY_DAEMON_REGISTRATION_EXCEPTION" + // The maximum request rate permitted by the Amazon EC2 APIs has been exceeded + // for your account. + TerminationCode_AwsRequestLimitExceeded TerminationCode = "AWS_REQUEST_LIMIT_EXCEEDED" + // We don't have enough addresses in the subnet for the instances in the + // request. + TerminationCode_AwsInsufficientFreeAddressesInSubnetFailure TerminationCode = "AWS_INSUFFICIENT_FREE_ADDRESSES_IN_SUBNET_FAILURE" + // The request is not supported (This is a vague error code that can be thrown + // for a lot of reasons.) + TerminationCode_AwsUnsupportedFailure TerminationCode = "AWS_UNSUPPORTED_FAILURE" + // Could not find enough azure resources to fulfill the request. + TerminationCode_AzureQuotaExceededException TerminationCode = "AZURE_QUOTA_EXCEEDED_EXCEPTION" + // NOTE: This is currently used by exceptions with messages that are classified + // as user errors. + TerminationCode_AzureOperationNotAllowedException TerminationCode = "AZURE_OPERATION_NOT_ALLOWED_EXCEPTION" + // Failure when mounting remote NFS to container + TerminationCode_NfsMountFailure TerminationCode = "NFS_MOUNT_FAILURE" + // K8S failed to upscale to acquire new nodes + TerminationCode_K8sAutoscalingFailure TerminationCode = "K8S_AUTOSCALING_FAILURE" + // DBR Cluster launched on K8s (i.e. CMv2) has failed to start up in time + TerminationCode_K8sDbrClusterLaunchTimeout TerminationCode = "K8S_DBR_CLUSTER_LAUNCH_TIMEOUT" + // Container launch failed while downloading the spark image. Catch all for if + // anything goes wrong while downloading and extracting the spark tarball. + TerminationCode_SparkImageDownloadFailure TerminationCode = "SPARK_IMAGE_DOWNLOAD_FAILURE" + // Azure VM Extension failure during instance bootstrap + TerminationCode_AzureVmExtensionFailure TerminationCode = "AZURE_VM_EXTENSION_FAILURE" + // Workspace was cancelled hence deny/terminate the cluster + TerminationCode_WorkspaceCancelledError TerminationCode = "WORKSPACE_CANCELLED_ERROR" + // The spot instance count in an account has exceeded the limit + TerminationCode_AwsMaxSpotInstanceCountExceededFailure TerminationCode = "AWS_MAX_SPOT_INSTANCE_COUNT_EXCEEDED_FAILURE" + // Cluster is terminated because the services are temporarily unavailable. This + // normally happens when CM is restarting and draining execution contexts, or + // IM/Delegate is overloaded, so that it will not be able to retry the instance + // launch request. + TerminationCode_TemporarilyUnavailable TerminationCode = "TEMPORARILY_UNAVAILABLE" + // Bootstrap failure due to error during worker setup, usually due to an issue + // with disk or gpu setup. See SetupCommandBuilder for other possible causes + TerminationCode_WorkerSetupFailure TerminationCode = "WORKER_SETUP_FAILURE" + // Cluster failure due to IP space exhaustion. For example on CMv2, Kubernetes + // will fail to scale up new nodes if the pod IP CIDR block is exhausted. + TerminationCode_IpExhaustionFailure TerminationCode = "IP_EXHAUSTION_FAILURE" + // Could not find enough GCP resources to fulfill the request. TODO: It's very + // unfortunate that we have per-cloud termination reasons while we should have + // cloud-agnostic termination reasons. For example, we should consolidate + // {AZURE_QUOTA_EXCEEDED_EXCEPTION, AWS_REQUEST_LIMIT_EXCEEDED and + // GCP_QUOTA_EXCEEDED}, {AWS_INSUFFICIENT_FREE_ADDRESSES_IN_SUBNET_FAILURE, + // IP_EXHAUSTION_FAILURE}, etc. + TerminationCode_GcpQuotaExceeded TerminationCode = "GCP_QUOTA_EXCEEDED" + // Cloud provider is undergoing a transient resource throttling. This is + // retryable. + TerminationCode_CloudProviderResourceStockout TerminationCode = "CLOUD_PROVIDER_RESOURCE_STOCKOUT" + // The GCP service account associated with the DBR cluster is deleted. + TerminationCode_GcpServiceAccountDeleted TerminationCode = "GCP_SERVICE_ACCOUNT_DELETED" + // Legit cluster termination in Azure caused by customer revoking the key + // permission used for managed-disks encryption + TerminationCode_AzureByokKeyPermissionFailure TerminationCode = "AZURE_BYOK_KEY_PERMISSION_FAILURE" + // Termination because of spot instance terminated by cloud provider + TerminationCode_SpotInstanceTermination TerminationCode = "SPOT_INSTANCE_TERMINATION" + // Termination because of unsupported azure ephemeral os disk setup + TerminationCode_AzureEphemeralDiskFailure TerminationCode = "AZURE_EPHEMERAL_DISK_FAILURE" + // The cluster was terminated because we detected an abusive runtime behavior + // that violated Terms of Service or Acceptable Use Policy. + TerminationCode_AbuseDetected TerminationCode = "ABUSE_DETECTED" + // Failed to pull DBR images due to permission error. + TerminationCode_ImagePullPermissionDenied TerminationCode = "IMAGE_PULL_PERMISSION_DENIED" + // Workspace configuration is in error state due to configuration issue or ACL + // modification by the customer side + TerminationCode_WorkspaceConfigurationError TerminationCode = "WORKSPACE_CONFIGURATION_ERROR" + // Catch all error for all secret resolution issues in cluster launch. This + // should be alerted on, and is considered a server error. This can be split out + // into other cases if there are client errors - for e.g. INVALID_ARGUMENT is + // used for secrets that don't exist and permission issues + TerminationCode_SecretResolutionError TerminationCode = "SECRET_RESOLUTION_ERROR" + // Failure due to an instance being of an unsupported type. This is used when an + // instance in an EC2 fleet is of an unrecognized type, or an invalid type (i.e. + // graviton when we don't want graviton instances). This should be alerted on. + TerminationCode_UnsupportedInstanceType TerminationCode = "UNSUPPORTED_INSTANCE_TYPE" + // Failed during instance bootstrap with error code Cannot convert NVMe-based + // dev id + TerminationCode_CloudProviderDiskSetupFailure TerminationCode = "CLOUD_PROVIDER_DISK_SETUP_FAILURE" + // Exception when setting up instances using ssh bootstrap + TerminationCode_SshBootstrapFailure TerminationCode = "SSH_BOOTSTRAP_FAILURE" + // Failed during instance bootstrap with error code Cannot convert NVMe-based + // dev id + TerminationCode_AwsInaccessibleKmsKeyFailure TerminationCode = "AWS_INACCESSIBLE_KMS_KEY_FAILURE" + // The bootstrapping init-containers in Spark failed or timed out, blocking the + // Spark container from bootstrapping. This is a refinement of + // `SPARK_STARTUP_FAILURE`. (init-containers are a bootstrapping step owned by + // Databricks) + TerminationCode_InitContainerNotFinished TerminationCode = "INIT_CONTAINER_NOT_FINISHED" + // Container launch failed due to storage servers throttling our download of + // spark images. Can happen due to transient spikes of downloads overloading + // storage servers or gradual increase in usage. In the latter case we need to + // increase the number of storage servers in the region to help spread load. + TerminationCode_SparkImageDownloadThrottled TerminationCode = "SPARK_IMAGE_DOWNLOAD_THROTTLED" + // The spark image specified for the cluster was not found when attempting to + // download. Usually due to the customer custom specifying a bad image. + TerminationCode_SparkImageNotFound TerminationCode = "SPARK_IMAGE_NOT_FOUND" + // Indicates that the cloud provider operations performed for the cluster were + // dropped due to an influx in load in the cloud provider and had to be dropped + // from our end to alleviate pressure within the DelegateRpcClient. Please see + // go/cmloadshedding for more. + TerminationCode_ClusterOperationThrottled TerminationCode = "CLUSTER_OPERATION_THROTTLED" + // The error code can be used to indicate a request misses its deadline. Can be + // used for either request timeouts or missed deadlines (i.e. a request is not + // completed as it was processed after its specified deadline) + TerminationCode_ClusterOperationTimeout TerminationCode = "CLUSTER_OPERATION_TIMEOUT" + // This error code is used to terminate long-running Generic compute jobs in + // Serverless Environment as part of the NephosLongRunning watcher running in + // Cluster Monitor Service. + TerminationCode_ServerlessLongRunningTerminated TerminationCode = "SERVERLESS_LONG_RUNNING_TERMINATED" + // This error code is used when the cluster is terminated due to its instances + // fail with partial failure from Azure packed deployments. In Azure, we might + // pack multiple launch requests in one deployment template in order to avoid + // the 800 templates limit on Azure side. If the packed deployment fails + // multiple times, the cluster could be terminated by this + // [[AZURE_PACKED_DEPLOYMENT_PARTIAL_FAILURE]] termination code. + TerminationCode_AzurePackedDeploymentPartialFailure TerminationCode = "AZURE_PACKED_DEPLOYMENT_PARTIAL_FAILURE" + // The instances acquired from a pool in IMv2 do not have a valid worker image + // to be used in the cluster launch. This usually occurs after AMI/VHD upgrades, + // worker branch updates, etc. + TerminationCode_InvalidWorkerImageFailure TerminationCode = "INVALID_WORKER_IMAGE_FAILURE" + // Worker environment version was changed due to workspace network or CMK + // update. + TerminationCode_WorkspaceUpdate TerminationCode = "WORKSPACE_UPDATE" + // The parameter user specified or the user account to create the cluster is + // invalid according to AWS. + TerminationCode_InvalidAwsParameter TerminationCode = "INVALID_AWS_PARAMETER" + // ** Only relevant on k8s dataplanes (i.e. clusters launched with CMv2 - not + // CMv1). + // + // k8s evicted the driver pod due to disk pressure on the driver node. This is + // likely due to a customer job consuming too much disk and so this is + // classified as a customer issue. + TerminationCode_DriverOutOfDisk TerminationCode = "DRIVER_OUT_OF_DISK" + // ** Only relevant on k8s dataplanes (i.e. clusters launched with CMv2 - not + // CMv1). + // + // k8s evicted the driver pod due to memory pressure on the driver node. A + // customer job consuming significant amounts of memory should not be able to + // trigger this as the driver container would OOM first (we set memory limits on + // our pods). Thus this termination reason will be considered a databricks + // issue. + TerminationCode_DriverOutOfMemory TerminationCode = "DRIVER_OUT_OF_MEMORY" + // ** Only relevant on k8s dataplanes (i.e. clusters launched with CMv2 - not + // CMv1). Original driver pod took too long to become ready and timed out. + TerminationCode_DriverLaunchTimeout TerminationCode = "DRIVER_LAUNCH_TIMEOUT" + // ** Only relevant on k8s dataplanes (i.e. clusters launched with CMv2 - not + // CMv1). Unexpected failure during driver pod launch. + TerminationCode_DriverUnexpectedFailure TerminationCode = "DRIVER_UNEXPECTED_FAILURE" + // ** Only relevant on k8s dataplanes (i.e. clusters launched with CMv2 - not + // CMv1). Unexpected new driver pod created + TerminationCode_UnexpectedPodRecreation TerminationCode = "UNEXPECTED_POD_RECREATION" + // Failure due to disabled or inaccessible CMK. + TerminationCode_GcpInaccessibleKmsKeyFailure TerminationCode = "GCP_INACCESSIBLE_KMS_KEY_FAILURE" + // Failure due to missing/incorrect permission setup on CMK. + TerminationCode_GcpKmsKeyPermissionDenied TerminationCode = "GCP_KMS_KEY_PERMISSION_DENIED" + // Driver pod evicted in Nephos + TerminationCode_DriverEviction TerminationCode = "DRIVER_EVICTION" + // User request for termination directly to cloud + TerminationCode_UserInitiatedVmTermination TerminationCode = "USER_INITIATED_VM_TERMINATION" + // GCP Specific IAM API timeout issues during Workload Idenitity (Cluster + // Identity) binding process + TerminationCode_GcpIamTimeout TerminationCode = "GCP_IAM_TIMEOUT" + // Could not find enough AWS resources to fulfill the request + TerminationCode_AwsResourceQuotaExceeded TerminationCode = "AWS_RESOURCE_QUOTA_EXCEEDED" + // Cloud account setup has some error (e.g. pending email verification, blocked) + TerminationCode_CloudAccountSetupFailure TerminationCode = "CLOUD_ACCOUNT_SETUP_FAILURE" + // The specified key pair name does not exist. + TerminationCode_AwsInvalidKeyPair TerminationCode = "AWS_INVALID_KEY_PAIR" + // Driver pod creation failure in nephos + TerminationCode_DriverPodCreationFailure TerminationCode = "DRIVER_POD_CREATION_FAILURE" + // Cluster terminated manually by on-call due to emergency maintenance + TerminationCode_MaintenanceMode TerminationCode = "MAINTENANCE_MODE" + // Nephos internal error due to insufficient provisioned k8s capacity or + // insufficient cloud quota + TerminationCode_InternalCapacityFailure TerminationCode = "INTERNAL_CAPACITY_FAILURE" + // Nephos: could not acquire executor pods from pod pool + TerminationCode_ExecutorPodUnscheduled TerminationCode = "EXECUTOR_POD_UNSCHEDULED" + // Artifact download failed because it was too slow + TerminationCode_StorageDownloadFailureSlow TerminationCode = "STORAGE_DOWNLOAD_FAILURE_SLOW" + // Artifact download failed because it was throttled by the download server + TerminationCode_StorageDownloadFailureThrottled TerminationCode = "STORAGE_DOWNLOAD_FAILURE_THROTTLED" + // The cluster was terminated because the size of the dynamic spark conf + // exceeded the limit. + TerminationCode_DynamicSparkConfSizeExceeded TerminationCode = "DYNAMIC_SPARK_CONF_SIZE_EXCEEDED" + // Failure to update the instance profile for the cluster. + TerminationCode_AwsInstanceProfileUpdateFailure TerminationCode = "AWS_INSTANCE_PROFILE_UPDATE_FAILURE" + // The instance pool did not exist when the cluster was launched. + TerminationCode_InstancePoolNotFound TerminationCode = "INSTANCE_POOL_NOT_FOUND" + // Attempting to launch more instances was rejected as it would exceed the + // pool's max capacity. + TerminationCode_InstancePoolMaxCapacityReached TerminationCode = "INSTANCE_POOL_MAX_CAPACITY_REACHED" + // The KMS key provided is in an incorrect state. + TerminationCode_AwsInvalidKmsKeyState TerminationCode = "AWS_INVALID_KMS_KEY_STATE" + // Insufficient capacity failure from GCE API. + TerminationCode_GcpInsufficientCapacity TerminationCode = "GCP_INSUFFICIENT_CAPACITY" + // Rate quota exceeded for GCP API (e.g. Read requests per minute per region). + TerminationCode_GcpApiRateQuotaExceeded TerminationCode = "GCP_API_RATE_QUOTA_EXCEEDED" + // Resource quota exceeded (e.g. # of n1 vCPUs in a region). + TerminationCode_GcpResourceQuotaExceeded TerminationCode = "GCP_RESOURCE_QUOTA_EXCEEDED" + // Subnet IP space exhausted. + TerminationCode_GcpIpSpaceExhausted TerminationCode = "GCP_IP_SPACE_EXHAUSTED" + // Missing permissions to launch VM with service account. + TerminationCode_GcpServiceAccountAccessDenied TerminationCode = "GCP_SERVICE_ACCOUNT_ACCESS_DENIED" + // VM attempting to launch with non-existent service account. + TerminationCode_GcpServiceAccountNotFound TerminationCode = "GCP_SERVICE_ACCOUNT_NOT_FOUND" + // Forbidden (403) returned by GCP API. + TerminationCode_GcpForbidden TerminationCode = "GCP_FORBIDDEN" + // Not found (404) returned by GCP API. + TerminationCode_GcpNotFound TerminationCode = "GCP_NOT_FOUND" + // Gatekeeper indicated the cluster should be shutdown + TerminationCode_ResourceUsageBlocked TerminationCode = "RESOURCE_USAGE_BLOCKED" + // The data access config of the workspace has changed, and clusters using + // outdated config will be terminated. + TerminationCode_DataAccessConfigChanged TerminationCode = "DATA_ACCESS_CONFIG_CHANGED" + // Failed to fetch internal PAT token required for init script installation from + // WSFS/UC volumes + TerminationCode_AccessTokenFailure TerminationCode = "ACCESS_TOKEN_FAILURE" + // It indicates there is a placement v2 protocol rollout/rollback event for the + // corresponding workspace when processing the placement session on the + // instance-manager side. A retry will fix the issue by switching back to the + // correct placement protocol. + TerminationCode_InvalidInstancePlacementProtocol TerminationCode = "INVALID_INSTANCE_PLACEMENT_PROTOCOL" + // The cluster was terminated as it failed to resolve budget policy. + TerminationCode_BudgetPolicyResolutionFailure TerminationCode = "BUDGET_POLICY_RESOLUTION_FAILURE" + // This customer/error combination is a known issue and is intentionally + // excluded from termination metrics + TerminationCode_InPenaltyBox TerminationCode = "IN_PENALTY_BOX" + // The cluster was terminated when the primary workspace failed over to the + // secondary workspace. This is expected because there is no data plane in the + // secondary workspace. + TerminationCode_DisasterRecoveryReplication TerminationCode = "DISASTER_RECOVERY_REPLICATION" + // A bootstrap timeout that was caused by misconfiguration on the customer's + // side + TerminationCode_BootstrapTimeoutDueToMisconfig TerminationCode = "BOOTSTRAP_TIMEOUT_DUE_TO_MISCONFIG" + // Instance unreachable, but due to misconfiguration on the customer's side + TerminationCode_InstanceUnreachableDueToMisconfig TerminationCode = "INSTANCE_UNREACHABLE_DUE_TO_MISCONFIG" + // Bootstrap timeout due to script download failure, but due to misconfiguration + // on the customer's side + TerminationCode_StorageDownloadFailureDueToMisconfig TerminationCode = "STORAGE_DOWNLOAD_FAILURE_DUE_TO_MISCONFIG" + // CPRF, but due to misconfiguration on the customer's side + TerminationCode_ControlPlaneRequestFailureDueToMisconfig TerminationCode = "CONTROL_PLANE_REQUEST_FAILURE_DUE_TO_MISCONFIG" + // CPLF, but due to misconfiguration on the customer's side + TerminationCode_CloudProviderLaunchFailureDueToMisconfig TerminationCode = "CLOUD_PROVIDER_LAUNCH_FAILURE_DUE_TO_MISCONFIG" + // GCP subnet is in transient "resourceNotReady" state. + TerminationCode_GcpSubnetNotReady TerminationCode = "GCP_SUBNET_NOT_READY" + // The operation on the cloud provider was cancelled. Possibly due to a user + // action. + TerminationCode_CloudOperationCancelled TerminationCode = "CLOUD_OPERATION_CANCELLED" + // If cloud provider indicates instance creation was a success, yet the instance + // is never created. This can happen in certain edge cases like quota exhaustion + // on GCP. We have an open bug here: + // https://partnerissuetracker.corp.google.com/issues/339061883 + TerminationCode_CloudProviderInstanceNotLaunched TerminationCode = "CLOUD_PROVIDER_INSTANCE_NOT_LAUNCHED" + // GCP Databricks VM Machine Image is blocked by customer organization policy. + TerminationCode_GcpTrustedImageProjectsViolated TerminationCode = "GCP_TRUSTED_IMAGE_PROJECTS_VIOLATED" + // cluster terminate can happened when a budget policy limit enforcement + // activated + TerminationCode_BudgetPolicyLimitEnforcementActivated TerminationCode = "BUDGET_POLICY_LIMIT_ENFORCEMENT_ACTIVATED" + TerminationCode_EosSparkImage TerminationCode = "EOS_SPARK_IMAGE" + // Serverless only. There are no eligible K8s for the cluster. + TerminationCode_NoMatchedK8s TerminationCode = "NO_MATCHED_K8S" + // Lazy allocation timeout. Timeout before any internal DBR clusters were + // allocated. + TerminationCode_LazyAllocationTimeout TerminationCode = "LAZY_ALLOCATION_TIMEOUT" + // CMv2 unable to contact chauffeur or node-daemon on the driver node. + TerminationCode_DriverNodeUnreachable TerminationCode = "DRIVER_NODE_UNREACHABLE" + // Dynamic secret generation failed. + TerminationCode_SecretCreationFailure TerminationCode = "SECRET_CREATION_FAILURE" + // Driver or executor pod failed to be scheduled. + TerminationCode_PodSchedulingFailure TerminationCode = "POD_SCHEDULING_FAILURE" + // Driver or executor pod failed to finish assigning. + TerminationCode_PodAssignmentFailure TerminationCode = "POD_ASSIGNMENT_FAILURE" + // Lazy allocation timeout with unknown reason. + TerminationCode_AllocationTimeout TerminationCode = "ALLOCATION_TIMEOUT" + // Lazy allocation timeout. Maps to NoUnallocatedDbrCluster. + TerminationCode_AllocationTimeoutNoUnallocatedClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_UNALLOCATED_CLUSTERS" + // Lazy allocation timeout. Maps to NoMatchedUnallocatedDbrCluster. + TerminationCode_AllocationTimeoutNoMatchedClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_MATCHED_CLUSTERS" + // Lazy allocation timeout. Maps to NoUnallocatedReadyDbrCluster. + TerminationCode_AllocationTimeoutNoReadyClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_READY_CLUSTERS" + // Lazy allocation timeout. Maps to NoMatchedUnallocatedWarmedUpDbrCluster. + TerminationCode_AllocationTimeoutNoWarmedUpClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_WARMED_UP_CLUSTERS" + // Lazy allocation timeout. Maps to NoCandidatesWithNodeDaemonK8sReady. + TerminationCode_AllocationTimeoutNodeDaemonNotReady TerminationCode = "ALLOCATION_TIMEOUT_NODE_DAEMON_NOT_READY" + // Lazy allocation timeout. Maps to NoCandidatesHealthy. + TerminationCode_AllocationTimeoutNoHealthyClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_HEALTHY_CLUSTERS" + // When nephos blocking wait for netvisor setup ready signal, terminated by + // timeout. This error code only applies to clusters with the attribute + // should_block_for_network_readiness: true + TerminationCode_NetvisorSetupTimeout TerminationCode = "NETVISOR_SETUP_TIMEOUT" + // Serverless only. The preselected K8s for the cluster is not eligible. + TerminationCode_NoMatchedK8sTestingTag TerminationCode = "NO_MATCHED_K8S_TESTING_TAG" + // The customer's repeatedly attempting to launch clusters with some + // configuration that the CSP's not able to provide + TerminationCode_CloudProviderResourceStockoutDueToMisconfig TerminationCode = "CLOUD_PROVIDER_RESOURCE_STOCKOUT_DUE_TO_MISCONFIG" + // For the GCP CMv1 Migration, we will terminate all CMv2 based clusters with + // this failure. + TerminationCode_GkeBasedClusterTermination TerminationCode = "GKE_BASED_CLUSTER_TERMINATION" + // Lazy allocation timeout. Maps to NoCandidatesHealthyAndWarmedUp. + TerminationCode_AllocationTimeoutNoHealthyAndWarmedUpClusters TerminationCode = "ALLOCATION_TIMEOUT_NO_HEALTHY_AND_WARMED_UP_CLUSTERS" + // Docker container's OS was not valid. + TerminationCode_DockerInvalidOsException TerminationCode = "DOCKER_INVALID_OS_EXCEPTION" + // Something went wrong during the creation of the docker container. + TerminationCode_DockerContainerCreationException TerminationCode = "DOCKER_CONTAINER_CREATION_EXCEPTION" + // Customer passed in a docker image that's too large for the instance. + TerminationCode_DockerImageTooLargeForInstanceException TerminationCode = "DOCKER_IMAGE_TOO_LARGE_FOR_INSTANCE_EXCEPTION" + // The cluster was terminated because the DNS resolution failed. + TerminationCode_DnsResolutionError TerminationCode = "DNS_RESOLUTION_ERROR" + // Org policy is preventing a GCE API operation from being executed. + TerminationCode_GcpDeniedByOrgPolicy TerminationCode = "GCP_DENIED_BY_ORG_POLICY" + // Customer passed in a secret that they do not have permissions to resolve. + TerminationCode_SecretPermissionDenied TerminationCode = "SECRET_PERMISSION_DENIED" + // Start of network health check generated failures + TerminationCode_NetworkCheckNicFailure TerminationCode = "NETWORK_CHECK_NIC_FAILURE" + TerminationCode_NetworkCheckDnsServerFailure TerminationCode = "NETWORK_CHECK_DNS_SERVER_FAILURE" + TerminationCode_NetworkCheckStorageFailure TerminationCode = "NETWORK_CHECK_STORAGE_FAILURE" + TerminationCode_NetworkCheckMetadataEndpointFailure TerminationCode = "NETWORK_CHECK_METADATA_ENDPOINT_FAILURE" + TerminationCode_NetworkCheckControlPlaneFailure TerminationCode = "NETWORK_CHECK_CONTROL_PLANE_FAILURE" + TerminationCode_NetworkCheckMultipleComponentsFailure TerminationCode = "NETWORK_CHECK_MULTIPLE_COMPONENTS_FAILURE" + // Driver has been down or unresponsive for an extended period of time + TerminationCode_DriverUnhealthy TerminationCode = "DRIVER_UNHEALTHY" + // cluster request is denied due to disallowed usage policy entitlement + TerminationCode_UsagePolicyEntitlementDenied TerminationCode = "USAGE_POLICY_ENTITLEMENT_DENIED" + // Request exceeded MAX_ACTIVE_DBR_PODS_PER_K8S_CLUSTER quota - too many active + // pods on the K8s cluster + TerminationCode_K8sActivePodQuotaExceeded TerminationCode = "K8S_ACTIVE_POD_QUOTA_EXCEEDED" + // Request exceeded MAX_PODS_PER_CLOUD_ACCOUNT quota - subscription/cloud + // account pod limit reached + TerminationCode_CloudAccountPodQuotaExceeded TerminationCode = "CLOUD_ACCOUNT_POD_QUOTA_EXCEEDED" + // Start of network health check generated failures due to misconfiguration + TerminationCode_NetworkCheckNicFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_NIC_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_NetworkCheckDnsServerFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_DNS_SERVER_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_NetworkCheckStorageFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_STORAGE_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_NetworkCheckMetadataEndpointFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_METADATA_ENDPOINT_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_NetworkCheckControlPlaneFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_CONTROL_PLANE_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_NetworkCheckMultipleComponentsFailureDueToMisconfig TerminationCode = "NETWORK_CHECK_MULTIPLE_COMPONENTS_FAILURE_DUE_TO_MISCONFIG" + // CMv2 could not resolve the DBR image for versionless workloads (REPL, + // GENERIC). This typically happens when no spark version is found from the + // channel mapping and the workload is versionless-enabled. + TerminationCode_DbrImageResolutionFailure TerminationCode = "DBR_IMAGE_RESOLUTION_FAILURE" + TerminationCode_ControlPlaneConnectionFailure TerminationCode = "CONTROL_PLANE_CONNECTION_FAILURE" + TerminationCode_ControlPlaneConnectionFailureDueToMisconfig TerminationCode = "CONTROL_PLANE_CONNECTION_FAILURE_DUE_TO_MISCONFIG" + TerminationCode_RateLimited TerminationCode = "RATE_LIMITED" + // The cluster was terminated because mutual TLS port 8443 check failed. + TerminationCode_MtlsPortConnectivityFailure TerminationCode = "MTLS_PORT_CONNECTIVITY_FAILURE" + // The cluster was terminated because hivemetastore connectivity check failed. + TerminationCode_HivemetastoreConnectivityFailure TerminationCode = "HIVEMETASTORE_CONNECTIVITY_FAILURE" +) + +// type of the termination +type TerminationType string + +const ( + TerminationType_Unspecified TerminationType = "" + // Termination succeeded normally + TerminationType_Success TerminationType = "SUCCESS" + // Non-retryable. Client must fix parameters before reattempting the cluster + // creation + TerminationType_ClientError TerminationType = "CLIENT_ERROR" + // Databricks service issue. Clients may retry + TerminationType_ServiceFault TerminationType = "SERVICE_FAULT" + // AWS or Azure infrastructure issue. Clients may retry after the underlying + // cloud issue is resolved + TerminationType_CloudFailure TerminationType = "CLOUD_FAILURE" +) + +type WarehouseType string + +const ( + WarehouseType_Unspecified WarehouseType = "" + // Classic warehouse type + WarehouseType_Classic WarehouseType = "CLASSIC" + // Pro warehouse type + WarehouseType_Pro WarehouseType = "PRO" +) + +type EndpointHealth_Status string + +const ( + EndpointHealth_Status_Unspecified EndpointHealth_Status = "" + // Endpoint is functioning normally and there are no known issues. + EndpointHealth_Status_Healthy EndpointHealth_Status = "HEALTHY" + // Endpoint might be functional, but there are some known issues. Performance + // might be affected. + EndpointHealth_Status_Degraded EndpointHealth_Status = "DEGRADED" + // Endpoint is severely affected. Likely will not be able to serve queries. + EndpointHealth_Status_Failed EndpointHealth_Status = "FAILED" +) + +// Configures the channel name and DBSQL version of the warehouse. +// CHANNEL_NAME_CUSTOM should be chosen only when `dbsql_version` is specified.. +type Channel struct { + Name ChannelName + DbsqlVersion *string +} + +// Request message for CreateDefaultWarehouseOverride.. +type CreateDefaultWarehouseOverrideRequest struct { + // Required. The ID to use for the override, which will become the final + // component of the override's resource name. Can be a numeric user ID or the + // literal string "me" for the current user. + DefaultWarehouseOverrideId *string + // Required. The default warehouse override to create. + DefaultWarehouseOverride *DefaultWarehouseOverride +} + +// Creates a new SQL warehouse.. +type CreateWarehouseRequest struct { + // Logical name for the cluster. + // + // Supported values: - Must be unique within an org. - Must be less than 100 + // characters. + Name *string + // Size of the clusters allocated for this warehouse. Increasing the size of a + // spark cluster allows you to run larger queries on it. If you want to increase + // the number of concurrent queries, please tune max_num_clusters. + // + // Supported values: - 2X-Small - X-Small - Small - Medium - Large - X-Large - + // 2X-Large - 3X-Large - 4X-Large - 5X-Large + ClusterSize *string + // Minimum number of available clusters that will be maintained for this SQL + // warehouse. Increasing this will ensure that a larger number of clusters are + // always running and therefore may reduce the cold start time for new queries. + // This is similar to reserved vs. revocable cores in a resource manager. + // + // Supported values: - Must be > 0 - Must be <= min(max_num_clusters, 30) + // + // Defaults to 1 + MinNumClusters *int + // Maximum number of clusters that the autoscaler will create to handle + // concurrent queries. + // + // Supported values: - Must be >= min_num_clusters - Must be <= 40. + // + // Defaults to min_clusters if unset. + MaxNumClusters *int + // The amount of time in minutes that a SQL warehouse must be idle (i.e., no + // RUNNING queries) before it is automatically stopped. + // + // Supported values: - Must be == 0 or >= 10 mins - 0 indicates no autostop. + // + // Defaults to 120 mins + AutoStopMins *int + // warehouse creator name + CreatorName *string + // Deprecated. Instance profile used to pass IAM role to the cluster + InstanceProfileArn *string + // A set of key-value pairs that will be tagged on all resources (e.g., AWS + // instances and EBS volumes) associated with this SQL warehouse. + // + // Supported values: - Number of tags < 45. + Tags *EndpointTags + // Configurations whether the endpoint should use spot instances. + SpotInstancePolicy EndpointSpotInstancePolicy + // Configures whether the warehouse should use Photon optimized clusters. + // + // Defaults to true. + EnablePhoton *bool + // Channel Details + Channel *Channel + // Configures whether the warehouse should use serverless compute + EnableServerlessCompute *bool + // Warehouse type: `PRO` or `CLASSIC`. If you want to use serverless compute, + // you must set to `PRO` and also set the field `enable_serverless_compute` to + // `true`. + WarehouseType WarehouseType +} + +type CreateWarehouseResponse struct { + // Id for the SQL warehouse. This value is unique across all SQL warehouses. + Id *string +} + +// Represents a per-user default warehouse override configuration. This resource +// allows users or administrators to customize how a user's default warehouse is +// selected for SQL operations. If no override exists for a user, the workspace +// default warehouse will be used.. +type DefaultWarehouseOverride struct { + // The resource name of the default warehouse override. Format: + // default-warehouse-overrides/{default_warehouse_override_id} + Name *string `fieldmask:"name"` + // The ID component of the resource name (user ID). + DefaultWarehouseOverrideId *string `fieldmask:"default_warehouse_override_id"` + // The type of override behavior. + Type DefaultWarehouseOverrideType `fieldmask:"type"` + // The specific warehouse ID when type is CUSTOM. Not set for LAST_SELECTED + // type. + WarehouseId *string `fieldmask:"warehouse_id"` +} + +// Request message for DeleteDefaultWarehouseOverride.. +type DeleteDefaultWarehouseOverrideRequest struct { + // Required. The resource name of the default warehouse override to delete. + // Format: default-warehouse-overrides/{default_warehouse_override_id} The + // default_warehouse_override_id can be a numeric user ID or the literal string + // "me" for the current user. + Name *string +} + +type DeleteWarehouseResponse struct { +} + +// This is an incremental edit functionality, so all fields except id are +// optional. If a field is set, the corresponding configuration in the SQL +// warehouse is modified. If a field is unset, the existing configuration value +// in the SQL warehouse is retained. Thus, this API is not idempotent.. +type EditWarehouseRequest struct { + // Required. Id of the warehouse to configure. + Id *string + // Logical name for the cluster. + // + // Supported values: - Must be unique within an org. - Must be less than 100 + // characters. + Name *string + // Size of the clusters allocated for this warehouse. Increasing the size of a + // spark cluster allows you to run larger queries on it. If you want to increase + // the number of concurrent queries, please tune max_num_clusters. + // + // Supported values: - 2X-Small - X-Small - Small - Medium - Large - X-Large - + // 2X-Large - 3X-Large - 4X-Large - 5X-Large + ClusterSize *string + // Minimum number of available clusters that will be maintained for this SQL + // warehouse. Increasing this will ensure that a larger number of clusters are + // always running and therefore may reduce the cold start time for new queries. + // This is similar to reserved vs. revocable cores in a resource manager. + // + // Supported values: - Must be > 0 - Must be <= min(max_num_clusters, 30) + // + // Defaults to 1 + MinNumClusters *int + // Maximum number of clusters that the autoscaler will create to handle + // concurrent queries. + // + // Supported values: - Must be >= min_num_clusters - Must be <= 40. + // + // Defaults to min_clusters if unset. + MaxNumClusters *int + // The amount of time in minutes that a SQL warehouse must be idle (i.e., no + // RUNNING queries) before it is automatically stopped. + // + // Supported values: - Must be == 0 or >= 10 mins - 0 indicates no autostop. + // + // Defaults to 120 mins + AutoStopMins *int + // warehouse creator name + CreatorName *string + // Deprecated. Instance profile used to pass IAM role to the cluster + InstanceProfileArn *string + // A set of key-value pairs that will be tagged on all resources (e.g., AWS + // instances and EBS volumes) associated with this SQL warehouse. + // + // Supported values: - Number of tags < 45. + Tags *EndpointTags + // Configurations whether the endpoint should use spot instances. + SpotInstancePolicy EndpointSpotInstancePolicy + // Configures whether the warehouse should use Photon optimized clusters. + // + // Defaults to true. + EnablePhoton *bool + // Channel Details + Channel *Channel + // Configures whether the warehouse should use serverless compute + EnableServerlessCompute *bool + // Warehouse type: `PRO` or `CLASSIC`. If you want to use serverless compute, + // you must set to `PRO` and also set the field `enable_serverless_compute` to + // `true`. + WarehouseType WarehouseType +} + +type EditWarehouseResponse struct { +} + +type EndpointConfPair struct { + Key *string + Value *string +} + +type EndpointHealth struct { + // Health status of the endpoint. + Status EndpointHealth_Status + // Deprecated. split into summary and details for security + Message *string + // The reason for failure to bring up clusters for this warehouse. This is + // available when status is 'FAILED' and sometimes when it is DEGRADED. + FailureReason *TerminationReason + // A short summary of the health status in case of degraded/failed warehouses. + Summary *string + // Details about errors that are causing current degraded/failed status. + Details *string +} + +type EndpointInfo struct { + // unique identifier for warehouse + Id *string + // Logical name for the cluster. + // + // Supported values: - Must be unique within an org. - Must be less than 100 + // characters. + Name *string + // Size of the clusters allocated for this warehouse. Increasing the size of a + // spark cluster allows you to run larger queries on it. If you want to increase + // the number of concurrent queries, please tune max_num_clusters. + // + // Supported values: - 2X-Small - X-Small - Small - Medium - Large - X-Large - + // 2X-Large - 3X-Large - 4X-Large - 5X-Large + ClusterSize *string + // Minimum number of available clusters that will be maintained for this SQL + // warehouse. Increasing this will ensure that a larger number of clusters are + // always running and therefore may reduce the cold start time for new queries. + // This is similar to reserved vs. revocable cores in a resource manager. + // + // Supported values: - Must be > 0 - Must be <= min(max_num_clusters, 30) + // + // Defaults to 1 + MinNumClusters *int + // Maximum number of clusters that the autoscaler will create to handle + // concurrent queries. + // + // Supported values: - Must be >= min_num_clusters - Must be <= 40. + // + // Defaults to min_clusters if unset. + MaxNumClusters *int + // The amount of time in minutes that a SQL warehouse must be idle (i.e., no + // RUNNING queries) before it is automatically stopped. + // + // Supported values: - Must be == 0 or >= 10 mins - 0 indicates no autostop. + // + // Defaults to 120 mins + AutoStopMins *int + // warehouse creator name + CreatorName *string + // Deprecated. Instance profile used to pass IAM role to the cluster + InstanceProfileArn *string + // A set of key-value pairs that will be tagged on all resources (e.g., AWS + // instances and EBS volumes) associated with this SQL warehouse. + // + // Supported values: - Number of tags < 45. + Tags *EndpointTags + // Configurations whether the endpoint should use spot instances. + SpotInstancePolicy EndpointSpotInstancePolicy + // Configures whether the warehouse should use Photon optimized clusters. + // + // Defaults to true. + EnablePhoton *bool + // Channel Details + Channel *Channel + // Configures whether the warehouse should use serverless compute + EnableServerlessCompute *bool + // Warehouse type: `PRO` or `CLASSIC`. If you want to use serverless compute, + // you must set to `PRO` and also set the field `enable_serverless_compute` to + // `true`. + WarehouseType WarehouseType + // current number of clusters running for the service + NumClusters *int + // Deprecated. current number of active sessions for the warehouse + NumActiveSessions *int64 + // state of the endpoint + State EndpointState + // the jdbc connection string for this warehouse + JdbcUrl *string + // ODBC parameters for the SQL warehouse + OdbcParams *OdbcParams + // Optional health status. Assume the warehouse is healthy if this field is not + // set. + Health *EndpointHealth +} + +type EndpointTagPair struct { + Key *string + Value *string +} + +type EndpointTags struct { + CustomTags []EndpointTagPair +} + +// Request message for GetDefaultWarehouseOverride.. +type GetDefaultWarehouseOverrideRequest struct { + // Required. The resource name of the default warehouse override to retrieve. + // Format: default-warehouse-overrides/{default_warehouse_override_id} The + // default_warehouse_override_id can be a numeric user ID or the literal string + // "me" for the current user. + Name *string +} + +// Fetches the warehouse info for a single SQL warehouse.. +type GetWarehouseRequest struct { + // Required. Id of the SQL warehouse. + Id *string +} + +type GetWarehouseResponse struct { + // unique identifier for warehouse + Id *string + // Logical name for the cluster. + // + // Supported values: - Must be unique within an org. - Must be less than 100 + // characters. + Name *string + // Size of the clusters allocated for this warehouse. Increasing the size of a + // spark cluster allows you to run larger queries on it. If you want to increase + // the number of concurrent queries, please tune max_num_clusters. + // + // Supported values: - 2X-Small - X-Small - Small - Medium - Large - X-Large - + // 2X-Large - 3X-Large - 4X-Large - 5X-Large + ClusterSize *string + // Minimum number of available clusters that will be maintained for this SQL + // warehouse. Increasing this will ensure that a larger number of clusters are + // always running and therefore may reduce the cold start time for new queries. + // This is similar to reserved vs. revocable cores in a resource manager. + // + // Supported values: - Must be > 0 - Must be <= min(max_num_clusters, 30) + // + // Defaults to 1 + MinNumClusters *int + // Maximum number of clusters that the autoscaler will create to handle + // concurrent queries. + // + // Supported values: - Must be >= min_num_clusters - Must be <= 40. + // + // Defaults to min_clusters if unset. + MaxNumClusters *int + // The amount of time in minutes that a SQL warehouse must be idle (i.e., no + // RUNNING queries) before it is automatically stopped. + // + // Supported values: - Must be == 0 or >= 10 mins - 0 indicates no autostop. + // + // Defaults to 120 mins + AutoStopMins *int + // warehouse creator name + CreatorName *string + // Deprecated. Instance profile used to pass IAM role to the cluster + InstanceProfileArn *string + // A set of key-value pairs that will be tagged on all resources (e.g., AWS + // instances and EBS volumes) associated with this SQL warehouse. + // + // Supported values: - Number of tags < 45. + Tags *EndpointTags + // Configurations whether the endpoint should use spot instances. + SpotInstancePolicy EndpointSpotInstancePolicy + // Configures whether the warehouse should use Photon optimized clusters. + // + // Defaults to true. + EnablePhoton *bool + // Channel Details + Channel *Channel + // Configures whether the warehouse should use serverless compute + EnableServerlessCompute *bool + // Warehouse type: `PRO` or `CLASSIC`. If you want to use serverless compute, + // you must set to `PRO` and also set the field `enable_serverless_compute` to + // `true`. + WarehouseType WarehouseType + // current number of clusters running for the service + NumClusters *int + // Deprecated. current number of active sessions for the warehouse + NumActiveSessions *int64 + // state of the endpoint + State EndpointState + // the jdbc connection string for this warehouse + JdbcUrl *string + // ODBC parameters for the SQL warehouse + OdbcParams *OdbcParams + // Optional health status. Assume the warehouse is healthy if this field is not + // set. + Health *EndpointHealth +} + +// Fetches the workspace level SQL warehouse configurations. These are the +// configurations that are set centrally and shared by all SQL warehouses in a +// workspace.. +type GetWorkspaceWarehouseConfigRequest struct { +} + +type GetWorkspaceWarehouseConfigResponse struct { + // Security policy for warehouses + SecurityPolicy EndpointSecurityPolicy + // Spark confs for external hive metastore configuration JSON serialized size + // must be less than <= 512K + DataAccessConfig []EndpointConfPair + // AWS Only: The instance profile used to pass an IAM role to the SQL + // warehouses. This configuration is also applied to the workspace's serverless + // compute for notebooks and jobs. + InstanceProfileArn *string + // Optional: Channel selection details + Channel *Channel + // Deprecated: only setting this to true is allowed. + EnableServerlessCompute *bool + // Deprecated: Use sql_configuration_parameters + GlobalParam *RepeatedEndpointConfPairs + // Deprecated: Use sql_configuration_parameters + ConfigParam *RepeatedEndpointConfPairs + // SQL configuration parameters + SqlConfigurationParameters *RepeatedEndpointConfPairs + // GCP only: Google Service Account used to pass to cluster to access Google + // Cloud Storage + GoogleServiceAccount *string + // List of Warehouse Types allowed in this workspace (limits allowed value of + // the type field in CreateWarehouse and EditWarehouse). Note: Some types cannot + // be disabled, they don't need to be specified in SetWorkspaceWarehouseConfig. + // Note: Disabling a type may cause existing warehouses to be converted to + // another type. Used by frontend to save specific type availability in the + // warehouse create and edit form UI. + EnabledWarehouseTypes []WarehouseTypePair +} + +// Request message for ListDefaultWarehouseOverrides.. +type ListDefaultWarehouseOverridesRequest struct { + // The maximum number of overrides to return. The service may return fewer than + // this value. If unspecified, at most 100 overrides will be returned. The + // maximum value is 1000; values above 1000 will be coerced to 1000. + PageSize *int + // A page token, received from a previous `ListDefaultWarehouseOverrides` call. + // Provide this to retrieve the subsequent page. + // + // When paginating, all other parameters provided to + // `ListDefaultWarehouseOverrides` must match the call that provided the page + // token. + PageToken *string +} + +// Response message for ListDefaultWarehouseOverrides.. +type ListDefaultWarehouseOverridesResponse struct { + // The default warehouse overrides in the workspace. + DefaultWarehouseOverrides []DefaultWarehouseOverride + // A token, which can be sent as `page_token` to retrieve the next page. If this + // field is omitted, there are no subsequent pages. + NextPageToken *string +} + +type ListWarehousesResponse struct { + // A list of warehouses and their configurations. + Warehouses []EndpointInfo + // A token, which can be sent as `page_token` to retrieve the next page. If this + // field is omitted, there are no subsequent pages. + NextPageToken *string +} + +type OdbcParams struct { + Hostname *string + Path *string + Protocol *string + Port *int +} + +type RepeatedEndpointConfPairs struct { + // Deprecated: Use configuration_pairs + ConfigPair []EndpointConfPair + ConfigurationPairs []EndpointConfPair +} + +// Sets the workspace level warehouse configuration that is shared by all SQL +// warehouses in this workspace. +// +// This is idempotent.. +type SetWorkspaceWarehouseConfigRequest struct { + // Security policy for warehouses + SecurityPolicy EndpointSecurityPolicy + // Spark confs for external hive metastore configuration JSON serialized size + // must be less than <= 512K + DataAccessConfig []EndpointConfPair + // AWS Only: The instance profile used to pass an IAM role to the SQL + // warehouses. This configuration is also applied to the workspace's serverless + // compute for notebooks and jobs. + InstanceProfileArn *string + // Optional: Channel selection details + Channel *Channel + // Deprecated: only setting this to true is allowed. + EnableServerlessCompute *bool + // Deprecated: Use sql_configuration_parameters + GlobalParam *RepeatedEndpointConfPairs + // Deprecated: Use sql_configuration_parameters + ConfigParam *RepeatedEndpointConfPairs + // SQL configuration parameters + SqlConfigurationParameters *RepeatedEndpointConfPairs + // GCP only: Google Service Account used to pass to cluster to access Google + // Cloud Storage + GoogleServiceAccount *string + // List of Warehouse Types allowed in this workspace (limits allowed value of + // the type field in CreateWarehouse and EditWarehouse). Note: Some types cannot + // be disabled, they don't need to be specified in SetWorkspaceWarehouseConfig. + // Note: Disabling a type may cause existing warehouses to be converted to + // another type. Used by frontend to save specific type availability in the + // warehouse create and edit form UI. + EnabledWarehouseTypes []WarehouseTypePair +} + +type SetWorkspaceWarehouseConfigResponse struct { +} + +type StartResponse struct { +} + +type StopResponse struct { +} + +type TerminationReason struct { + // status code indicating why the cluster was terminated + Code TerminationCode + // type of the termination + Type TerminationType + // list of parameters that provide additional information about why the cluster + // was terminated + Parameters map[string]string +} + +// Request message for UpdateDefaultWarehouseOverride.. +type UpdateDefaultWarehouseOverrideRequest struct { + // Required. The default warehouse override to update. The name field must be + // set in the format: + // default-warehouse-overrides/{default_warehouse_override_id} The + // default_warehouse_override_id can be a numeric user ID or the literal string + // "me" for the current user. + DefaultWarehouseOverride *DefaultWarehouseOverride + // Required. Field mask specifying which fields to update. Only the fields + // specified in the mask will be updated. Use "*" to update all fields. When + // allow_missing is true, this field is ignored and all fields are applied. + UpdateMask *types.FieldMask[DefaultWarehouseOverride] + // If set to true, and the override is not found, a new override will be + // created. In this situation, `update_mask` is ignored and all fields are + // applied. Defaults to false. + AllowMissing *bool +} + +// * Configuration values to enable or disable the access to specific warehouse +// types in the workspace.. +type WarehouseTypePair struct { + WarehouseType WarehouseType + // If set to false the specific warehouse type will not be allowed as a value + // for warehouse_type in CreateWarehouse and EditWarehouse + Enabled *bool +} + +// Deletes a warehouse. This API is idempotent.. +type DeleteWarehouseRequest struct { + // Required. Id of the SQL warehouse. + Id *string +} + +// Lists all of the SQL warehouses. TODO: consider paginating to limit the +// number of warehouses returned.. +type ListWarehousesRequest struct { + // Deprecated: this field is ignored by the server. Service Principal which will + // be used to fetch the list of endpoints. If not specified, SQL Gateway will + // use the user from the session header. + RunAsUserId *int64 + // The max number of warehouses to return. + PageSize *int + // A page token, received from a previous `ListWarehouses` call. Provide this to + // retrieve the subsequent page; otherwise the first will be retrieved. + // + // When paginating, all other parameters provided to `ListWarehouses` must match + // the call that provided the page token. + PageToken *string +} + +// Starts a SQL warehouse. This API is idempotent.. +type StartRequest struct { + // Required. Id of the SQL warehouse. + Id *string +} + +// Stops a SQL warehouse. This API is idempotent.. +type StopRequest struct { + // Required. Id of the SQL warehouse. + Id *string +} diff --git a/warehouses/v1/wire.go b/warehouses/v1/wire.go new file mode 100755 index 0000000..7d4d7d5 --- /dev/null +++ b/warehouses/v1/wire.go @@ -0,0 +1,780 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package warehouses + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type channelWire struct { + Name ChannelName `json:"name,omitempty"` + DbsqlVersion *string `json:"dbsql_version,omitempty"` +} + +func channelToWire(v *Channel) (*channelWire, error) { + if v == nil { + return nil, nil + } + return &channelWire{ + Name: v.Name, + DbsqlVersion: v.DbsqlVersion, + }, nil +} + +func channelFromWire(w *channelWire) (*Channel, error) { + if w == nil { + return nil, nil + } + return &Channel{ + Name: w.Name, + DbsqlVersion: w.DbsqlVersion, + }, nil +} + +type createDefaultWarehouseOverrideRequestWire struct { + DefaultWarehouseOverrideId *string `json:"default_warehouse_override_id,omitempty"` + DefaultWarehouseOverride *defaultWarehouseOverrideWire `json:"default_warehouse_override,omitempty"` +} + +func createDefaultWarehouseOverrideRequestToWire(v *CreateDefaultWarehouseOverrideRequest) (*createDefaultWarehouseOverrideRequestWire, error) { + if v == nil { + return nil, nil + } + defaultWarehouseOverrideWireValue, err := defaultWarehouseOverrideToWire(v.DefaultWarehouseOverride) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateDefaultWarehouseOverrideRequest.DefaultWarehouseOverride", err) + } + return &createDefaultWarehouseOverrideRequestWire{ + DefaultWarehouseOverrideId: v.DefaultWarehouseOverrideId, + DefaultWarehouseOverride: defaultWarehouseOverrideWireValue, + }, nil +} + +type createWarehouseRequestWire struct { + Name *string `json:"name,omitempty"` + ClusterSize *string `json:"cluster_size,omitempty"` + MinNumClusters *int `json:"min_num_clusters,omitempty"` + MaxNumClusters *int `json:"max_num_clusters,omitempty"` + AutoStopMins *int `json:"auto_stop_mins,omitempty"` + CreatorName *string `json:"creator_name,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + Tags *endpointTagsWire `json:"tags,omitempty"` + SpotInstancePolicy EndpointSpotInstancePolicy `json:"spot_instance_policy,omitempty"` + EnablePhoton *bool `json:"enable_photon,omitempty"` + Channel *channelWire `json:"channel,omitempty"` + EnableServerlessCompute *bool `json:"enable_serverless_compute,omitempty"` + WarehouseType WarehouseType `json:"warehouse_type,omitempty"` +} + +func createWarehouseRequestToWire(v *CreateWarehouseRequest) (*createWarehouseRequestWire, error) { + if v == nil { + return nil, nil + } + tagsWireValue, err := endpointTagsToWire(v.Tags) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateWarehouseRequest.Tags", err) + } + channelWireValue, err := channelToWire(v.Channel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateWarehouseRequest.Channel", err) + } + return &createWarehouseRequestWire{ + Name: v.Name, + ClusterSize: v.ClusterSize, + MinNumClusters: v.MinNumClusters, + MaxNumClusters: v.MaxNumClusters, + AutoStopMins: v.AutoStopMins, + CreatorName: v.CreatorName, + InstanceProfileArn: v.InstanceProfileArn, + Tags: tagsWireValue, + SpotInstancePolicy: v.SpotInstancePolicy, + EnablePhoton: v.EnablePhoton, + Channel: channelWireValue, + EnableServerlessCompute: v.EnableServerlessCompute, + WarehouseType: v.WarehouseType, + }, nil +} + +type createWarehouseResponseWire struct { + Id *string `json:"id,omitempty"` +} + +func createWarehouseResponseFromWire(w *createWarehouseResponseWire) (*CreateWarehouseResponse, error) { + if w == nil { + return nil, nil + } + return &CreateWarehouseResponse{ + Id: w.Id, + }, nil +} + +type defaultWarehouseOverrideWire struct { + Name *string `json:"name,omitempty"` + DefaultWarehouseOverrideId *string `json:"default_warehouse_override_id,omitempty"` + Type DefaultWarehouseOverrideType `json:"type,omitempty"` + WarehouseId *string `json:"warehouse_id,omitempty"` +} + +func defaultWarehouseOverrideToWire(v *DefaultWarehouseOverride) (*defaultWarehouseOverrideWire, error) { + if v == nil { + return nil, nil + } + return &defaultWarehouseOverrideWire{ + Name: v.Name, + DefaultWarehouseOverrideId: v.DefaultWarehouseOverrideId, + Type: v.Type, + WarehouseId: v.WarehouseId, + }, nil +} + +func defaultWarehouseOverrideFromWire(w *defaultWarehouseOverrideWire) (*DefaultWarehouseOverride, error) { + if w == nil { + return nil, nil + } + return &DefaultWarehouseOverride{ + Name: w.Name, + DefaultWarehouseOverrideId: w.DefaultWarehouseOverrideId, + Type: w.Type, + WarehouseId: w.WarehouseId, + }, nil +} + +type editWarehouseRequestWire struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + ClusterSize *string `json:"cluster_size,omitempty"` + MinNumClusters *int `json:"min_num_clusters,omitempty"` + MaxNumClusters *int `json:"max_num_clusters,omitempty"` + AutoStopMins *int `json:"auto_stop_mins,omitempty"` + CreatorName *string `json:"creator_name,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + Tags *endpointTagsWire `json:"tags,omitempty"` + SpotInstancePolicy EndpointSpotInstancePolicy `json:"spot_instance_policy,omitempty"` + EnablePhoton *bool `json:"enable_photon,omitempty"` + Channel *channelWire `json:"channel,omitempty"` + EnableServerlessCompute *bool `json:"enable_serverless_compute,omitempty"` + WarehouseType WarehouseType `json:"warehouse_type,omitempty"` +} + +func editWarehouseRequestToWire(v *EditWarehouseRequest) (*editWarehouseRequestWire, error) { + if v == nil { + return nil, nil + } + tagsWireValue, err := endpointTagsToWire(v.Tags) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditWarehouseRequest.Tags", err) + } + channelWireValue, err := channelToWire(v.Channel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EditWarehouseRequest.Channel", err) + } + return &editWarehouseRequestWire{ + Id: v.Id, + Name: v.Name, + ClusterSize: v.ClusterSize, + MinNumClusters: v.MinNumClusters, + MaxNumClusters: v.MaxNumClusters, + AutoStopMins: v.AutoStopMins, + CreatorName: v.CreatorName, + InstanceProfileArn: v.InstanceProfileArn, + Tags: tagsWireValue, + SpotInstancePolicy: v.SpotInstancePolicy, + EnablePhoton: v.EnablePhoton, + Channel: channelWireValue, + EnableServerlessCompute: v.EnableServerlessCompute, + WarehouseType: v.WarehouseType, + }, nil +} + +type endpointConfPairWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func endpointConfPairToWire(v *EndpointConfPair) (*endpointConfPairWire, error) { + if v == nil { + return nil, nil + } + return &endpointConfPairWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func endpointConfPairFromWire(w *endpointConfPairWire) (*EndpointConfPair, error) { + if w == nil { + return nil, nil + } + return &EndpointConfPair{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type endpointHealthWire struct { + Status EndpointHealth_Status `json:"status,omitempty"` + Message *string `json:"message,omitempty"` + FailureReason *terminationReasonWire `json:"failure_reason,omitempty"` + Summary *string `json:"summary,omitempty"` + Details *string `json:"details,omitempty"` +} + +func endpointHealthFromWire(w *endpointHealthWire) (*EndpointHealth, error) { + if w == nil { + return nil, nil + } + failureReasonPublicValue, err := terminationReasonFromWire(w.FailureReason) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointHealth.FailureReason", err) + } + return &EndpointHealth{ + Status: w.Status, + Message: w.Message, + FailureReason: failureReasonPublicValue, + Summary: w.Summary, + Details: w.Details, + }, nil +} + +type endpointInfoWire struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + ClusterSize *string `json:"cluster_size,omitempty"` + MinNumClusters *int `json:"min_num_clusters,omitempty"` + MaxNumClusters *int `json:"max_num_clusters,omitempty"` + AutoStopMins *int `json:"auto_stop_mins,omitempty"` + CreatorName *string `json:"creator_name,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + Tags *endpointTagsWire `json:"tags,omitempty"` + SpotInstancePolicy EndpointSpotInstancePolicy `json:"spot_instance_policy,omitempty"` + EnablePhoton *bool `json:"enable_photon,omitempty"` + Channel *channelWire `json:"channel,omitempty"` + EnableServerlessCompute *bool `json:"enable_serverless_compute,omitempty"` + WarehouseType WarehouseType `json:"warehouse_type,omitempty"` + NumClusters *int `json:"num_clusters,omitempty"` + NumActiveSessions *int64 `json:"num_active_sessions,omitempty"` + State EndpointState `json:"state,omitempty"` + JdbcUrl *string `json:"jdbc_url,omitempty"` + OdbcParams *odbcParamsWire `json:"odbc_params,omitempty"` + Health *endpointHealthWire `json:"health,omitempty"` +} + +func endpointInfoFromWire(w *endpointInfoWire) (*EndpointInfo, error) { + if w == nil { + return nil, nil + } + tagsPublicValue, err := endpointTagsFromWire(w.Tags) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointInfo.Tags", err) + } + channelPublicValue, err := channelFromWire(w.Channel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointInfo.Channel", err) + } + odbcParamsPublicValue, err := odbcParamsFromWire(w.OdbcParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointInfo.OdbcParams", err) + } + healthPublicValue, err := endpointHealthFromWire(w.Health) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointInfo.Health", err) + } + return &EndpointInfo{ + Id: w.Id, + Name: w.Name, + ClusterSize: w.ClusterSize, + MinNumClusters: w.MinNumClusters, + MaxNumClusters: w.MaxNumClusters, + AutoStopMins: w.AutoStopMins, + CreatorName: w.CreatorName, + InstanceProfileArn: w.InstanceProfileArn, + Tags: tagsPublicValue, + SpotInstancePolicy: w.SpotInstancePolicy, + EnablePhoton: w.EnablePhoton, + Channel: channelPublicValue, + EnableServerlessCompute: w.EnableServerlessCompute, + WarehouseType: w.WarehouseType, + NumClusters: w.NumClusters, + NumActiveSessions: w.NumActiveSessions, + State: w.State, + JdbcUrl: w.JdbcUrl, + OdbcParams: odbcParamsPublicValue, + Health: healthPublicValue, + }, nil +} + +type endpointTagPairWire struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +func endpointTagPairToWire(v *EndpointTagPair) (*endpointTagPairWire, error) { + if v == nil { + return nil, nil + } + return &endpointTagPairWire{ + Key: v.Key, + Value: v.Value, + }, nil +} + +func endpointTagPairFromWire(w *endpointTagPairWire) (*EndpointTagPair, error) { + if w == nil { + return nil, nil + } + return &EndpointTagPair{ + Key: w.Key, + Value: w.Value, + }, nil +} + +type endpointTagsWire struct { + CustomTags []endpointTagPairWire `json:"custom_tags,omitempty"` +} + +func endpointTagsToWire(v *EndpointTags) (*endpointTagsWire, error) { + if v == nil { + return nil, nil + } + customTagsWireValue, err := convertSlice(v.CustomTags, endpointTagPairToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointTags.CustomTags", err) + } + return &endpointTagsWire{ + CustomTags: customTagsWireValue, + }, nil +} + +func endpointTagsFromWire(w *endpointTagsWire) (*EndpointTags, error) { + if w == nil { + return nil, nil + } + customTagsPublicValue, err := convertSlice(w.CustomTags, endpointTagPairFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "EndpointTags.CustomTags", err) + } + return &EndpointTags{ + CustomTags: customTagsPublicValue, + }, nil +} + +type getWarehouseResponseWire struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + ClusterSize *string `json:"cluster_size,omitempty"` + MinNumClusters *int `json:"min_num_clusters,omitempty"` + MaxNumClusters *int `json:"max_num_clusters,omitempty"` + AutoStopMins *int `json:"auto_stop_mins,omitempty"` + CreatorName *string `json:"creator_name,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + Tags *endpointTagsWire `json:"tags,omitempty"` + SpotInstancePolicy EndpointSpotInstancePolicy `json:"spot_instance_policy,omitempty"` + EnablePhoton *bool `json:"enable_photon,omitempty"` + Channel *channelWire `json:"channel,omitempty"` + EnableServerlessCompute *bool `json:"enable_serverless_compute,omitempty"` + WarehouseType WarehouseType `json:"warehouse_type,omitempty"` + NumClusters *int `json:"num_clusters,omitempty"` + NumActiveSessions *int64 `json:"num_active_sessions,omitempty"` + State EndpointState `json:"state,omitempty"` + JdbcUrl *string `json:"jdbc_url,omitempty"` + OdbcParams *odbcParamsWire `json:"odbc_params,omitempty"` + Health *endpointHealthWire `json:"health,omitempty"` +} + +func getWarehouseResponseFromWire(w *getWarehouseResponseWire) (*GetWarehouseResponse, error) { + if w == nil { + return nil, nil + } + tagsPublicValue, err := endpointTagsFromWire(w.Tags) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWarehouseResponse.Tags", err) + } + channelPublicValue, err := channelFromWire(w.Channel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWarehouseResponse.Channel", err) + } + odbcParamsPublicValue, err := odbcParamsFromWire(w.OdbcParams) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWarehouseResponse.OdbcParams", err) + } + healthPublicValue, err := endpointHealthFromWire(w.Health) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWarehouseResponse.Health", err) + } + return &GetWarehouseResponse{ + Id: w.Id, + Name: w.Name, + ClusterSize: w.ClusterSize, + MinNumClusters: w.MinNumClusters, + MaxNumClusters: w.MaxNumClusters, + AutoStopMins: w.AutoStopMins, + CreatorName: w.CreatorName, + InstanceProfileArn: w.InstanceProfileArn, + Tags: tagsPublicValue, + SpotInstancePolicy: w.SpotInstancePolicy, + EnablePhoton: w.EnablePhoton, + Channel: channelPublicValue, + EnableServerlessCompute: w.EnableServerlessCompute, + WarehouseType: w.WarehouseType, + NumClusters: w.NumClusters, + NumActiveSessions: w.NumActiveSessions, + State: w.State, + JdbcUrl: w.JdbcUrl, + OdbcParams: odbcParamsPublicValue, + Health: healthPublicValue, + }, nil +} + +type getWorkspaceWarehouseConfigResponseWire struct { + SecurityPolicy EndpointSecurityPolicy `json:"security_policy,omitempty"` + DataAccessConfig []endpointConfPairWire `json:"data_access_config,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + Channel *channelWire `json:"channel,omitempty"` + EnableServerlessCompute *bool `json:"enable_serverless_compute,omitempty"` + GlobalParam *repeatedEndpointConfPairsWire `json:"global_param,omitempty"` + ConfigParam *repeatedEndpointConfPairsWire `json:"config_param,omitempty"` + SqlConfigurationParameters *repeatedEndpointConfPairsWire `json:"sql_configuration_parameters,omitempty"` + GoogleServiceAccount *string `json:"google_service_account,omitempty"` + EnabledWarehouseTypes []warehouseTypePairWire `json:"enabled_warehouse_types,omitempty"` +} + +func getWorkspaceWarehouseConfigResponseFromWire(w *getWorkspaceWarehouseConfigResponseWire) (*GetWorkspaceWarehouseConfigResponse, error) { + if w == nil { + return nil, nil + } + dataAccessConfigPublicValue, err := convertSlice(w.DataAccessConfig, endpointConfPairFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWorkspaceWarehouseConfigResponse.DataAccessConfig", err) + } + channelPublicValue, err := channelFromWire(w.Channel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWorkspaceWarehouseConfigResponse.Channel", err) + } + globalParamPublicValue, err := repeatedEndpointConfPairsFromWire(w.GlobalParam) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWorkspaceWarehouseConfigResponse.GlobalParam", err) + } + configParamPublicValue, err := repeatedEndpointConfPairsFromWire(w.ConfigParam) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWorkspaceWarehouseConfigResponse.ConfigParam", err) + } + sqlConfigurationParametersPublicValue, err := repeatedEndpointConfPairsFromWire(w.SqlConfigurationParameters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWorkspaceWarehouseConfigResponse.SqlConfigurationParameters", err) + } + enabledWarehouseTypesPublicValue, err := convertSlice(w.EnabledWarehouseTypes, warehouseTypePairFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "GetWorkspaceWarehouseConfigResponse.EnabledWarehouseTypes", err) + } + return &GetWorkspaceWarehouseConfigResponse{ + SecurityPolicy: w.SecurityPolicy, + DataAccessConfig: dataAccessConfigPublicValue, + InstanceProfileArn: w.InstanceProfileArn, + Channel: channelPublicValue, + EnableServerlessCompute: w.EnableServerlessCompute, + GlobalParam: globalParamPublicValue, + ConfigParam: configParamPublicValue, + SqlConfigurationParameters: sqlConfigurationParametersPublicValue, + GoogleServiceAccount: w.GoogleServiceAccount, + EnabledWarehouseTypes: enabledWarehouseTypesPublicValue, + }, nil +} + +type listDefaultWarehouseOverridesRequestWire struct { + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listDefaultWarehouseOverridesRequestToWire(v *ListDefaultWarehouseOverridesRequest) (*listDefaultWarehouseOverridesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listDefaultWarehouseOverridesRequestWire{ + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type listDefaultWarehouseOverridesResponseWire struct { + DefaultWarehouseOverrides []defaultWarehouseOverrideWire `json:"default_warehouse_overrides,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listDefaultWarehouseOverridesResponseFromWire(w *listDefaultWarehouseOverridesResponseWire) (*ListDefaultWarehouseOverridesResponse, error) { + if w == nil { + return nil, nil + } + defaultWarehouseOverridesPublicValue, err := convertSlice(w.DefaultWarehouseOverrides, defaultWarehouseOverrideFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListDefaultWarehouseOverridesResponse.DefaultWarehouseOverrides", err) + } + return &ListDefaultWarehouseOverridesResponse{ + DefaultWarehouseOverrides: defaultWarehouseOverridesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type listWarehousesResponseWire struct { + Warehouses []endpointInfoWire `json:"warehouses,omitempty"` + NextPageToken *string `json:"next_page_token,omitempty"` +} + +func listWarehousesResponseFromWire(w *listWarehousesResponseWire) (*ListWarehousesResponse, error) { + if w == nil { + return nil, nil + } + warehousesPublicValue, err := convertSlice(w.Warehouses, endpointInfoFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "ListWarehousesResponse.Warehouses", err) + } + return &ListWarehousesResponse{ + Warehouses: warehousesPublicValue, + NextPageToken: w.NextPageToken, + }, nil +} + +type odbcParamsWire struct { + Hostname *string `json:"hostname,omitempty"` + Path *string `json:"path,omitempty"` + Protocol *string `json:"protocol,omitempty"` + Port *int `json:"port,omitempty"` +} + +func odbcParamsFromWire(w *odbcParamsWire) (*OdbcParams, error) { + if w == nil { + return nil, nil + } + return &OdbcParams{ + Hostname: w.Hostname, + Path: w.Path, + Protocol: w.Protocol, + Port: w.Port, + }, nil +} + +type repeatedEndpointConfPairsWire struct { + ConfigPair []endpointConfPairWire `json:"config_pair,omitempty"` + ConfigurationPairs []endpointConfPairWire `json:"configuration_pairs,omitempty"` +} + +func repeatedEndpointConfPairsToWire(v *RepeatedEndpointConfPairs) (*repeatedEndpointConfPairsWire, error) { + if v == nil { + return nil, nil + } + configPairWireValue, err := convertSlice(v.ConfigPair, endpointConfPairToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RepeatedEndpointConfPairs.ConfigPair", err) + } + configurationPairsWireValue, err := convertSlice(v.ConfigurationPairs, endpointConfPairToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RepeatedEndpointConfPairs.ConfigurationPairs", err) + } + return &repeatedEndpointConfPairsWire{ + ConfigPair: configPairWireValue, + ConfigurationPairs: configurationPairsWireValue, + }, nil +} + +func repeatedEndpointConfPairsFromWire(w *repeatedEndpointConfPairsWire) (*RepeatedEndpointConfPairs, error) { + if w == nil { + return nil, nil + } + configPairPublicValue, err := convertSlice(w.ConfigPair, endpointConfPairFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RepeatedEndpointConfPairs.ConfigPair", err) + } + configurationPairsPublicValue, err := convertSlice(w.ConfigurationPairs, endpointConfPairFromWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "RepeatedEndpointConfPairs.ConfigurationPairs", err) + } + return &RepeatedEndpointConfPairs{ + ConfigPair: configPairPublicValue, + ConfigurationPairs: configurationPairsPublicValue, + }, nil +} + +type setWorkspaceWarehouseConfigRequestWire struct { + SecurityPolicy EndpointSecurityPolicy `json:"security_policy,omitempty"` + DataAccessConfig []endpointConfPairWire `json:"data_access_config,omitempty"` + InstanceProfileArn *string `json:"instance_profile_arn,omitempty"` + Channel *channelWire `json:"channel,omitempty"` + EnableServerlessCompute *bool `json:"enable_serverless_compute,omitempty"` + GlobalParam *repeatedEndpointConfPairsWire `json:"global_param,omitempty"` + ConfigParam *repeatedEndpointConfPairsWire `json:"config_param,omitempty"` + SqlConfigurationParameters *repeatedEndpointConfPairsWire `json:"sql_configuration_parameters,omitempty"` + GoogleServiceAccount *string `json:"google_service_account,omitempty"` + EnabledWarehouseTypes []warehouseTypePairWire `json:"enabled_warehouse_types,omitempty"` +} + +func setWorkspaceWarehouseConfigRequestToWire(v *SetWorkspaceWarehouseConfigRequest) (*setWorkspaceWarehouseConfigRequestWire, error) { + if v == nil { + return nil, nil + } + dataAccessConfigWireValue, err := convertSlice(v.DataAccessConfig, endpointConfPairToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SetWorkspaceWarehouseConfigRequest.DataAccessConfig", err) + } + channelWireValue, err := channelToWire(v.Channel) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SetWorkspaceWarehouseConfigRequest.Channel", err) + } + globalParamWireValue, err := repeatedEndpointConfPairsToWire(v.GlobalParam) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SetWorkspaceWarehouseConfigRequest.GlobalParam", err) + } + configParamWireValue, err := repeatedEndpointConfPairsToWire(v.ConfigParam) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SetWorkspaceWarehouseConfigRequest.ConfigParam", err) + } + sqlConfigurationParametersWireValue, err := repeatedEndpointConfPairsToWire(v.SqlConfigurationParameters) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SetWorkspaceWarehouseConfigRequest.SqlConfigurationParameters", err) + } + enabledWarehouseTypesWireValue, err := convertSlice(v.EnabledWarehouseTypes, warehouseTypePairToWire) + if err != nil { + return nil, fmt.Errorf("%s: %w", "SetWorkspaceWarehouseConfigRequest.EnabledWarehouseTypes", err) + } + return &setWorkspaceWarehouseConfigRequestWire{ + SecurityPolicy: v.SecurityPolicy, + DataAccessConfig: dataAccessConfigWireValue, + InstanceProfileArn: v.InstanceProfileArn, + Channel: channelWireValue, + EnableServerlessCompute: v.EnableServerlessCompute, + GlobalParam: globalParamWireValue, + ConfigParam: configParamWireValue, + SqlConfigurationParameters: sqlConfigurationParametersWireValue, + GoogleServiceAccount: v.GoogleServiceAccount, + EnabledWarehouseTypes: enabledWarehouseTypesWireValue, + }, nil +} + +type terminationReasonWire struct { + Code TerminationCode `json:"code,omitempty"` + Type TerminationType `json:"type,omitempty"` + Parameters map[string]string `json:"parameters,omitempty"` +} + +func terminationReasonFromWire(w *terminationReasonWire) (*TerminationReason, error) { + if w == nil { + return nil, nil + } + return &TerminationReason{ + Code: w.Code, + Type: w.Type, + Parameters: w.Parameters, + }, nil +} + +type updateDefaultWarehouseOverrideRequestWire struct { + DefaultWarehouseOverride *defaultWarehouseOverrideWire `json:"default_warehouse_override,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` + AllowMissing *bool `json:"allow_missing,omitempty"` +} + +func updateDefaultWarehouseOverrideRequestToWire(v *UpdateDefaultWarehouseOverrideRequest) (*updateDefaultWarehouseOverrideRequestWire, error) { + if v == nil { + return nil, nil + } + defaultWarehouseOverrideWireValue, err := defaultWarehouseOverrideToWire(v.DefaultWarehouseOverride) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateDefaultWarehouseOverrideRequest.DefaultWarehouseOverride", err) + } + return &updateDefaultWarehouseOverrideRequestWire{ + DefaultWarehouseOverride: defaultWarehouseOverrideWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + AllowMissing: v.AllowMissing, + }, nil +} + +type warehouseTypePairWire struct { + WarehouseType WarehouseType `json:"warehouse_type,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func warehouseTypePairToWire(v *WarehouseTypePair) (*warehouseTypePairWire, error) { + if v == nil { + return nil, nil + } + return &warehouseTypePairWire{ + WarehouseType: v.WarehouseType, + Enabled: v.Enabled, + }, nil +} + +func warehouseTypePairFromWire(w *warehouseTypePairWire) (*WarehouseTypePair, error) { + if w == nil { + return nil, nil + } + return &WarehouseTypePair{ + WarehouseType: w.WarehouseType, + Enabled: w.Enabled, + }, nil +} + +type listWarehousesRequestWire struct { + RunAsUserId *int64 `json:"run_as_user_id,omitempty"` + PageSize *int `json:"page_size,omitempty"` + PageToken *string `json:"page_token,omitempty"` +} + +func listWarehousesRequestToWire(v *ListWarehousesRequest) (*listWarehousesRequestWire, error) { + if v == nil { + return nil, nil + } + return &listWarehousesRequestWire{ + RunAsUserId: v.RunAsUserId, + PageSize: v.PageSize, + PageToken: v.PageToken, + }, nil +} + +type startRequestWire struct { + Id *string `json:"id,omitempty"` +} + +func startRequestToWire(v *StartRequest) (*startRequestWire, error) { + if v == nil { + return nil, nil + } + return &startRequestWire{ + Id: v.Id, + }, nil +} + +type stopRequestWire struct { + Id *string `json:"id,omitempty"` +} + +func stopRequestToWire(v *StopRequest) (*stopRequestWire, error) { + if v == nil { + return nil, nil + } + return &stopRequestWire{ + Id: v.Id, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +} diff --git a/workspaces/.package.json b/workspaces/.package.json new file mode 100644 index 0000000..514f22d --- /dev/null +++ b/workspaces/.package.json @@ -0,0 +1,3 @@ +{ + "package": "workspaces" +} diff --git a/workspaces/CHANGELOG.md b/workspaces/CHANGELOG.md new file mode 100644 index 0000000..6224c04 --- /dev/null +++ b/workspaces/CHANGELOG.md @@ -0,0 +1,3 @@ +# Version changelog + +## Release v0.0.1-dev.1 (2026-08-20) diff --git a/workspaces/README.md b/workspaces/README.md new file mode 100644 index 0000000..6b62f6e --- /dev/null +++ b/workspaces/README.md @@ -0,0 +1,30 @@ +# github.com/databricks/sdk-go/workspaces + +> [!WARNING] +> +> ## ⚠️ PREVIEW - NOT FOR PRODUCTION USE +> +> **This SDK is in active development and is subject to change without notice.** +> +> - ❌ **Do NOT use in production environments** +> - ⚠️ **Breaking changes may occur at any time** +> - 🔬 **APIs are experimental and unstable** + +## Installation + +```bash +go get github.com/databricks/sdk-go/workspaces@latest +``` + +## Usage + +```go +import "github.com/databricks/sdk-go/workspaces/v1" + +client, err := workspaces.NewClient(ctx) +if err != nil { + return err +} +``` + +For a full getting-started guide, see the [root README](../README.md). diff --git a/workspaces/go.mod b/workspaces/go.mod new file mode 100644 index 0000000..3023c4d --- /dev/null +++ b/workspaces/go.mod @@ -0,0 +1,20 @@ +module github.com/databricks/sdk-go/workspaces + +go 1.26.0 + +replace github.com/databricks/sdk-go/auth => ../auth + +replace github.com/databricks/sdk-go/core => ../core + +replace github.com/databricks/sdk-go/options => ../options + +require ( + github.com/databricks/sdk-go/auth v0.0.1-dev.1 + github.com/databricks/sdk-go/core v0.0.1-dev.1 + github.com/databricks/sdk-go/options v0.0.1-dev.1 +) + +require ( + golang.org/x/oauth2 v0.33.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect +) diff --git a/workspaces/internal/version.go b/workspaces/internal/version.go new file mode 100644 index 0000000..3384e0c --- /dev/null +++ b/workspaces/internal/version.go @@ -0,0 +1,5 @@ +package internal + +const ModuleName = "sdk-go-workspaces" + +const Version = "0.0.1-dev.1" diff --git a/workspaces/v1/client.go b/workspaces/v1/client.go new file mode 100755 index 0000000..4dd4fff --- /dev/null +++ b/workspaces/v1/client.go @@ -0,0 +1,668 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package workspaces + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "net/url" + "sync" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/clientinfo" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/client" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" + "github.com/databricks/sdk-go/workspaces/internal" +) + +type Client struct { + internalClient + + // extensions is a per-client store for hand-written mixins to attach + // lazily-built state. Keys should be unexported types private to the + // mixin, following the context.Value convention, to avoid collisions. + // The zero value is ready to use; it is safe for concurrent use. + extensions sync.Map +} + +type internalClient struct { + httpClient *http.Client + credentials auth.Credentials + logger *slog.Logger + userAgent func() (string, error) + host string + workspaceID string + accountID string +} + +func NewClient(ctx context.Context, opts ...client.Option) (*Client, error) { + cfg := internaloptions.ClientOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return nil, err + } + } + if err := cfg.Resolve(); err != nil { + return nil, err + } + userAgent := func() (string, error) { + info, err := clientinfo.Default().With( + internal.ModuleName, internal.Version, + "auth", cfg.Credentials.Name(), + ) + if err != nil { + return "", err + } + return info.String(), nil + } + + return &Client{ + internalClient: internalClient{ + httpClient: cfg.HTTPClient, + credentials: cfg.Credentials, + logger: cfg.Logger, + userAgent: userAgent, + host: cfg.Host, + workspaceID: cfg.WorkspaceID, + accountID: cfg.AccountID, + }, + }, nil +} + +// Creates a new workspace using a credential configuration and a storage +// configuration, an optional network configuration (if using a customer-managed +// VPC), an optional managed services key configuration (if using +// customer-managed keys for managed services), and an optional storage key +// configuration (if using customer-managed keys for storage). The key +// configurations used for managed services and storage encryption can be the +// same or different. +// +// Important: This operation is asynchronous. A response with HTTP status code +// 200 means the request has been accepted and is in progress, but does not mean +// that the workspace deployed successfully and is running. The initial +// workspace status is typically PROVISIONING. Use the workspace ID +// (workspace_id) field in the response to identify the new workspace and make +// repeated GET requests with the workspace ID and check its status. The +// workspace becomes available when the status changes to RUNNING. +// +// You can share one customer-managed VPC with multiple workspaces in a single +// account. It is not required to create a new VPC for each workspace. However, +// you cannot reuse subnets or Security Groups between workspaces. If you plan +// to share one VPC with multiple workspaces, make sure you size your VPC and +// subnets accordingly. Because a Databricks Account API network configuration +// encapsulates this information, you cannot reuse a Databricks Account API +// network configuration across workspaces. +// +// For information about how to create a new workspace with this API including +// error handling, see [Create a new workspace using the Account API]. +// +// Important: Customer-managed VPCs, PrivateLink, and customer-managed keys are +// supported on a limited set of deployment and subscription types. If you have +// questions about availability, contact your representative. +// +// This operation is available only if your account is on the E2 version of the +// platform or on a select custom plan that allows multiple workspaces per +// account. +// +// [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) createWorkspacePublicBase(ctx context.Context, req *CreateWorkspaceRequest, opts ...call.Option) (*Workspace, error) { + wireReq, err := createWorkspaceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Workspace + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "POST", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp workspaceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = workspaceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Creates a new workspace using a credential configuration and a storage +// configuration, an optional network configuration (if using a customer-managed +// VPC), an optional managed services key configuration (if using +// customer-managed keys for managed services), and an optional storage key +// configuration (if using customer-managed keys for storage). The key +// configurations used for managed services and storage encryption can be the +// same or different. +// +// Important: This operation is asynchronous. A response with HTTP status code +// 200 means the request has been accepted and is in progress, but does not mean +// that the workspace deployed successfully and is running. The initial +// workspace status is typically PROVISIONING. Use the workspace ID +// (workspace_id) field in the response to identify the new workspace and make +// repeated GET requests with the workspace ID and check its status. The +// workspace becomes available when the status changes to RUNNING. +// +// You can share one customer-managed VPC with multiple workspaces in a single +// account. It is not required to create a new VPC for each workspace. However, +// you cannot reuse subnets or Security Groups between workspaces. If you plan +// to share one VPC with multiple workspaces, make sure you size your VPC and +// subnets accordingly. Because a Databricks Account API network configuration +// encapsulates this information, you cannot reuse a Databricks Account API +// network configuration across workspaces. +// +// For information about how to create a new workspace with this API including +// error handling, see [Create a new workspace using the Account API]. +// +// Important: Customer-managed VPCs, PrivateLink, and customer-managed keys are +// supported on a limited set of deployment and subscription types. If you have +// questions about availability, contact your representative. +// +// This operation is available only if your account is on the E2 version of the +// platform or on a select custom plan that allows multiple workspaces per +// account. +// +// [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html +func (c *internalClient) CreateWorkspacePublic(ctx context.Context, req *CreateWorkspaceRequest, opts ...call.Option) (*CreateWorkspacePublicWaiter, error) { + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + resp, err := c.createWorkspacePublicBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.WorkspaceId == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "WorkspaceId") + } + return &CreateWorkspacePublicWaiter{ + poll: c.GetWorkspacePublic, + accountID: accountID, + workspaceId: *resp.WorkspaceId, + }, nil +} + +// CreateWorkspacePublicWaiter tracks the state of the operation started by CreateWorkspacePublic. +type CreateWorkspacePublicWaiter struct { + poll func(context.Context, *GetWorkspaceRequest, ...call.Option) (*Workspace, error) + accountID string + workspaceId int64 +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *CreateWorkspacePublicWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetWorkspaceRequest{ + AccountId: &w.accountID, + WorkspaceId: &w.workspaceId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.WorkspaceStatus + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case WorkspaceStatus_Running, WorkspaceStatus_Banned, WorkspaceStatus_Failed: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *CreateWorkspacePublicWaiter) Wait(ctx context.Context, opts ...lro.Option) (*Workspace, error) { + var result *Workspace + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetWorkspaceRequest{ + AccountId: &w.accountID, + WorkspaceId: &w.workspaceId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.WorkspaceStatus + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case WorkspaceStatus_Running: + result = pollResp + return nil + case WorkspaceStatus_Banned, WorkspaceStatus_Failed: + message := "(no message)" + if pollResp.WorkspaceStatusMessage != nil { + message = fmt.Sprintf("%v", *pollResp.WorkspaceStatusMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} + +// Deletes a workspace, both specified by ID. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) DeleteWorkspacePublic(ctx context.Context, req *DeleteWorkspaceRequest, opts ...call.Option) (*Workspace, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Workspace + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "DELETE", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp workspaceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = workspaceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Gets information including status for a workspace, specified by +// ID. In the response, the `workspace_status` field indicates the current +// status. After initial workspace creation (which is asynchronous), make +// repeated `GET` requests with the workspace ID and check its status. The +// workspace becomes available when the status changes to `RUNNING`. For +// information about how to create a new workspace with this API **including +// error handling**, see [Create a new workspace using the Account API]. +// +// [Create a new workspace using the Account API]: http://docs.databricks.com/administration-guide/account-api/new-workspace.html +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) GetWorkspacePublic(ctx context.Context, req *GetWorkspaceRequest, opts ...call.Option) (*Workspace, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.WorkspaceId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Workspace + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp workspaceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = workspaceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Lists workspaces for an account. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) ListWorkspacesPublic(ctx context.Context, req *ListWorkspacesRequest, opts ...call.Option) (*ListWorkspacesResponse, error) { + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + if req.AccountId != nil && *req.AccountId != "" { + accountID = *req.AccountId + } + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces") + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *ListWorkspacesResponse + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "GET", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp []workspaceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + convertedResponseBody, err := convertSlice(wireResp, workspaceFromWire) + if err != nil { + return fmt.Errorf("ListWorkspacesResponse.Workspaces: %w", err) + } + resp = &ListWorkspacesResponse{ + Workspaces: convertedResponseBody, + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a workspace. +// Account-level method. Uses the Client's accountID, overridable per call via req.AccountId. +func (c *internalClient) updateWorkspacePublicBase(ctx context.Context, req *UpdateWorkspaceRequest, opts ...call.Option) (*Workspace, error) { + wireReq, err := updateWorkspaceRequestToWire(req) + if err != nil { + return nil, err + } + body, err := json.Marshal(wireReq.CustomerFacingWorkspace) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + + baseURL, err := url.Parse(c.host) + if err != nil { + return nil, err + } + accountID := c.accountID + pb := pathBuilder{} + pb.literal("/api/2.0/accounts/") + pb.singleSegment(accountID) + pb.literal("/workspaces/") + pb.singleSegment(*req.CustomerFacingWorkspace.WorkspaceId) + baseURL.Path, baseURL.RawPath = pb.build() + queryParams := url.Values{} + if err := addQueryValue(queryParams, "update_mask", wireReq.UpdateMask); err != nil { + return nil, err + } + baseURL.RawQuery = queryParams.Encode() + urlStr := baseURL.String() + + var resp *Workspace + + call := func(ctx context.Context) error { + httpReq, err := newHTTPRequest(ctx, httpRequestOptions{ + Method: "PATCH", + URL: urlStr, + Credentials: c.credentials, + UserAgent: c.userAgent, + Headers: headers, + Body: bytes.NewBuffer(body), + }) + if err != nil { + return err + } + + respBody, _, err := executeHTTPCall(httpCallOptions{ + req: httpReq, + client: c.httpClient, + logger: c.logger, + }) + if err != nil { + return err + } + var wireResp workspaceWire + if err := json.Unmarshal(respBody, &wireResp); err != nil { + return err + } + resp, err = workspaceFromWire(&wireResp) + if err != nil { + return err + } + return nil + } + + if err := executeCall(ctx, call, opts); err != nil { + return nil, err + } + return resp, nil +} + +// Updates a workspace. +func (c *internalClient) UpdateWorkspacePublic(ctx context.Context, req *UpdateWorkspaceRequest, opts ...call.Option) (*UpdateWorkspacePublicWaiter, error) { + accountID := c.accountID + resp, err := c.updateWorkspacePublicBase(ctx, req, opts...) + if err != nil { + return nil, err + } + if resp.WorkspaceId == nil { + return nil, fmt.Errorf("response field %q required for polling is missing", "WorkspaceId") + } + return &UpdateWorkspacePublicWaiter{ + poll: c.GetWorkspacePublic, + accountID: accountID, + workspaceId: *resp.WorkspaceId, + }, nil +} + +// UpdateWorkspacePublicWaiter tracks the state of the operation started by UpdateWorkspacePublic. +type UpdateWorkspacePublicWaiter struct { + poll func(context.Context, *GetWorkspaceRequest, ...call.Option) (*Workspace, error) + accountID string + workspaceId int64 +} + +// Done polls once and reports whether the operation has reached a terminal state. +func (w *UpdateWorkspacePublicWaiter) Done(ctx context.Context, opts ...call.Option) (bool, error) { + pollResp, err := w.poll(ctx, &GetWorkspaceRequest{ + AccountId: &w.accountID, + WorkspaceId: &w.workspaceId, + }, opts...) + if err != nil { + return false, err + } + if pollResp == nil { + return false, fmt.Errorf("response is missing") + } + status := pollResp.WorkspaceStatus + if status == "" { + return false, fmt.Errorf("response missing required status field") + } + switch status { + case WorkspaceStatus_Running, WorkspaceStatus_Banned, WorkspaceStatus_Failed: + return true, nil + default: + return false, nil + } +} + +// Wait polls until the operation reaches a terminal state. +func (w *UpdateWorkspacePublicWaiter) Wait(ctx context.Context, opts ...lro.Option) (*Workspace, error) { + var result *Workspace + poll := func(ctx context.Context) error { + pollResp, err := w.poll(ctx, &GetWorkspaceRequest{ + AccountId: &w.accountID, + WorkspaceId: &w.workspaceId, + }) + if err != nil { + return err + } + if pollResp == nil { + return fmt.Errorf("response is missing") + } + status := pollResp.WorkspaceStatus + if status == "" { + return fmt.Errorf("response missing required status field") + } + switch status { + case WorkspaceStatus_Running: + result = pollResp + return nil + case WorkspaceStatus_Banned, WorkspaceStatus_Failed: + message := "(no message)" + if pollResp.WorkspaceStatusMessage != nil { + message = fmt.Sprintf("%v", *pollResp.WorkspaceStatusMessage) + } + return fmt.Errorf("terminal state %s: %s", status, message) + default: + return errOperationStillRunning + } + } + if err := executeWait(ctx, poll, opts...); err != nil { + return nil, err + } + return result, nil +} diff --git a/workspaces/v1/genhelper.go b/workspaces/v1/genhelper.go new file mode 100755 index 0000000..ef7b4a3 --- /dev/null +++ b/workspaces/v1/genhelper.go @@ -0,0 +1,243 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package workspaces + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "strings" + + "github.com/databricks/sdk-go/auth" + "github.com/databricks/sdk-go/core/apierr" + "github.com/databricks/sdk-go/core/ops" + "github.com/databricks/sdk-go/options/call" + "github.com/databricks/sdk-go/options/internaloptions" + "github.com/databricks/sdk-go/options/lro" +) + +type httpCallOptions struct { + req *http.Request + client *http.Client + logger *slog.Logger +} + +type httpRequestOptions struct { + Method string + URL string + Credentials auth.Credentials + UserAgent func() (string, error) + Headers http.Header + Body io.Reader +} + +func newHTTPRequest(ctx context.Context, opts httpRequestOptions) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, opts.Method, opts.URL, opts.Body) + if err != nil { + closeBody(opts.Body) + return nil, err + } + + req.Header = opts.Headers.Clone() + if opts.Credentials != nil { + headers, err := opts.Credentials.AuthHeaders(ctx) + if err != nil { + closeBody(opts.Body) + return nil, err + } + for _, h := range headers { + req.Header.Add(h.Key, h.Value) + } + } + if opts.UserAgent != nil { + userAgent, err := opts.UserAgent() + if err != nil { + closeBody(opts.Body) + return nil, err + } + if userAgent != "" { + req.Header.Set("User-Agent", userAgent) + } + } + + return req, nil +} + +func closeBody(body io.Reader) { + if body == nil { + return + } + if rc, ok := body.(io.ReadCloser); ok { + _ = rc.Close() + } +} + +// lazyRequest implements slog.LogValuer for lazy evaluation of request +// logging. +type lazyRequest struct{ req *http.Request } + +func (r lazyRequest) LogValue() slog.Value { + return slog.GroupValue( + slog.String("method", r.req.Method), + slog.String("url", r.req.URL.String()), + ) +} + +// lazyResponse implements slog.LogValuer for lazy evaluation of response +// logging. +type lazyResponse struct { + resp *http.Response + body []byte +} + +func (r lazyResponse) LogValue() slog.Value { + return slog.GroupValue( + slog.Int("status", r.resp.StatusCode), + slog.String("body", string(r.body)), + ) +} + +// executeHTTPCall executes an HTTP call and returns the response body and +// headers, or an error. The headers are returned so callers can populate +// header-mapped response fields alongside the JSON body. This function takes +// care of logging the request and response. +func executeHTTPCall(opts httpCallOptions) ([]byte, http.Header, error) { + opts.logger.Debug("HTTP request", "request", lazyRequest{opts.req}) + resp, err := opts.client.Do(opts.req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, nil}) + return nil, nil, err + } + opts.logger.Debug("HTTP response", "response", lazyResponse{resp, body}) + if err := apierr.FromHTTPError(resp.StatusCode, resp.Header, body); err != nil { + return nil, nil, err + } + return body, resp.Header, nil +} + +// executeCall resolves call.Option values to ops.Option values and invokes +// ops.Execute. +func executeCall(ctx context.Context, op func(context.Context) error, opts []call.Option) error { + cfg := internaloptions.CallOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + var opsOpts []ops.Option + if cfg.Retrier != nil { + opsOpts = append(opsOpts, ops.WithRetrier(cfg.Retrier)) + } + if cfg.RateLimiter != nil { + opsOpts = append(opsOpts, ops.WithLimiter(cfg.RateLimiter)) + } + if cfg.Timeout != 0 { + opsOpts = append(opsOpts, ops.WithTimeout(cfg.Timeout)) + } + return ops.Execute(ctx, op, opsOpts...) +} + +var errOperationStillRunning = errors.New("operation is still running") + +func executeWait(ctx context.Context, operation func(context.Context) error, opts ...lro.Option) error { + cfg := internaloptions.LROOptions{} + for _, opt := range opts { + if err := opt(&cfg); err != nil { + return err + } + } + return ops.Execute(ctx, operation, + ops.WithTimeout(cfg.Timeout), + ops.WithRetrier(func() ops.Retrier { + return ops.RetryIf(ops.BackoffPolicy{}, func(err error) bool { + return errors.Is(err, errOperationStillRunning) + }) + }), + ) +} + +func addQueryValue(params url.Values, key string, value any) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + var decoded any + if err := decoder.Decode(&decoded); err != nil { + return err + } + flattenQueryValue(params, key, decoded) + return nil +} + +func flattenQueryValue(params url.Values, key string, value any) { + switch value := value.(type) { + case nil: + // JSON null represents an absent query value. + case map[string]any: + for childKey, child := range value { + flattenQueryValue(params, key+"."+childKey, child) + } + case []any: + for _, item := range value { + params.Add(key, fmt.Sprintf("%v", item)) + } + default: + params.Add(key, fmt.Sprintf("%v", value)) + } +} + +// pathBuilder assembles a request path from static literals and parameter +// values. It tracks the decoded path and its percent-escaped wire form in +// lockstep so build() can assign both url.URL.Path and url.URL.RawPath; because +// RawPath is a valid escaping of Path, url.URL.String() emits it verbatim +// instead of re-escaping (which would double-encode "%"). +type pathBuilder struct { + path strings.Builder + raw strings.Builder +} + +// literal appends a static path segment, identical on the decoded and escaped +// paths. +func (b *pathBuilder) literal(s string) { + b.path.WriteString(s) + b.raw.WriteString(s) +} + +// singleSegment appends a single-segment path parameter: the value occupies one +// path segment, so everything is escaped, including "/". The value is formatted +// with %v so strings, enums, and numbers all work. +func (b *pathBuilder) singleSegment(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + b.raw.WriteString(url.PathEscape(s)) +} + +// multiSegments appends a multi-segment path parameter: the value spans several +// path segments, so each segment is escaped but the "/" separators are kept. +// The value is formatted with %v so strings, enums, and numbers all work. +func (b *pathBuilder) multiSegments(v any) { + s := fmt.Sprintf("%v", v) + b.path.WriteString(s) + segments := strings.Split(s, "/") + for i, seg := range segments { + segments[i] = url.PathEscape(seg) + } + b.raw.WriteString(strings.Join(segments, "/")) +} + +func (b *pathBuilder) build() (path, rawPath string) { + return b.path.String(), b.raw.String() +} diff --git a/workspaces/v1/model.go b/workspaces/v1/model.go new file mode 100755 index 0000000..c9c55c4 --- /dev/null +++ b/workspaces/v1/model.go @@ -0,0 +1,389 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package workspaces + +import ( + "github.com/databricks/sdk-go/core/types" +) + +// Corresponds to compute mode defined here: +// https://src.dev.databricks.com/databricks/universe@9076536b18479afd639d1c1f9dd5a59f72215e69/-/blob/central/api/common.proto?L872 +type ComputeMode string + +const ( + ComputeMode_Unspecified ComputeMode = "" + // Classic + Serverless + ComputeMode_Hybrid ComputeMode = "HYBRID" + // Serverless-only. + ComputeMode_Serverless ComputeMode = "SERVERLESS" +) + +// Specifies the network connectivity types for the GKE nodes and the GKE master +// network. +// +// Set to `PRIVATE_NODE_PUBLIC_MASTER` for a private GKE cluster for the +// workspace. The GKE nodes will not have public IPs. +// +// Set to `PUBLIC_NODE_PUBLIC_MASTER` for a public GKE cluster. The nodes of a +// public GKE cluster have public IP addresses. +type GkeConnectivityType string + +const ( + GkeConnectivityType_Unspecified GkeConnectivityType = "" + // The nodes of the GKE cluster will have private IP only. GKE master will still + // have a public IP. + GkeConnectivityType_PrivateNodePublicMaster GkeConnectivityType = "PRIVATE_NODE_PUBLIC_MASTER" + // The GKE cluster will have public IPs for both its nodes and GKE master. + GkeConnectivityType_PublicNodePublicMaster GkeConnectivityType = "PUBLIC_NODE_PUBLIC_MASTER" +) + +type PricingTier string + +const ( + PricingTier_Unspecified PricingTier = "" + // Tier for CE workspaces + PricingTier_CommunityEdition PricingTier = "COMMUNITY_EDITION" + // Standard pricing tier that maps to STANDARD_TIER feature tier + PricingTier_Standard PricingTier = "STANDARD" + // Premium pricing tier that maps to STANDARD_W_SEC_TIER feature tier + PricingTier_Premium PricingTier = "PREMIUM" + // Enterprise pricing tier that maps to ENTERPRISE_TIER_V2 feature tier + PricingTier_Enterprise PricingTier = "ENTERPRISE" + // Dedicated pricing tier that maps to the DEDICATED feature tier + PricingTier_Dedicated PricingTier = "DEDICATED" +) + +type StorageMode string + +const ( + StorageMode_Unspecified StorageMode = "" + // The storage resources of the workspace are hosted by customers. + StorageMode_CustomerHosted StorageMode = "CUSTOMER_HOSTED" + // The storage resources of the workspace are hosted by Databricks. + StorageMode_DefaultStorage StorageMode = "DEFAULT_STORAGE" +) + +// The different statuses of a workspace. The following represents the current +// set of valid transitions from status to status: NOT_PROVISIONED -> +// PROVISIONING -> CANCELLED PROVISIONING -> RUNNING -> FAILED -> CANCELLED +// (note that this transition is disallowed in the MultiWorkspace Project) +// RUNNING -> PROVISIONING -> BANNED -> CANCELLED FAILED -> PROVISIONING -> +// CANCELLED BANNED -> RUNNING -> CANCELLED Note that a transition from any +// state to itself is also valid. +type WorkspaceStatus string + +const ( + WorkspaceStatus_Unspecified WorkspaceStatus = "" + // Status for workspaces being provisioned. + WorkspaceStatus_Provisioning WorkspaceStatus = "PROVISIONING" + // Status for running workspaces. + WorkspaceStatus_Running WorkspaceStatus = "RUNNING" + // Status for workspaces that have failed to be provisioned. This is currently + // an AWS-only state since an Azure customer can easily retry to launch a + // workspace that failed to launch, whereas this process is different in AWS. + WorkspaceStatus_Failed WorkspaceStatus = "FAILED" + // Status for banned workspaces. This is intended for use with CE workspaces, + // although there is no code to enforce this restriction. These workspaces can + // be unbanned at a later time. + WorkspaceStatus_Banned WorkspaceStatus = "BANNED" + // Status for cancelling workspaces. This state always comes before the + // CANCELLED status. + WorkspaceStatus_Cancelling WorkspaceStatus = "CANCELLING" +) + +type AzureWorkspaceInfo struct { + // Azure Resource Group name + ResourceGroup *string `fieldmask:"resource_group"` + // Azure Subscription ID + SubscriptionId *string `fieldmask:"subscription_id"` +} + +type CloudResourceContainer struct { + CloudResourceContainer isCloudResourceContainer_CloudResourceContainer + _ [0]cloudResourceContainerCloudResourceContainerFieldMaskMetadata `fieldmask_oneof:"CloudResourceContainer"` +} + +type isCloudResourceContainer_CloudResourceContainer interface { + isCloudResourceContainer_CloudResourceContainer() +} + +// CloudResourceContainer_CloudResourceContainer_Gcp selects Gcp for CloudResourceContainer.CloudResourceContainer. +type CloudResourceContainer_CloudResourceContainer_Gcp struct { + Gcp GcpCloudResourceContainer `fieldmask:"gcp"` +} + +func (*CloudResourceContainer_CloudResourceContainer_Gcp) isCloudResourceContainer_CloudResourceContainer() { +} + +type cloudResourceContainerCloudResourceContainerFieldMaskMetadata struct { + *CloudResourceContainer_CloudResourceContainer_Gcp +} + +type CreateWorkspaceRequest struct { + AccountId *string + // The human-readable name of the workspace. + WorkspaceName *string + // The deployment name defines part of the subdomain for the workspace. The + // workspace URL for the web application and REST APIs is + // .cloud.databricks.com. For example, if the + // deployment name is abcsales, your workspace URL will be + // https://abcsales.cloud.databricks.com. Hyphens are allowed. This property + // supports only the set of characters that are allowed in a subdomain. To set + // this value, you must have a deployment name prefix. Contact your + // account team to add an account deployment name prefix to your account. + // Workspace deployment names follow the account prefix and a hyphen. For + // example, if your account's deployment prefix is acme and the workspace + // deployment name is workspace-1, the JSON response for the deployment_name + // field becomes acme-workspace-1. The workspace URL would be + // acme-workspace-1.cloud.databricks.com. You can also set the deployment_name + // to the reserved keyword EMPTY if you want the deployment name to only include + // the deployment prefix. For example, if your account's deployment prefix is + // acme and the workspace deployment name is EMPTY, the deployment_name becomes + // acme only and the workspace URL is acme.cloud.databricks.com. This value must + // be unique across all non-deleted deployments across all AWS regions. If a new + // workspace omits this property, the server generates a unique deployment name + // for you with the pattern dbc-xxxxxxxx-xxxx. + DeploymentName *string + AwsRegion *string + // The Google Cloud region of the workspace data plane in your Google account + // (for example, `us-east4`). + Location *string + // DEPRECATED: This field is being ignored by the server and will be removed in + // the future. The cloud name. This field always has the value `gcp`. + Cloud *string + PricingTier PricingTier + CloudResourceContainer *CloudResourceContainer + // ID of the workspace's credential configuration object. + CredentialsId *string + // ID of the workspace's storage configuration object. + StorageConfigurationId *string + // The ID of the workspace's network configuration object. To use AWS + // PrivateLink, this field is required. + NetworkId *string + GcpManagedNetworkConfig *GcpManagedNetworkConfig + GkeConfig *GkeConfig + // ID of the workspace's private access settings object. Only used for + // PrivateLink. You must specify this ID if you are using [AWS PrivateLink] for + // either front-end (user-to-workspace connection), back-end (data plane to + // control plane connection), or both connection types. Before configuring + // PrivateLink, read the [ article about PrivateLink].", + // + // [ article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html + // [AWS PrivateLink]: https://aws.amazon.com/privatelink/ + PrivateAccessSettingsId *string + // The ID of the workspace's managed services encryption key configuration + // object. This is used to help protect and control access to the workspace's + // notebooks, secrets, Databricks SQL queries, and query history. The provided + // key configuration object property use_cases must contain MANAGED_SERVICES. + ManagedServicesCustomerManagedKeyId *string + // The ID of the workspace's storage encryption key configuration object. This + // is used to encrypt the workspace's root S3 bucket (root DBFS and system data) + // and, optionally, cluster EBS volumes. The provided key configuration object + // property use_cases must contain STORAGE. + StorageCustomerManagedKeyId *string + // The custom tags key-value pairing that is attached to this workspace. The + // key-value pair is a string of utf-8 characters. The value can be an empty + // string, with maximum length of 255 characters. The key can be of maximum + // length of 127 characters, and cannot be empty. + CustomTags map[string]string + // If the compute mode is `SERVERLESS`, a serverless workspace is created that + // comes pre-configured with serverless compute and default storage, providing a + // fully-managed, enterprise-ready SaaS experience. This means you don't need to + // provide any resources managed by you, such as credentials, storage, or + // network. If the compute mode is `HYBRID` (which is the default option), a + // classic workspace is created that uses customer-managed resources. + ComputeMode ComputeMode + // The object ID of network connectivity config. Once assigned, the workspace + // serverless compute resources use the same set of stable IP CIDR blocks and + // optional private link to access your resources. + NetworkConnectivityConfigId *string +} + +type DeleteWorkspaceRequest struct { + WorkspaceId *int64 + AccountId *string +} + +type GcpCloudResourceContainer struct { + ProjectId *string `fieldmask:"project_id"` +} + +// The shared network config for GCP workspace. This object has common network +// configurations that are network attributions of a workspace. DEPRECATED. Use +// GkeConfig instead.. +type GcpCommonNetworkConfig struct { + // The type of network connectivity of the GKE cluster. + GkeConnectivityType GkeConnectivityType `fieldmask:"gke_connectivity_type"` + // The IP range that will be used to allocate GKE cluster master resources from. + // This field must not be set if gke_cluster_type=PUBLIC_NODE_PUBLIC_MASTER. + GkeClusterMasterIpRange *string `fieldmask:"gke_cluster_master_ip_range"` +} + +// The network configuration for the workspace.. +type GcpManagedNetworkConfig struct { + // The IP range which will be used to allocate GKE cluster nodes from. Note: + // Pods, services and master IP range must be mutually exclusive. + SubnetCidr *string `fieldmask:"subnet_cidr"` + // The IP range that will be used to allocate GKE cluster Pods from. + GkeClusterPodIpRange *string `fieldmask:"gke_cluster_pod_ip_range"` + // The IP range that will be used to allocate GKE cluster Services from. + GkeClusterServiceIpRange *string `fieldmask:"gke_cluster_service_ip_range"` +} + +type GetWorkspaceRequest struct { + WorkspaceId *int64 + AccountId *string +} + +// The configurations of the GKE cluster used by the GCP workspace.. +type GkeConfig struct { + // The type of network connectivity of the GKE cluster. + ConnectivityType GkeConnectivityType `fieldmask:"connectivity_type"` + // The IP range that will be used to allocate GKE cluster master resources from. + // This field must not be set if gke_cluster_type=PUBLIC_NODE_PUBLIC_MASTER. + MasterIpRange *string `fieldmask:"master_ip_range"` +} + +type ListWorkspacesRequest struct { + AccountId *string +} + +type ListWorkspacesResponse struct { + Workspaces []Workspace +} + +type UpdateWorkspaceRequest struct { + CustomerFacingWorkspace *Workspace + UpdateMask *types.FieldMask[Workspace] +} + +type Workspace struct { + // A unique integer ID for the workspace + WorkspaceId *int64 `fieldmask:"workspace_id"` + // The human-readable name of the workspace. + WorkspaceName *string `fieldmask:"workspace_name"` + AwsRegion *string `fieldmask:"aws_region"` + // Time in epoch milliseconds when the workspace was created. + CreationTime *int64 `fieldmask:"creation_time"` + DeploymentName *string `fieldmask:"deployment_name"` + // The status of a workspace + WorkspaceStatus WorkspaceStatus `fieldmask:"workspace_status"` + // account ID. + AccountId *string `fieldmask:"account_id"` + // ID of the workspace's credential configuration object. + CredentialsId *string `fieldmask:"credentials_id"` + // ID of the workspace's storage configuration object. + StorageConfigurationId *string `fieldmask:"storage_configuration_id"` + // Message describing the current workspace status. + WorkspaceStatusMessage *string `fieldmask:"workspace_status_message"` + NetworkConfig isWorkspace_NetworkConfig + PricingTier PricingTier `fieldmask:"pricing_tier"` + // ID of the workspace's private access settings object. Only used for + // PrivateLink. You must specify this ID if you are using [AWS PrivateLink] for + // either front-end (user-to-workspace connection), back-end (data plane to + // control plane connection), or both connection types. + // + // Before configuring PrivateLink, read the [ article about + // PrivateLink].", + // + // [ article about PrivateLink]: https://docs.databricks.com/administration-guide/cloud-configurations/aws/privatelink.html + // [AWS PrivateLink]: https://aws.amazon.com/privatelink/ + PrivateAccessSettingsId *string `fieldmask:"private_access_settings_id"` + // ID of the key configuration for encrypting managed services. + ManagedServicesCustomerManagedKeyId *string `fieldmask:"managed_services_customer_managed_key_id"` + // ID of the key configuration for encrypting workspace storage. + StorageCustomerManagedKeyId *string `fieldmask:"storage_customer_managed_key_id"` + // The Google Cloud region of the workspace data plane in your Google account + // (for example, `us-east4`). + Location *string `fieldmask:"location"` + // The cloud name. This field can have values like `azure`, `gcp`. + Cloud *string `fieldmask:"cloud"` + // The network configuration for the workspace. DEPRECATED. Use `network_id` + // instead. + Network *WorkspaceNetwork `fieldmask:"network"` + AzureWorkspaceInfo *AzureWorkspaceInfo `fieldmask:"azure_workspace_info"` + GkeConfig *GkeConfig `fieldmask:"gke_config"` + CloudResourceContainer *CloudResourceContainer `fieldmask:"cloud_resource_container"` + // The custom tags key-value pairing that is attached to this workspace. The + // key-value pair is a string of utf-8 characters. The value can be an empty + // string, with maximum length of 255 characters. The key can be of maximum + // length of 127 characters, and cannot be empty. + CustomTags map[string]string `fieldmask:"custom_tags"` + // The object ID of network connectivity config. + NetworkConnectivityConfigId *string `fieldmask:"network_connectivity_config_id"` + // The storage mode of the workspace. + StorageMode StorageMode `fieldmask:"storage_mode"` + // The compute mode of the workspace. + ComputeMode ComputeMode `fieldmask:"compute_mode"` + // A client owned field used to indicate the workspace status that the client + // expects to be in. For now this is only used to unblock Temporal workflow for + // GCP least privileged workspace. + ExpectedWorkspaceStatus WorkspaceStatus `fieldmask:"expected_workspace_status"` + _ [0]workspaceNetworkConfigFieldMaskMetadata `fieldmask_oneof:"NetworkConfig"` +} + +type isWorkspace_NetworkConfig interface { + isWorkspace_NetworkConfig() +} + +// Workspace_NetworkConfig_NetworkId selects NetworkId for Workspace.NetworkConfig. +// If this workspace is BYO VPC, then the network_id will be populated. If this +// workspace is not BYO VPC, then the network_id will be empty. +type Workspace_NetworkConfig_NetworkId struct { + NetworkId string `fieldmask:"network_id"` +} + +func (*Workspace_NetworkConfig_NetworkId) isWorkspace_NetworkConfig() {} + +// Workspace_NetworkConfig_GcpManagedNetworkConfig selects GcpManagedNetworkConfig for Workspace.NetworkConfig. +type Workspace_NetworkConfig_GcpManagedNetworkConfig struct { + GcpManagedNetworkConfig GcpManagedNetworkConfig `fieldmask:"gcp_managed_network_config"` +} + +func (*Workspace_NetworkConfig_GcpManagedNetworkConfig) isWorkspace_NetworkConfig() {} + +type workspaceNetworkConfigFieldMaskMetadata struct { + *Workspace_NetworkConfig_NetworkId + *Workspace_NetworkConfig_GcpManagedNetworkConfig +} + +// The network configuration for workspaces.. +type WorkspaceNetwork struct { + Network isWorkspaceNetwork_Network + // The shared network config for GCP workspace. This object has common network + // configurations that are network attributions of a workspace. This object is + // input-only. + GcpCommonNetworkConfig *GcpCommonNetworkConfig `fieldmask:"gcp_common_network_config"` + _ [0]workspaceNetworkNetworkFieldMaskMetadata `fieldmask_oneof:"Network"` +} + +type isWorkspaceNetwork_Network interface { + isWorkspaceNetwork_Network() +} + +// WorkspaceNetwork_Network_GcpManagedNetworkConfig selects GcpManagedNetworkConfig for WorkspaceNetwork.Network. +// The mutually exclusive network deployment modes. The option decides which +// network mode the workspace will use. The network config for GCP workspace +// with managed network. This object is input-only and will not be +// provided when listing workspaces. +type WorkspaceNetwork_Network_GcpManagedNetworkConfig struct { + GcpManagedNetworkConfig GcpManagedNetworkConfig `fieldmask:"gcp_managed_network_config"` +} + +func (*WorkspaceNetwork_Network_GcpManagedNetworkConfig) isWorkspaceNetwork_Network() {} + +// WorkspaceNetwork_Network_NetworkId selects NetworkId for WorkspaceNetwork.Network. +// The ID of the network object, if the workspace is a BYOVPC workspace. This +// should apply to workspaces on all clouds in internal services. In +// accounts-rest-api, user will use workspace.network_id for input and output +// instead. Currently (2021-06-19) the network ID is only used by GCP. +type WorkspaceNetwork_Network_NetworkId struct { + NetworkId string `fieldmask:"network_id"` +} + +func (*WorkspaceNetwork_Network_NetworkId) isWorkspaceNetwork_Network() {} + +type workspaceNetworkNetworkFieldMaskMetadata struct { + *WorkspaceNetwork_Network_GcpManagedNetworkConfig + *WorkspaceNetwork_Network_NetworkId +} diff --git a/workspaces/v1/wire.go b/workspaces/v1/wire.go new file mode 100755 index 0000000..d41a714 --- /dev/null +++ b/workspaces/v1/wire.go @@ -0,0 +1,535 @@ +// Code generated by Databricks SDK Generator. DO NOT EDIT. + +package workspaces + +import ( + "fmt" + + "github.com/databricks/sdk-go/core/types" +) + +func fieldMaskToWire[T any](mask *types.FieldMask[T]) *string { + if mask == nil { + return nil + } + value := mask.String() + return &value +} + +type azureWorkspaceInfoWire struct { + ResourceGroup *string `json:"resource_group,omitempty"` + SubscriptionId *string `json:"subscription_id,omitempty"` +} + +func azureWorkspaceInfoToWire(v *AzureWorkspaceInfo) (*azureWorkspaceInfoWire, error) { + if v == nil { + return nil, nil + } + return &azureWorkspaceInfoWire{ + ResourceGroup: v.ResourceGroup, + SubscriptionId: v.SubscriptionId, + }, nil +} + +func azureWorkspaceInfoFromWire(w *azureWorkspaceInfoWire) (*AzureWorkspaceInfo, error) { + if w == nil { + return nil, nil + } + return &AzureWorkspaceInfo{ + ResourceGroup: w.ResourceGroup, + SubscriptionId: w.SubscriptionId, + }, nil +} + +type cloudResourceContainerWire struct { + Gcp *gcpCloudResourceContainerWire `json:"gcp,omitempty"` +} + +func cloudResourceContainerToWire(v *CloudResourceContainer) (*cloudResourceContainerWire, error) { + if v == nil { + return nil, nil + } + var cloudResourceContainerGcpWire *gcpCloudResourceContainerWire + switch value := v.CloudResourceContainer.(type) { + case nil: + case *CloudResourceContainer_CloudResourceContainer_Gcp: + if value != nil { + cloudResourceContainerGcpConverted, err := gcpCloudResourceContainerToWire(&value.Gcp) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CloudResourceContainer.CloudResourceContainer.Gcp", err) + } + cloudResourceContainerGcpWire = cloudResourceContainerGcpConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "CloudResourceContainer.CloudResourceContainer", value) + } + return &cloudResourceContainerWire{ + Gcp: cloudResourceContainerGcpWire, + }, nil +} + +func cloudResourceContainerFromWire(w *cloudResourceContainerWire) (*CloudResourceContainer, error) { + if w == nil { + return nil, nil + } + cloudResourceContainerMembers := 0 + if w.Gcp != nil { + cloudResourceContainerMembers++ + } + if cloudResourceContainerMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "CloudResourceContainer.CloudResourceContainer") + } + var cloudResourceContainerSelection isCloudResourceContainer_CloudResourceContainer + switch { + case w.Gcp != nil: + cloudResourceContainerGcpConverted, err := gcpCloudResourceContainerFromWire(w.Gcp) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CloudResourceContainer.CloudResourceContainer.Gcp", err) + } + cloudResourceContainerSelection = &CloudResourceContainer_CloudResourceContainer_Gcp{Gcp: *cloudResourceContainerGcpConverted} + } + return &CloudResourceContainer{ + CloudResourceContainer: cloudResourceContainerSelection, + }, nil +} + +type createWorkspaceRequestWire struct { + AccountId *string `json:"account_id,omitempty"` + WorkspaceName *string `json:"workspace_name,omitempty"` + DeploymentName *string `json:"deployment_name,omitempty"` + AwsRegion *string `json:"aws_region,omitempty"` + Location *string `json:"location,omitempty"` + Cloud *string `json:"cloud,omitempty"` + PricingTier PricingTier `json:"pricing_tier,omitempty"` + CloudResourceContainer *cloudResourceContainerWire `json:"cloud_resource_container,omitempty"` + CredentialsId *string `json:"credentials_id,omitempty"` + StorageConfigurationId *string `json:"storage_configuration_id,omitempty"` + NetworkId *string `json:"network_id,omitempty"` + GcpManagedNetworkConfig *gcpManagedNetworkConfigWire `json:"gcp_managed_network_config,omitempty"` + GkeConfig *gkeConfigWire `json:"gke_config,omitempty"` + PrivateAccessSettingsId *string `json:"private_access_settings_id,omitempty"` + ManagedServicesCustomerManagedKeyId *string `json:"managed_services_customer_managed_key_id,omitempty"` + StorageCustomerManagedKeyId *string `json:"storage_customer_managed_key_id,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + ComputeMode ComputeMode `json:"compute_mode,omitempty"` + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` +} + +func createWorkspaceRequestToWire(v *CreateWorkspaceRequest) (*createWorkspaceRequestWire, error) { + if v == nil { + return nil, nil + } + cloudResourceContainerWireValue, err := cloudResourceContainerToWire(v.CloudResourceContainer) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateWorkspaceRequest.CloudResourceContainer", err) + } + gcpManagedNetworkConfigWireValue, err := gcpManagedNetworkConfigToWire(v.GcpManagedNetworkConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateWorkspaceRequest.GcpManagedNetworkConfig", err) + } + gkeConfigWireValue, err := gkeConfigToWire(v.GkeConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "CreateWorkspaceRequest.GkeConfig", err) + } + return &createWorkspaceRequestWire{ + AccountId: v.AccountId, + WorkspaceName: v.WorkspaceName, + DeploymentName: v.DeploymentName, + AwsRegion: v.AwsRegion, + Location: v.Location, + Cloud: v.Cloud, + PricingTier: v.PricingTier, + CloudResourceContainer: cloudResourceContainerWireValue, + CredentialsId: v.CredentialsId, + StorageConfigurationId: v.StorageConfigurationId, + NetworkId: v.NetworkId, + GcpManagedNetworkConfig: gcpManagedNetworkConfigWireValue, + GkeConfig: gkeConfigWireValue, + PrivateAccessSettingsId: v.PrivateAccessSettingsId, + ManagedServicesCustomerManagedKeyId: v.ManagedServicesCustomerManagedKeyId, + StorageCustomerManagedKeyId: v.StorageCustomerManagedKeyId, + CustomTags: v.CustomTags, + ComputeMode: v.ComputeMode, + NetworkConnectivityConfigId: v.NetworkConnectivityConfigId, + }, nil +} + +type gcpCloudResourceContainerWire struct { + ProjectId *string `json:"project_id,omitempty"` +} + +func gcpCloudResourceContainerToWire(v *GcpCloudResourceContainer) (*gcpCloudResourceContainerWire, error) { + if v == nil { + return nil, nil + } + return &gcpCloudResourceContainerWire{ + ProjectId: v.ProjectId, + }, nil +} + +func gcpCloudResourceContainerFromWire(w *gcpCloudResourceContainerWire) (*GcpCloudResourceContainer, error) { + if w == nil { + return nil, nil + } + return &GcpCloudResourceContainer{ + ProjectId: w.ProjectId, + }, nil +} + +type gcpCommonNetworkConfigWire struct { + GkeConnectivityType GkeConnectivityType `json:"gke_connectivity_type,omitempty"` + GkeClusterMasterIpRange *string `json:"gke_cluster_master_ip_range,omitempty"` +} + +func gcpCommonNetworkConfigToWire(v *GcpCommonNetworkConfig) (*gcpCommonNetworkConfigWire, error) { + if v == nil { + return nil, nil + } + return &gcpCommonNetworkConfigWire{ + GkeConnectivityType: v.GkeConnectivityType, + GkeClusterMasterIpRange: v.GkeClusterMasterIpRange, + }, nil +} + +func gcpCommonNetworkConfigFromWire(w *gcpCommonNetworkConfigWire) (*GcpCommonNetworkConfig, error) { + if w == nil { + return nil, nil + } + return &GcpCommonNetworkConfig{ + GkeConnectivityType: w.GkeConnectivityType, + GkeClusterMasterIpRange: w.GkeClusterMasterIpRange, + }, nil +} + +type gcpManagedNetworkConfigWire struct { + SubnetCidr *string `json:"subnet_cidr,omitempty"` + GkeClusterPodIpRange *string `json:"gke_cluster_pod_ip_range,omitempty"` + GkeClusterServiceIpRange *string `json:"gke_cluster_service_ip_range,omitempty"` +} + +func gcpManagedNetworkConfigToWire(v *GcpManagedNetworkConfig) (*gcpManagedNetworkConfigWire, error) { + if v == nil { + return nil, nil + } + return &gcpManagedNetworkConfigWire{ + SubnetCidr: v.SubnetCidr, + GkeClusterPodIpRange: v.GkeClusterPodIpRange, + GkeClusterServiceIpRange: v.GkeClusterServiceIpRange, + }, nil +} + +func gcpManagedNetworkConfigFromWire(w *gcpManagedNetworkConfigWire) (*GcpManagedNetworkConfig, error) { + if w == nil { + return nil, nil + } + return &GcpManagedNetworkConfig{ + SubnetCidr: w.SubnetCidr, + GkeClusterPodIpRange: w.GkeClusterPodIpRange, + GkeClusterServiceIpRange: w.GkeClusterServiceIpRange, + }, nil +} + +type gkeConfigWire struct { + ConnectivityType GkeConnectivityType `json:"connectivity_type,omitempty"` + MasterIpRange *string `json:"master_ip_range,omitempty"` +} + +func gkeConfigToWire(v *GkeConfig) (*gkeConfigWire, error) { + if v == nil { + return nil, nil + } + return &gkeConfigWire{ + ConnectivityType: v.ConnectivityType, + MasterIpRange: v.MasterIpRange, + }, nil +} + +func gkeConfigFromWire(w *gkeConfigWire) (*GkeConfig, error) { + if w == nil { + return nil, nil + } + return &GkeConfig{ + ConnectivityType: w.ConnectivityType, + MasterIpRange: w.MasterIpRange, + }, nil +} + +type updateWorkspaceRequestWire struct { + CustomerFacingWorkspace *workspaceWire `json:"customer_facing_workspace,omitempty"` + UpdateMask *string `json:"update_mask,omitempty"` +} + +func updateWorkspaceRequestToWire(v *UpdateWorkspaceRequest) (*updateWorkspaceRequestWire, error) { + if v == nil { + return nil, nil + } + customerFacingWorkspaceWireValue, err := workspaceToWire(v.CustomerFacingWorkspace) + if err != nil { + return nil, fmt.Errorf("%s: %w", "UpdateWorkspaceRequest.CustomerFacingWorkspace", err) + } + return &updateWorkspaceRequestWire{ + CustomerFacingWorkspace: customerFacingWorkspaceWireValue, + UpdateMask: fieldMaskToWire(v.UpdateMask), + }, nil +} + +type workspaceWire struct { + WorkspaceId *int64 `json:"workspace_id,omitempty"` + WorkspaceName *string `json:"workspace_name,omitempty"` + AwsRegion *string `json:"aws_region,omitempty"` + CreationTime *int64 `json:"creation_time,omitempty"` + DeploymentName *string `json:"deployment_name,omitempty"` + WorkspaceStatus WorkspaceStatus `json:"workspace_status,omitempty"` + AccountId *string `json:"account_id,omitempty"` + CredentialsId *string `json:"credentials_id,omitempty"` + StorageConfigurationId *string `json:"storage_configuration_id,omitempty"` + WorkspaceStatusMessage *string `json:"workspace_status_message,omitempty"` + NetworkId *string `json:"network_id,omitempty"` + GcpManagedNetworkConfig *gcpManagedNetworkConfigWire `json:"gcp_managed_network_config,omitempty"` + PricingTier PricingTier `json:"pricing_tier,omitempty"` + PrivateAccessSettingsId *string `json:"private_access_settings_id,omitempty"` + ManagedServicesCustomerManagedKeyId *string `json:"managed_services_customer_managed_key_id,omitempty"` + StorageCustomerManagedKeyId *string `json:"storage_customer_managed_key_id,omitempty"` + Location *string `json:"location,omitempty"` + Cloud *string `json:"cloud,omitempty"` + Network *workspaceNetworkWire `json:"network,omitempty"` + AzureWorkspaceInfo *azureWorkspaceInfoWire `json:"azure_workspace_info,omitempty"` + GkeConfig *gkeConfigWire `json:"gke_config,omitempty"` + CloudResourceContainer *cloudResourceContainerWire `json:"cloud_resource_container,omitempty"` + CustomTags map[string]string `json:"custom_tags,omitempty"` + NetworkConnectivityConfigId *string `json:"network_connectivity_config_id,omitempty"` + StorageMode StorageMode `json:"storage_mode,omitempty"` + ComputeMode ComputeMode `json:"compute_mode,omitempty"` + ExpectedWorkspaceStatus WorkspaceStatus `json:"expected_workspace_status,omitempty"` +} + +func workspaceToWire(v *Workspace) (*workspaceWire, error) { + if v == nil { + return nil, nil + } + networkWireValue, err := workspaceNetworkToWire(v.Network) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Workspace.Network", err) + } + azureWorkspaceInfoWireValue, err := azureWorkspaceInfoToWire(v.AzureWorkspaceInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Workspace.AzureWorkspaceInfo", err) + } + gkeConfigWireValue, err := gkeConfigToWire(v.GkeConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Workspace.GkeConfig", err) + } + cloudResourceContainerWireValue, err := cloudResourceContainerToWire(v.CloudResourceContainer) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Workspace.CloudResourceContainer", err) + } + var networkConfigNetworkIdWire *string + var networkConfigGcpManagedNetworkConfigWire *gcpManagedNetworkConfigWire + switch value := v.NetworkConfig.(type) { + case nil: + case *Workspace_NetworkConfig_NetworkId: + if value != nil { + networkConfigNetworkIdWire = new(value.NetworkId) + } + case *Workspace_NetworkConfig_GcpManagedNetworkConfig: + if value != nil { + networkConfigGcpManagedNetworkConfigConverted, err := gcpManagedNetworkConfigToWire(&value.GcpManagedNetworkConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Workspace.NetworkConfig.GcpManagedNetworkConfig", err) + } + networkConfigGcpManagedNetworkConfigWire = networkConfigGcpManagedNetworkConfigConverted + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "Workspace.NetworkConfig", value) + } + return &workspaceWire{ + WorkspaceId: v.WorkspaceId, + WorkspaceName: v.WorkspaceName, + AwsRegion: v.AwsRegion, + CreationTime: v.CreationTime, + DeploymentName: v.DeploymentName, + WorkspaceStatus: v.WorkspaceStatus, + AccountId: v.AccountId, + CredentialsId: v.CredentialsId, + StorageConfigurationId: v.StorageConfigurationId, + WorkspaceStatusMessage: v.WorkspaceStatusMessage, + NetworkId: networkConfigNetworkIdWire, + GcpManagedNetworkConfig: networkConfigGcpManagedNetworkConfigWire, + PricingTier: v.PricingTier, + PrivateAccessSettingsId: v.PrivateAccessSettingsId, + ManagedServicesCustomerManagedKeyId: v.ManagedServicesCustomerManagedKeyId, + StorageCustomerManagedKeyId: v.StorageCustomerManagedKeyId, + Location: v.Location, + Cloud: v.Cloud, + Network: networkWireValue, + AzureWorkspaceInfo: azureWorkspaceInfoWireValue, + GkeConfig: gkeConfigWireValue, + CloudResourceContainer: cloudResourceContainerWireValue, + CustomTags: v.CustomTags, + NetworkConnectivityConfigId: v.NetworkConnectivityConfigId, + StorageMode: v.StorageMode, + ComputeMode: v.ComputeMode, + ExpectedWorkspaceStatus: v.ExpectedWorkspaceStatus, + }, nil +} + +func workspaceFromWire(w *workspaceWire) (*Workspace, error) { + if w == nil { + return nil, nil + } + networkConfigMembers := 0 + if w.NetworkId != nil { + networkConfigMembers++ + } + if w.GcpManagedNetworkConfig != nil { + networkConfigMembers++ + } + if networkConfigMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "Workspace.NetworkConfig") + } + networkPublicValue, err := workspaceNetworkFromWire(w.Network) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Workspace.Network", err) + } + azureWorkspaceInfoPublicValue, err := azureWorkspaceInfoFromWire(w.AzureWorkspaceInfo) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Workspace.AzureWorkspaceInfo", err) + } + gkeConfigPublicValue, err := gkeConfigFromWire(w.GkeConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Workspace.GkeConfig", err) + } + cloudResourceContainerPublicValue, err := cloudResourceContainerFromWire(w.CloudResourceContainer) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Workspace.CloudResourceContainer", err) + } + var networkConfigSelection isWorkspace_NetworkConfig + switch { + case w.NetworkId != nil: + networkConfigSelection = &Workspace_NetworkConfig_NetworkId{NetworkId: *w.NetworkId} + case w.GcpManagedNetworkConfig != nil: + networkConfigGcpManagedNetworkConfigConverted, err := gcpManagedNetworkConfigFromWire(w.GcpManagedNetworkConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "Workspace.NetworkConfig.GcpManagedNetworkConfig", err) + } + networkConfigSelection = &Workspace_NetworkConfig_GcpManagedNetworkConfig{GcpManagedNetworkConfig: *networkConfigGcpManagedNetworkConfigConverted} + } + return &Workspace{ + WorkspaceId: w.WorkspaceId, + WorkspaceName: w.WorkspaceName, + AwsRegion: w.AwsRegion, + CreationTime: w.CreationTime, + DeploymentName: w.DeploymentName, + WorkspaceStatus: w.WorkspaceStatus, + AccountId: w.AccountId, + CredentialsId: w.CredentialsId, + StorageConfigurationId: w.StorageConfigurationId, + WorkspaceStatusMessage: w.WorkspaceStatusMessage, + PricingTier: w.PricingTier, + PrivateAccessSettingsId: w.PrivateAccessSettingsId, + ManagedServicesCustomerManagedKeyId: w.ManagedServicesCustomerManagedKeyId, + StorageCustomerManagedKeyId: w.StorageCustomerManagedKeyId, + Location: w.Location, + Cloud: w.Cloud, + Network: networkPublicValue, + AzureWorkspaceInfo: azureWorkspaceInfoPublicValue, + GkeConfig: gkeConfigPublicValue, + CloudResourceContainer: cloudResourceContainerPublicValue, + CustomTags: w.CustomTags, + NetworkConnectivityConfigId: w.NetworkConnectivityConfigId, + StorageMode: w.StorageMode, + ComputeMode: w.ComputeMode, + ExpectedWorkspaceStatus: w.ExpectedWorkspaceStatus, + NetworkConfig: networkConfigSelection, + }, nil +} + +type workspaceNetworkWire struct { + GcpManagedNetworkConfig *gcpManagedNetworkConfigWire `json:"gcp_managed_network_config,omitempty"` + NetworkId *string `json:"network_id,omitempty"` + GcpCommonNetworkConfig *gcpCommonNetworkConfigWire `json:"gcp_common_network_config,omitempty"` +} + +func workspaceNetworkToWire(v *WorkspaceNetwork) (*workspaceNetworkWire, error) { + if v == nil { + return nil, nil + } + gcpCommonNetworkConfigWireValue, err := gcpCommonNetworkConfigToWire(v.GcpCommonNetworkConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkspaceNetwork.GcpCommonNetworkConfig", err) + } + var networkGcpManagedNetworkConfigWire *gcpManagedNetworkConfigWire + var networkNetworkIdWire *string + switch value := v.Network.(type) { + case nil: + case *WorkspaceNetwork_Network_GcpManagedNetworkConfig: + if value != nil { + networkGcpManagedNetworkConfigConverted, err := gcpManagedNetworkConfigToWire(&value.GcpManagedNetworkConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkspaceNetwork.Network.GcpManagedNetworkConfig", err) + } + networkGcpManagedNetworkConfigWire = networkGcpManagedNetworkConfigConverted + } + case *WorkspaceNetwork_Network_NetworkId: + if value != nil { + networkNetworkIdWire = new(value.NetworkId) + } + default: + return nil, fmt.Errorf("%s: unsupported oneof implementation %T", "WorkspaceNetwork.Network", value) + } + return &workspaceNetworkWire{ + GcpManagedNetworkConfig: networkGcpManagedNetworkConfigWire, + NetworkId: networkNetworkIdWire, + GcpCommonNetworkConfig: gcpCommonNetworkConfigWireValue, + }, nil +} + +func workspaceNetworkFromWire(w *workspaceNetworkWire) (*WorkspaceNetwork, error) { + if w == nil { + return nil, nil + } + networkMembers := 0 + if w.GcpManagedNetworkConfig != nil { + networkMembers++ + } + if w.NetworkId != nil { + networkMembers++ + } + if networkMembers > 1 { + return nil, fmt.Errorf("%s: multiple oneof members set", "WorkspaceNetwork.Network") + } + gcpCommonNetworkConfigPublicValue, err := gcpCommonNetworkConfigFromWire(w.GcpCommonNetworkConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkspaceNetwork.GcpCommonNetworkConfig", err) + } + var networkSelection isWorkspaceNetwork_Network + switch { + case w.GcpManagedNetworkConfig != nil: + networkGcpManagedNetworkConfigConverted, err := gcpManagedNetworkConfigFromWire(w.GcpManagedNetworkConfig) + if err != nil { + return nil, fmt.Errorf("%s: %w", "WorkspaceNetwork.Network.GcpManagedNetworkConfig", err) + } + networkSelection = &WorkspaceNetwork_Network_GcpManagedNetworkConfig{GcpManagedNetworkConfig: *networkGcpManagedNetworkConfigConverted} + case w.NetworkId != nil: + networkSelection = &WorkspaceNetwork_Network_NetworkId{NetworkId: *w.NetworkId} + } + return &WorkspaceNetwork{ + GcpCommonNetworkConfig: gcpCommonNetworkConfigPublicValue, + Network: networkSelection, + }, nil +} + +func convertSlice[T, W any](s []T, conv func(*T) (*W, error)) ([]W, error) { + if s == nil { + return nil, nil + } + out := make([]W, len(s)) + for i := range s { + converted, err := conv(&s[i]) + if err != nil { + return nil, fmt.Errorf("element %d: %w", i, err) + } + out[i] = *converted + } + return out, nil +}